// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. package edu.wpi.first.units; import java.util.Objects; /** * A measure holds the magnitude and unit of some dimension, such as distance, time, or speed. A * measure is immutable and type safe, making it easy to use in concurrent situations * and gives compile-time safety. Two measures with the same unit and magnitude are * effectively the same object. * * @param the unit type of the measure */ public class ImmutableMeasure> implements Measure { private final double m_magnitude; private final double m_baseUnitMagnitude; private final U m_unit; /** * Creates a new immutable measure instance. This shouldn't be used directly; prefer one of the * factory methods instead. * * @param magnitude the magnitude of this measure * @param unit the unit of this measure. */ @SuppressWarnings("unchecked") ImmutableMeasure(double magnitude, double baseUnitMagnitude, Unit unit) { Objects.requireNonNull(unit, "Unit cannot be null"); m_magnitude = magnitude; m_baseUnitMagnitude = baseUnitMagnitude; m_unit = (U) unit; } /** * Creates a new measure in the given unit with a magnitude equal to the given one in base units. * * @param the type of the units of measure * @param baseUnitMagnitude the magnitude of the measure, in terms of the base unit of measure * @param unit the unit of measure * @return a new measure */ public static > ImmutableMeasure ofBaseUnits( double baseUnitMagnitude, Unit unit) { return new ImmutableMeasure<>(unit.fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, unit); } /** * Creates a new measure in the given unit with a magnitude in terms of that unit. * * @param the type of the units of measure * @param relativeMagnitude the magnitude of the measure * @param unit the unit of measure * @return a new measure */ public static > ImmutableMeasure ofRelativeUnits( double relativeMagnitude, Unit unit) { return new ImmutableMeasure<>(relativeMagnitude, unit.toBaseUnits(relativeMagnitude), unit); } /** Gets the unitless magnitude of this measure. */ @Override public double magnitude() { return m_magnitude; } @Override public double baseUnitMagnitude() { return m_baseUnitMagnitude; } /** Gets the units of this measure. */ @Override public U unit() { return m_unit; } /** * Checks for object equality. To check if two measures are equivalent, use {@link * #isEquivalent(Measure) isEquivalent}. */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Measure)) { return false; } Measure that = (Measure) o; return Objects.equals(m_unit, that.unit()) && m_baseUnitMagnitude == that.baseUnitMagnitude(); } @Override public int hashCode() { return Objects.hash(m_magnitude, m_unit); } @Override public Measure copy() { return this; // already immutable, no need to allocate a new object } @Override public String toString() { return toShortString(); } }