|
12 | 12 | import java.util.ArrayList; |
13 | 13 | import java.util.List; |
14 | 14 | import java.util.Optional; |
| 15 | +import java.util.function.Function; |
15 | 16 |
|
16 | 17 | import static com.google.common.base.Preconditions.checkNotNull; |
17 | 18 |
|
|
21 | 22 | * To be publishable, a type should have one or more accessor methods annotated with {@link NTValue}. This is done |
22 | 23 | * with annotations instead of methods |
23 | 24 | */ |
24 | | -public class NTPublishOperation<T extends NTPublishable> implements Operation { |
| 25 | +public class NTPublishOperation<S, T extends NTPublishable> implements Operation { |
25 | 26 |
|
26 | | - private final Class<T> type; |
| 27 | + private final Class<S> type; |
| 28 | + private final Function<S, T> converter; |
27 | 29 | private final List<Method> ntValueMethods = new ArrayList<>(); |
28 | 30 |
|
| 31 | + /** |
| 32 | + * Create a new publish operation for a socket type that implements {@link NTPublishable} directly |
| 33 | + */ |
| 34 | + @SuppressWarnings("unchecked") |
29 | 35 | public NTPublishOperation(Class<T> type) { |
30 | | - this.type = checkNotNull(type, "Type was null"); |
| 36 | + this((Class<S>) type, type, value -> (T) value); |
| 37 | + } |
| 38 | + |
| 39 | + /** |
| 40 | + * Create a new publish operation where the socket type and NTPublishable type are different. This is useful for |
| 41 | + * classes that we don't create, such as JavaCV's {@link org.bytedeco.javacpp.opencv_core.Size} class, since we |
| 42 | + * can't make them implement additional interfaces. |
| 43 | + * |
| 44 | + * @param socketType The type of socket that can be connected to this step |
| 45 | + * @param reportType A class implementing {@link NTPublishable} that determines what data is sent to NetworkTables |
| 46 | + * @param converter A function to convert socket values into publishable values |
| 47 | + */ |
| 48 | + public NTPublishOperation(Class<S> socketType, Class<T> reportType, Function<S, T> converter) { |
| 49 | + this.type = checkNotNull(socketType, "Type was null"); |
| 50 | + this.converter = checkNotNull(converter, "Converter was null"); |
31 | 51 |
|
32 | 52 | // Any accessor method with an @NTValue annotation can be published to NetworkTables. |
33 | | - for (Method method : type.getDeclaredMethods()) { |
| 53 | + for (Method method : reportType.getDeclaredMethods()) { |
34 | 54 | if (method.getAnnotation(NTValue.class) != null) { |
35 | 55 | if (method.getParameters().length > 0) { |
36 | 56 | throw new IllegalArgumentException("@NTValue method must have 0 parameters: " + method); |
@@ -88,7 +108,7 @@ public OutputSocket<?>[] createOutputSockets(EventBus eventBus) { |
88 | 108 | public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs) { |
89 | 109 | int i = 0; |
90 | 110 |
|
91 | | - final NTPublishable value = (NTPublishable) inputs[i++].getValue().get(); |
| 111 | + final NTPublishable value = converter.apply((S) inputs[i++].getValue().get()); |
92 | 112 | final String subtableName = (String) inputs[i++].getValue().get(); |
93 | 113 |
|
94 | 114 | if (subtableName.isEmpty()) { |
|
0 commit comments