diff --git a/wpiunits/generate_units.py b/wpiunits/generate_units.py index 2aebf286c2..2c4bc0856e 100755 --- a/wpiunits/generate_units.py +++ b/wpiunits/generate_units.py @@ -258,7 +258,18 @@ UNIT_CONFIGURATIONS = { "Velocity": { "base_unit": "unit()", "generics": {"D": {"extends": "Unit"}}, - "multiply": {}, + "multiply": { + "Time": { + "implementation": inspect.cleandoc( + """ + @Override + default Measure times(Time multiplier) { + return (Measure) unit().numerator().ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude()); + } + """ + ) + } + }, "divide": {}, }, "Voltage": {"base_unit": "Volts", "multiply": {"Current": "Power"}, "divide": {}}, @@ -310,6 +321,15 @@ def mtou(measure_name): return re.sub(regex, "\\1Unit\\2", measure_name) +def indent(multiline_string, indentation): + """ + Indents a multiline string by `indentation` number of spaces + """ + return "\n".join( + list(map(lambda line: " " * indentation + line, multiline_string.split("\n"))) + ) + + def main(): dirname, _ = os.path.split(os.path.abspath(__file__)) @@ -331,6 +351,7 @@ def main(): "generics_list": generics_list, "generics_usage": generics_usage, "mtou": mtou, + "indent": indent, } for unit_name in UNIT_CONFIGURATIONS: diff --git a/wpiunits/src/generate/main/java/Measure-interface.java.jinja b/wpiunits/src/generate/main/java/Measure-interface.java.jinja index 83c7025d9f..0e05d11be1 100644 --- a/wpiunits/src/generate/main/java/Measure-interface.java.jinja +++ b/wpiunits/src/generate/main/java/Measure-interface.java.jinja @@ -80,10 +80,14 @@ public interface {{ helpers['type_decl'](name) }} extends Measure<{{ helpers['mt } {% else %} {% if unit in config[name]['multiply'] %} +{%- if 'implementation' in config[name]['multiply'][unit] -%} +{{ helpers['indent'](config[name]['multiply'][unit]['implementation'], 2) }} +{%- else %} @Override default {{ config[name]['multiply'][unit] }} times({{ unit }} multiplier) { return {{ config[config[name]['multiply'][unit]]['base_unit'] }}.of(baseUnitMagnitude() * multiplier.baseUnitMagnitude()); } +{%- endif %} {% else %} @Override default Mult<{{ helpers['mtou'](name) }}, {{ helpers['mtou'](unit) }}> times({{ unit }} multiplier) { diff --git a/wpiunits/src/generated/main/java/edu/wpi/first/units/measure/Velocity.java b/wpiunits/src/generated/main/java/edu/wpi/first/units/measure/Velocity.java index bc1c9ce8c2..e69991d111 100644 --- a/wpiunits/src/generated/main/java/edu/wpi/first/units/measure/Velocity.java +++ b/wpiunits/src/generated/main/java/edu/wpi/first/units/measure/Velocity.java @@ -287,10 +287,9 @@ public interface Velocity extends Measure> { return (Per, TemperatureUnit>) Measure.super.divide(divisor); } - @Override - default Mult, TimeUnit> times(Time multiplier) { - return (Mult, TimeUnit>) Measure.super.times(multiplier); + default Measure times(Time multiplier) { + return (Measure) unit().numerator().ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude()); } @Override diff --git a/wpiunits/src/test/java/edu/wpi/first/units/measure/VelocityTest.java b/wpiunits/src/test/java/edu/wpi/first/units/measure/VelocityTest.java new file mode 100644 index 0000000000..177769acd3 --- /dev/null +++ b/wpiunits/src/test/java/edu/wpi/first/units/measure/VelocityTest.java @@ -0,0 +1,27 @@ +// 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.measure; + +import static edu.wpi.first.units.Units.Milliseconds; +import static edu.wpi.first.units.Units.Seconds; +import static edu.wpi.first.units.Units.Volts; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +import edu.wpi.first.units.Measure; +import edu.wpi.first.units.VelocityUnit; +import edu.wpi.first.units.VoltageUnit; +import org.junit.jupiter.api.Test; + +class VelocityTest { + @Test + void velocityTimesTimeReturnsDivisor() { + var velocity = VelocityUnit.combine(Volts, Seconds).of(123); + var time = Milliseconds.of(100); + Measure result = velocity.times(time); + // Compile-time test - would fail to compile if the return type was Mult or Measure + + assertInstanceOf(Voltage.class, result); + } +}