001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.units; 006 007import edu.wpi.first.units.measure.Dimensionless; 008import edu.wpi.first.units.mutable.GenericMutableMeasureImpl; 009 010/** 011 * A measure holds the magnitude and unit of some dimension, such as distance, time, or speed. An 012 * immutable measure is <i>immutable</i> and <i>type safe</i>, making it easy to use in concurrent 013 * situations and gives compile-time safety. Two measures with the same <i>unit</i> and 014 * <i>magnitude</i> are effectively equivalent objects. 015 * 016 * @param magnitude the magnitude of the measure in terms of its unit 017 * @param baseUnitMagnitude the magnitude of the measure in terms of its base unit 018 * @param unit the unit of the measurement 019 * @param <U> the unit type of the measure 020 */ 021public record ImmutableMeasure<U extends Unit>(double magnitude, double baseUnitMagnitude, U unit) 022 implements Measure<U> { 023 /** 024 * Creates a new measure in the given unit with a magnitude equal to the given one in base units. 025 * 026 * @param <U> the type of the units of measure 027 * @param baseUnitMagnitude the magnitude of the measure, in terms of the base unit of measure 028 * @param unit the unit of measure 029 * @return a new measure 030 */ 031 public static <U extends Unit> ImmutableMeasure<U> ofBaseUnits(double baseUnitMagnitude, U unit) { 032 return new ImmutableMeasure<>(unit.fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, unit); 033 } 034 035 /** 036 * Creates a new measure in the given unit with a magnitude in terms of that unit. 037 * 038 * @param <U> the type of the units of measure 039 * @param relativeMagnitude the magnitude of the measure 040 * @param unit the unit of measure 041 * @return a new measure 042 */ 043 public static <U extends Unit> ImmutableMeasure<U> ofRelativeUnits( 044 double relativeMagnitude, U unit) { 045 return new ImmutableMeasure<>(relativeMagnitude, unit.toBaseUnits(relativeMagnitude), unit); 046 } 047 048 @Override 049 public Measure<U> copy() { 050 return this; // already immutable, no need to allocate a new object 051 } 052 053 @Override 054 public MutableMeasure<U, ?, ?> mutableCopy() { 055 return new GenericMutableMeasureImpl<>(magnitude, baseUnitMagnitude, unit); 056 } 057 058 @Override 059 public Measure<U> unaryMinus() { 060 return ofBaseUnits(0 - baseUnitMagnitude, unit); 061 } 062 063 @Override 064 public Measure<U> plus(Measure<? extends U> other) { 065 return ofBaseUnits(baseUnitMagnitude + other.baseUnitMagnitude(), unit); 066 } 067 068 @Override 069 public Measure<U> minus(Measure<? extends U> other) { 070 return ofBaseUnits(baseUnitMagnitude - other.baseUnitMagnitude(), unit); 071 } 072 073 @Override 074 public Measure<U> times(double multiplier) { 075 return ofBaseUnits(baseUnitMagnitude * multiplier, unit); 076 } 077 078 @Override 079 public Measure<U> times(Dimensionless multiplier) { 080 return ofBaseUnits(baseUnitMagnitude * multiplier.baseUnitMagnitude(), unit); 081 } 082 083 @Override 084 public Measure<U> div(double divisor) { 085 return ofBaseUnits(baseUnitMagnitude / divisor, unit); 086 } 087 088 @Override 089 public Measure<U> div(Dimensionless divisor) { 090 return ofBaseUnits(baseUnitMagnitude / divisor.baseUnitMagnitude(), unit); 091 } 092}