[wpiunits] Make Velocity.mult(Time) return Measure<D> (#7162)

Update code generator to allow arbitrary implementations of multiplication methods.
This commit is contained in:
Sam Carlberg
2024-10-04 01:19:36 -04:00
committed by GitHub
parent bc6553cd2b
commit 9a7710ebd3
4 changed files with 55 additions and 4 deletions

View File

@@ -258,7 +258,18 @@ UNIT_CONFIGURATIONS = {
"Velocity": {
"base_unit": "unit()",
"generics": {"D": {"extends": "Unit"}},
"multiply": {},
"multiply": {
"Time": {
"implementation": inspect.cleandoc(
"""
@Override
default Measure<D> times(Time multiplier) {
return (Measure<D>) 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:

View File

@@ -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) {

View File

@@ -287,10 +287,9 @@ public interface Velocity<D extends Unit> extends Measure<VelocityUnit<D>> {
return (Per<VelocityUnit<D>, TemperatureUnit>) Measure.super.divide(divisor);
}
@Override
default Mult<VelocityUnit<D>, TimeUnit> times(Time multiplier) {
return (Mult<VelocityUnit<D>, TimeUnit>) Measure.super.times(multiplier);
default Measure<D> times(Time multiplier) {
return (Measure<D>) unit().numerator().ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
}
@Override

View File

@@ -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<VoltageUnit> result = velocity.times(time);
// Compile-time test - would fail to compile if the return type was Mult or Measure<?>
assertInstanceOf(Voltage.class, result);
}
}