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; 008 009/** 010 * A mutable measurement can be used to keep a single object allocation and reference whose state is 011 * mutated or changed as it is used. This is helpful for optimizing memory usage to keep garbage 012 * collection time - and its associated loop overruns - to a minimum. 013 * 014 * @param <U> The dimension of measurement. 015 * @param <Base> The base measure type. 016 * @param <MutSelf> The self type. This MUST inherit from the base measure type. 017 */ 018public interface MutableMeasure< 019 U extends Unit, Base extends Measure<U>, MutSelf extends MutableMeasure<U, Base, MutSelf>> 020 extends Measure<U> { 021 /** 022 * Overwrites the state of this measure with new values. 023 * 024 * @param magnitude the new magnitude in terms of the new unit 025 * @param newUnit the new unit 026 * @return this measure 027 */ 028 MutSelf mut_replace(double magnitude, U newUnit); 029 030 /** 031 * Overwrites the state of this measure and replaces it completely with values from the given one. 032 * The magnitude, base unit magnitude, and unit will all be copied. This is functionally the same 033 * as calling {@code other.mutableCopy()}, but copying to a pre-existing mutable measure instead 034 * of instantiating a new one. 035 * 036 * @param other the other measure to copy values from 037 * @return this measure 038 */ 039 default MutSelf mut_replace(Base other) { 040 return mut_replace(other.magnitude(), other.unit()); 041 } 042 043 @Override 044 Base copy(); 045 046 /** 047 * Sets the new magnitude of the measurement. The magnitude must be in terms of the {@link 048 * #unit()}. 049 * 050 * @param magnitude the new magnitude of the measurement 051 * @return this mutable measure 052 */ 053 default MutSelf mut_setMagnitude(double magnitude) { 054 return mut_replace(magnitude, unit()); 055 } 056 057 /** 058 * Sets the new magnitude of the measurement. The magnitude must be in terms of the base unit of 059 * the current unit. 060 * 061 * @param baseUnitMagnitude the new magnitude of the measurement 062 * @return this mutable measure 063 */ 064 default MutSelf mut_setBaseUnitMagnitude(double baseUnitMagnitude) { 065 return mut_replace(unit().fromBaseUnits(baseUnitMagnitude), unit()); 066 } 067 068 /** 069 * Increments the current magnitude of the measure by the given value. The value must be in terms 070 * of the current {@link #unit() unit}. 071 * 072 * @param raw the raw value to accumulate by 073 * @return the measure 074 */ 075 default MutSelf mut_acc(double raw) { 076 return mut_setBaseUnitMagnitude(magnitude() + raw); 077 } 078 079 /** 080 * Increments the current magnitude of the measure by the amount of the given measure. 081 * 082 * @param other the measure whose value should be added to this one 083 * @return this measure 084 */ 085 default MutSelf mut_acc(Base other) { 086 return mut_setMagnitude(magnitude() + unit().fromBaseUnits(other.baseUnitMagnitude())); 087 } 088 089 /** 090 * Adds another measurement to this one. This will mutate the object instead of generating a new 091 * measurement object. 092 * 093 * @param other the measurement to add 094 * @return this measure 095 */ 096 default MutSelf mut_plus(Base other) { 097 return mut_acc(other); 098 } 099 100 /** 101 * Adds another measurement to this one. This will mutate the object instead of generating a new 102 * measurement object. This is a denormalized version of {@link #mut_plus(Measure)} to avoid 103 * having to wrap raw numbers in a {@code Measure} object and pay for an object allocation. 104 * 105 * @param magnitude the magnitude of the other measurement. 106 * @param otherUnit the unit of the other measurement 107 * @return this measure 108 */ 109 default MutSelf mut_plus(double magnitude, U otherUnit) { 110 return mut_setBaseUnitMagnitude(magnitude() + otherUnit.toBaseUnits(magnitude)); 111 } 112 113 /** 114 * Subtracts another measurement to this one. This will mutate the object instead of generating a 115 * new measurement object. 116 * 117 * @param other the measurement to subtract from this one 118 * @return this measure 119 */ 120 default MutSelf mut_minus(Base other) { 121 return mut_setBaseUnitMagnitude(baseUnitMagnitude() - other.baseUnitMagnitude()); 122 } 123 124 /** 125 * Subtracts another measurement from this one. This will mutate the object instead of generating 126 * a new measurement object. This is a denormalized version of {@link #mut_minus(Measure)} to 127 * avoid having to wrap raw numbers in a {@code Measure} object and pay for an object allocation. 128 * 129 * @param magnitude the magnitude of the other measurement. 130 * @param otherUnit the unit of the other measurement 131 * @return this measure 132 */ 133 default MutSelf mut_minus(double magnitude, U otherUnit) { 134 return mut_setBaseUnitMagnitude(baseUnitMagnitude() - otherUnit.toBaseUnits(magnitude)); 135 } 136 137 /** 138 * Multiplies this measurement by some constant value. This will mutate the object instead of 139 * generating a new measurement object. 140 * 141 * @param multiplier the multiplier to scale the measurement by 142 * @return this measure 143 */ 144 default MutSelf mut_times(double multiplier) { 145 return mut_setBaseUnitMagnitude(baseUnitMagnitude() * multiplier); 146 } 147 148 /** 149 * Multiplies this measurement by some constant value. This will mutate the object instead of 150 * generating a new measurement object. 151 * 152 * @param multiplier the multiplier to scale the measurement by 153 * @return this measure 154 */ 155 default MutSelf mut_times(Dimensionless multiplier) { 156 return mut_times(multiplier.baseUnitMagnitude()); 157 } 158 159 /** 160 * Divides this measurement by some constant value. This will mutate the object instead of 161 * generating a new measurement object. 162 * 163 * @param divisor the divisor to scale the measurement by 164 * @return this measure 165 */ 166 default MutSelf mut_divide(double divisor) { 167 return mut_times(1 / divisor); 168 } 169 170 /** 171 * Divides this measurement by some constant value. This will mutate the object instead of 172 * generating a new measurement object. 173 * 174 * @param divisor the divisor to scale the measurement by 175 * @return this measure 176 */ 177 default MutSelf mut_divide(Dimensionless divisor) { 178 return mut_divide(divisor.baseUnitMagnitude()); 179 } 180}