RobotCore 1.0
WPILib port to raspberry Pi
Loading...
Searching...
No Matches
NetworkTablesTunableBackend.java
1// TODO - RobotCore - Modified
2
3// Copyright (c) FIRST and other WPILib contributors.
4// Open Source Software; you can modify and/or share it under the terms of
5// the WPILib BSD license file in the root directory of this project.
6
7package org.wpilib.backend;
8
9import java.util.List;
10
11import org.wpilib.networktables.NetworkTableInstance;
12import org.wpilib.tunable.ComplexTunable;
13import org.wpilib.tunable.TunableBackend;
14import org.wpilib.tunable.TunableBase;
15
16// import edu.wpi.first.networktables.NetworkTableInstance;
17
18// import java.io.IOException;
19// import java.nio.ByteBuffer;
20// import java.util.ArrayList;
21// import java.util.Arrays;
22// import java.util.EnumSet;
23// import java.util.HashMap;
24// import java.util.IdentityHashMap;
25// import java.util.List;
26// import java.util.Map;
27// import java.util.function.BooleanSupplier;
28// import java.util.function.DoubleConsumer;
29// import java.util.function.DoubleSupplier;
30// import java.util.function.IntConsumer;
31// import java.util.function.IntSupplier;
32// import java.util.function.LongConsumer;
33// import java.util.function.LongSupplier;
34// import org.wpilib.networktables.GenericPublisher;
35// import org.wpilib.networktables.GenericSubscriber;
36// import org.wpilib.networktables.NetworkTableEvent;
37// import org.wpilib.networktables.NetworkTableInstance;
38// import org.wpilib.networktables.NetworkTableListenerPoller;
39// import org.wpilib.networktables.NetworkTableValue;
40// import org.wpilib.networktables.PubSubOption;
41// import org.wpilib.networktables.StringPublisher;
42// import org.wpilib.tunable.ComplexTunable;
43// import org.wpilib.tunable.Tunable;
44// import org.wpilib.tunable.TunableBackend;
45// import org.wpilib.tunable.TunableBase;
46// import org.wpilib.tunable.TunableBoolean;
47// import org.wpilib.tunable.TunableConfig;
48// import org.wpilib.tunable.TunableDouble;
49// import org.wpilib.tunable.TunableFloat;
50// import org.wpilib.tunable.TunableInt;
51// import org.wpilib.tunable.TunableLong;
52// import org.wpilib.tunable.TunableRegistry;
53// import org.wpilib.tunable.util.PathUtil;
54// import org.wpilib.util.function.BooleanConsumer;
55// import org.wpilib.util.function.FloatConsumer;
56// import org.wpilib.util.function.FloatSupplier;
57// import org.wpilib.util.protobuf.ProtobufBuffer;
58// import org.wpilib.util.struct.StructBuffer;
59
61public class NetworkTablesTunableBackend implements TunableBackend {
62
63 public NetworkTablesTunableBackend(NetworkTableInstance inst, String prefix) {
64 }
65
66 @Override
67 public void close() throws Exception {
68 // TODO Auto-generated method stub
69 throw new UnsupportedOperationException("Unimplemented method 'NetworkTablesTunableBackend.close'");
70 }
71
72 @Override
73 public boolean publish(String path, TunableBase tunable) {
74 // TODO Auto-generated method stub
75 throw new UnsupportedOperationException("Unimplemented method 'publish'");
76 }
77
78 @Override
79 public boolean publishComplex(String path, ComplexTunable tunable) {
80 // TODO Auto-generated method stub
81 throw new UnsupportedOperationException("Unimplemented method 'publishComplex'");
82 }
83
84 @Override
85 public void remove(String path) {
86 // TODO Auto-generated method stub
87 throw new UnsupportedOperationException("Unimplemented method 'remove'");
88 }
89
90 @Override
91 public List<PublishedTunable> removePrefix(String prefix) {
92 // TODO Auto-generated method stub
93 throw new UnsupportedOperationException("Unimplemented method 'removePrefix'");
94 }
95
96 @Override
97 public void update() {
98 // System.out.println("NetworkTablesTunableBackend.update");
99 // throw new UnsupportedOperationException("Unimplemented method 'update'");
100 // TODO - should I be using the original of this?
101 }
102 // private static final String MUTABLE_PROPERTIES = "{\"mutable\":true}";
103
104 // private final NetworkTableInstance m_inst;
105 // private final String m_prefix;
106 // private final Map<String, StoredEntry> m_entries = new HashMap<>();
107 // private final Map<TunableBase, List<StoredEntry>> m_entriesByTunable = new IdentityHashMap<>();
108 // private final List<StoredEntry> m_dirtyEntries = new ArrayList<>();
109 // private final List<StoredEntry> m_alwaysGetEntries = new ArrayList<>();
110 // private final List<StoredEntry> m_complexEntries = new ArrayList<>();
111 // private final List<StoredEntry> m_polledEntries = new ArrayList<>();
112 // private final Map<Integer, TunableValueEntry> m_subscriberMap = new HashMap<>();
113 // private final NetworkTableListenerPoller m_poller;
114 // private final List<Runnable> m_pendingMutations = new ArrayList<>();
115 // private final Map<String, Boolean> m_pendingPathStates = new HashMap<>();
116 // private final List<Runnable> m_onChangeCallbacks = new ArrayList<>();
117 // private final IdentityHashMap<ComplexTunable, Boolean> m_updatedComplexEntries =
118 // new IdentityHashMap<>();
119 // private int m_updateDepth;
120 // private boolean m_usingOnChangeCallbacks;
121 // private boolean m_closed;
122
123 // private static final class StoredEntry {
124 // StoredEntry(TunableEntry entry, TunableBase tunable, ComplexTunable complex) {
125 // this.entry = entry;
126 // this.tunable = tunable;
127 // this.complex = complex;
128 // }
129
130 // private final TunableEntry entry;
131 // private final TunableBase tunable;
132 // private final ComplexTunable complex;
133 // private boolean dirtyQueued;
134 // private boolean closed;
135 // }
136
137 // private static String getProperties(TunableConfig config) {
138 // String properties = config == null ? "{}" : config.getProperties();
139 // StringBuilder sb = new StringBuilder(properties.length() + 32);
140 // sb.append(properties, 0, properties.length() - 1);
141 // if (sb.length() > 1) {
142 // sb.append(',');
143 // }
144 // if (config != null && config.isRobust()) {
145 // sb.append("\"robust\":true,");
146 // }
147 // sb.append("\"mutable\":").append(config == null || config.isMutable()).append(',');
148 // sb.setCharAt(sb.length() - 1, '}');
149 // return sb.toString();
150 // }
151
152 // private interface TunableEntry extends AutoCloseable {
153 // void updateNetwork();
154
155 // @Override
156 // void close();
157 // }
158
159 // private static boolean isAlwaysGet(TunableBase tunable) {
160 // TunableConfig config = tunable.getConfig();
161 // return config != null && config.getPolling() == TunableConfig.Polling.ALWAYS_GET;
162 // }
163
164 // private record InitialUpdate(Runnable callback) {}
165
166 // private abstract class TunableValueEntry implements TunableEntry {
167 // TunableValueEntry(String path, TunableConfig config, String typeString) {
168 // m_path = path;
169 // if (config != null && config.getTypeString() != null) {
170 // typeString = config.getTypeString();
171 // }
172 // if (config != null && config.isRobust()) {
173 // m_publisher =
174 // m_inst.getTopic(path + "/value").genericPublishEx(typeString, getProperties(config));
175 // m_subscriber =
176 // m_inst
177 // .getTopic(path + "/tune")
178 // .genericSubscribe(typeString, PubSubOption.excludePublisher(m_publisher));
179 // } else {
180 // var topic = m_inst.getTopic(path);
181 // m_publisher = topic.genericPublishEx(typeString, getProperties(config));
182 // m_subscriber =
183 // topic.genericSubscribe(typeString, PubSubOption.excludePublisher(m_publisher));
184 // }
185 // m_subscriberMap.put(m_subscriber.getHandle(), this);
186 // if (config == null || config.isMutable()) {
187 // m_listener =
188 // m_poller.addListener(m_subscriber, EnumSet.of(NetworkTableEvent.Kind.VALUE_ALL));
189 // } else {
190 // m_listener = 0;
191 // }
192 // m_onChange = config == null ? null : config.getOnTune();
193 // m_applyInitialValue = config != null && config.isRobust() && config.isMutable();
194 // }
195
196 // @Override
197 // public void close() {
198 // if (m_listener != 0) {
199 // m_poller.removeListener(m_listener);
200 // }
201 // m_subscriberMap.remove(m_subscriber.getHandle());
202 // m_subscriber.close();
203 // m_publisher.close();
204 // }
205
206 // @Override
207 // public abstract void updateNetwork();
208
209 // protected abstract boolean doUpdateTunable(NetworkTableValue value);
210
211 // public Runnable updateTunable(NetworkTableValue value) {
212 // if (!doUpdateTunable(value)) {
213 // return null;
214 // }
215 // m_forcePublish = true;
216 // return m_onChange;
217 // }
218
219 // public InitialUpdate updateInitialTunable() {
220 // if (!m_applyInitialValue) {
221 // return null;
222 // }
223 // NetworkTableValue value = m_subscriber.get();
224 // if (!value.isValid()) {
225 // return null;
226 // }
227 // return new InitialUpdate(updateTunable(value));
228 // }
229
230 // protected boolean shouldPublishValue(boolean changed) {
231 // boolean shouldPublish = m_forcePublish || changed;
232 // m_forcePublish = false;
233 // return shouldPublish;
234 // }
235
236 // protected void reportWarning(String msg) {
237 // TunableRegistry.reportWarning("NetworkTables tunable '" + m_path + "': " + msg);
238 // }
239
240 // protected void reportWarning(String msg, Exception e) {
241 // reportWarning(msg + ": " + e);
242 // }
243
244 // protected void reportNullValueRetained(String valueDescription, boolean hasPublishedValue) {
245 // if (hasPublishedValue) {
246 // reportWarning(
247 // "null " + valueDescription + " value was not published; previous value retained");
248 // }
249 // }
250
251 // protected final String m_path;
252 // protected final GenericPublisher m_publisher;
253 // protected final GenericSubscriber m_subscriber;
254 // private final int m_listener;
255 // private final Runnable m_onChange;
256 // private final boolean m_applyInitialValue;
257 // private boolean m_forcePublish;
258 // }
259
260 // private final class TunableBooleanEntry extends TunableValueEntry {
261 // TunableBooleanEntry(
262 // String path, TunableConfig config, BooleanSupplier getter, BooleanConsumer setter) {
263 // super(path, config, "boolean");
264 // m_getter = getter;
265 // m_setter = setter;
266 // updateNetwork();
267 // }
268
269 // @Override
270 // public void updateNetwork() {
271 // boolean value = m_getter.getAsBoolean();
272 // if (shouldPublishValue(!m_hasLastValue || value != m_lastValue)) {
273 // m_lastValue = value;
274 // m_hasLastValue = true;
275 // m_publisher.setBoolean(value);
276 // }
277 // }
278
279 // @Override
280 // public boolean doUpdateTunable(NetworkTableValue value) {
281 // m_setter.accept(value.getBoolean());
282 // return true;
283 // }
284
285 // private final BooleanSupplier m_getter;
286 // private final BooleanConsumer m_setter;
287 // private boolean m_lastValue;
288 // private boolean m_hasLastValue;
289 // }
290
291 // private final class TunableIntEntry extends TunableValueEntry {
292 // TunableIntEntry(String path, TunableConfig config, IntSupplier getter, IntConsumer setter) {
293 // super(path, config, "int");
294 // m_getter = getter;
295 // m_setter = setter;
296 // updateNetwork();
297 // }
298
299 // @Override
300 // public void updateNetwork() {
301 // int value = m_getter.getAsInt();
302 // if (shouldPublishValue(!m_hasLastValue || value != m_lastValue)) {
303 // m_lastValue = value;
304 // m_hasLastValue = true;
305 // m_publisher.setInteger(value);
306 // }
307 // }
308
309 // @Override
310 // public boolean doUpdateTunable(NetworkTableValue value) {
311 // m_setter.accept((int) value.getInteger());
312 // return true;
313 // }
314
315 // private final IntSupplier m_getter;
316 // private final IntConsumer m_setter;
317 // private int m_lastValue;
318 // private boolean m_hasLastValue;
319 // }
320
321 // private final class TunableLongEntry extends TunableValueEntry {
322 // TunableLongEntry(String path, TunableConfig config, LongSupplier getter, LongConsumer setter) {
323 // super(path, config, "int");
324 // m_getter = getter;
325 // m_setter = setter;
326 // updateNetwork();
327 // }
328
329 // @Override
330 // public void updateNetwork() {
331 // long value = m_getter.getAsLong();
332 // if (shouldPublishValue(!m_hasLastValue || value != m_lastValue)) {
333 // m_lastValue = value;
334 // m_hasLastValue = true;
335 // m_publisher.setInteger(value);
336 // }
337 // }
338
339 // @Override
340 // public boolean doUpdateTunable(NetworkTableValue value) {
341 // m_setter.accept(value.getInteger());
342 // return true;
343 // }
344
345 // private final LongSupplier m_getter;
346 // private final LongConsumer m_setter;
347 // private long m_lastValue;
348 // private boolean m_hasLastValue;
349 // }
350
351 // private final class TunableFloatEntry extends TunableValueEntry {
352 // TunableFloatEntry(
353 // String path, TunableConfig config, FloatSupplier getter, FloatConsumer setter) {
354 // super(path, config, "float");
355 // m_getter = getter;
356 // m_setter = setter;
357 // updateNetwork();
358 // }
359
360 // @Override
361 // public void updateNetwork() {
362 // float value = m_getter.getAsFloat();
363 // if (shouldPublishValue(!m_hasLastValue || Float.compare(value, m_lastValue) != 0)) {
364 // m_lastValue = value;
365 // m_hasLastValue = true;
366 // m_publisher.setFloat(value);
367 // }
368 // }
369
370 // @Override
371 // public boolean doUpdateTunable(NetworkTableValue value) {
372 // m_setter.accept(value.getFloat());
373 // return true;
374 // }
375
376 // private final FloatSupplier m_getter;
377 // private final FloatConsumer m_setter;
378 // private float m_lastValue;
379 // private boolean m_hasLastValue;
380 // }
381
382 // private final class TunableDoubleEntry extends TunableValueEntry {
383 // TunableDoubleEntry(
384 // String path, TunableConfig config, DoubleSupplier getter, DoubleConsumer setter) {
385 // super(path, config, "double");
386 // m_getter = getter;
387 // m_setter = setter;
388 // updateNetwork();
389 // }
390
391 // @Override
392 // public void updateNetwork() {
393 // double value = m_getter.getAsDouble();
394 // if (shouldPublishValue(!m_hasLastValue || Double.compare(value, m_lastValue) != 0)) {
395 // m_lastValue = value;
396 // m_hasLastValue = true;
397 // m_publisher.setDouble(value);
398 // }
399 // }
400
401 // @Override
402 // public boolean doUpdateTunable(NetworkTableValue value) {
403 // m_setter.accept(value.getDouble());
404 // return true;
405 // }
406
407 // private final DoubleSupplier m_getter;
408 // private final DoubleConsumer m_setter;
409 // private double m_lastValue;
410 // private boolean m_hasLastValue;
411 // }
412
413 // @FunctionalInterface
414 // private interface ValuePublisher<T> {
415 // void publish(GenericPublisher publisher, T value);
416 // }
417
418 // @FunctionalInterface
419 // private interface ValueReader<T> {
420 // T read(NetworkTableValue value);
421 // }
422
423 // private final class NullableTunableValueEntry<T> extends TunableValueEntry {
424 // NullableTunableValueEntry(
425 // String path,
426 // Tunable<T> tunable,
427 // String typeString,
428 // ValuePublisher<T> valuePublisher,
429 // ValueReader<T> valueReader) {
430 // super(path, tunable.getConfig(), typeString);
431 // m_tunables = tunable;
432 // m_valueDescription = typeString;
433 // m_valuePublisher = valuePublisher;
434 // m_valueReader = valueReader;
435 // updateNetwork();
436 // }
437
438 // @Override
439 // public void updateNetwork() {
440 // T value = m_tunables.get();
441 // if (value == null) {
442 // shouldPublishValue(false);
443 // reportNullValueRetained(m_valueDescription, m_hasLastValue);
444 // } else if (shouldPublishValue(!m_hasLastValue || !value.equals(m_lastValue))) {
445 // m_lastValue = value;
446 // m_hasLastValue = true;
447 // m_valuePublisher.publish(m_publisher, value);
448 // }
449 // }
450
451 // @Override
452 // public boolean doUpdateTunable(NetworkTableValue value) {
453 // m_tunables.set(m_valueReader.read(value));
454 // return true;
455 // }
456
457 // private final Tunable<T> m_tunables;
458 // private final String m_valueDescription;
459 // private final ValuePublisher<T> m_valuePublisher;
460 // private final ValueReader<T> m_valueReader;
461 // private T m_lastValue;
462 // private boolean m_hasLastValue;
463 // }
464
465 // private final class TunableRawEntry extends TunableValueEntry {
466 // TunableRawEntry(String path, Tunable<byte[]> tunable) {
467 // super(path, tunable.getConfig(), "raw");
468 // m_tunables = tunable;
469 // updateNetwork();
470 // }
471
472 // @Override
473 // public void updateNetwork() {
474 // byte[] value = m_tunables.get();
475 // if (value == null) {
476 // shouldPublishValue(false);
477 // reportNullValueRetained("raw", m_lastValue != null);
478 // return;
479 // }
480 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
481 // m_lastValue = Arrays.copyOf(value, value.length);
482 // m_publisher.setRaw(value, 0, value.length);
483 // }
484 // }
485
486 // @Override
487 // public boolean doUpdateTunable(NetworkTableValue value) {
488 // m_tunables.set(value.getRaw());
489 // return true;
490 // }
491
492 // private final Tunable<byte[]> m_tunables;
493 // private byte[] m_lastValue;
494 // }
495
496 // private final class TunableBooleanArrayEntry extends TunableValueEntry {
497 // TunableBooleanArrayEntry(String path, Tunable<boolean[]> tunable) {
498 // super(path, tunable.getConfig(), "boolean[]");
499 // m_tunables = tunable;
500 // updateNetwork();
501 // }
502
503 // @Override
504 // public void updateNetwork() {
505 // boolean[] value = m_tunables.get();
506 // if (value == null) {
507 // shouldPublishValue(false);
508 // reportNullValueRetained("boolean array", m_lastValue != null);
509 // return;
510 // }
511 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
512 // m_lastValue = Arrays.copyOf(value, value.length);
513 // m_publisher.setBooleanArray(value);
514 // }
515 // }
516
517 // @Override
518 // public boolean doUpdateTunable(NetworkTableValue value) {
519 // m_tunables.set(value.getBooleanArray());
520 // return true;
521 // }
522
523 // private final Tunable<boolean[]> m_tunables;
524 // private boolean[] m_lastValue;
525 // }
526
527 // private final class TunableIntArrayEntry extends TunableValueEntry {
528 // TunableIntArrayEntry(String path, Tunable<int[]> tunable) {
529 // super(path, tunable.getConfig(), "int[]");
530 // m_tunables = tunable;
531 // updateNetwork();
532 // }
533
534 // @Override
535 // public void updateNetwork() {
536 // int[] value = m_tunables.get();
537 // if (value == null) {
538 // shouldPublishValue(false);
539 // reportNullValueRetained("int array", m_lastValue != null);
540 // return;
541 // }
542 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
543 // m_lastValue = Arrays.copyOf(value, value.length);
544 // m_publisher.setIntegerArray(toLongArray(value));
545 // }
546 // }
547
548 // @Override
549 // public boolean doUpdateTunable(NetworkTableValue value) {
550 // m_tunables.set(fromLongArray(value.getIntegerArray()));
551 // return true;
552 // }
553
554 // @SuppressWarnings("PMD.AvoidArrayLoops")
555 // private static long[] toLongArray(int[] arr) {
556 // long[] result = new long[arr.length];
557 // for (int i = 0; i < arr.length; i++) {
558 // result[i] = arr[i];
559 // }
560 // return result;
561 // }
562
563 // private static int[] fromLongArray(long[] arr) {
564 // int[] result = new int[arr.length];
565 // for (int i = 0; i < arr.length; i++) {
566 // result[i] = (int) arr[i];
567 // }
568 // return result;
569 // }
570
571 // private int[] m_lastValue;
572 // private final Tunable<int[]> m_tunables;
573 // }
574
575 // private final class TunableLongArrayEntry extends TunableValueEntry {
576 // TunableLongArrayEntry(String path, Tunable<long[]> tunable) {
577 // super(path, tunable.getConfig(), "int[]");
578 // m_tunables = tunable;
579 // updateNetwork();
580 // }
581
582 // @Override
583 // public void updateNetwork() {
584 // long[] value = m_tunables.get();
585 // if (value == null) {
586 // shouldPublishValue(false);
587 // reportNullValueRetained("long array", m_lastValue != null);
588 // return;
589 // }
590 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
591 // m_lastValue = Arrays.copyOf(value, value.length);
592 // m_publisher.setIntegerArray(value);
593 // }
594 // }
595
596 // @Override
597 // public boolean doUpdateTunable(NetworkTableValue value) {
598 // m_tunables.set(value.getIntegerArray());
599 // return true;
600 // }
601
602 // private final Tunable<long[]> m_tunables;
603 // private long[] m_lastValue;
604 // }
605
606 // private final class TunableFloatArrayEntry extends TunableValueEntry {
607 // TunableFloatArrayEntry(String path, Tunable<float[]> tunable) {
608 // super(path, tunable.getConfig(), "float[]");
609 // m_tunables = tunable;
610 // updateNetwork();
611 // }
612
613 // @Override
614 // public void updateNetwork() {
615 // float[] value = m_tunables.get();
616 // if (value == null) {
617 // shouldPublishValue(false);
618 // reportNullValueRetained("float array", m_lastValue != null);
619 // return;
620 // }
621 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
622 // m_lastValue = Arrays.copyOf(value, value.length);
623 // m_publisher.setFloatArray(value);
624 // }
625 // }
626
627 // @Override
628 // public boolean doUpdateTunable(NetworkTableValue value) {
629 // m_tunables.set(value.getFloatArray());
630 // return true;
631 // }
632
633 // private final Tunable<float[]> m_tunables;
634 // private float[] m_lastValue;
635 // }
636
637 // private final class TunableDoubleArrayEntry extends TunableValueEntry {
638 // TunableDoubleArrayEntry(String path, Tunable<double[]> tunable) {
639 // super(path, tunable.getConfig(), "double[]");
640 // m_tunables = tunable;
641 // updateNetwork();
642 // }
643
644 // @Override
645 // public void updateNetwork() {
646 // double[] value = m_tunables.get();
647 // if (value == null) {
648 // shouldPublishValue(false);
649 // reportNullValueRetained("double array", m_lastValue != null);
650 // return;
651 // }
652 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
653 // m_lastValue = Arrays.copyOf(value, value.length);
654 // m_publisher.setDoubleArray(value);
655 // }
656 // }
657
658 // @Override
659 // public boolean doUpdateTunable(NetworkTableValue value) {
660 // m_tunables.set(value.getDoubleArray());
661 // return true;
662 // }
663
664 // private final Tunable<double[]> m_tunables;
665 // private double[] m_lastValue;
666 // }
667
668 // private final class TunableStringArrayEntry extends TunableValueEntry {
669 // TunableStringArrayEntry(String path, Tunable<String[]> tunable) {
670 // super(path, tunable.getConfig(), "string[]");
671 // m_tunables = tunable;
672 // updateNetwork();
673 // }
674
675 // @Override
676 // public void updateNetwork() {
677 // String[] value = m_tunables.get();
678 // if (value == null) {
679 // shouldPublishValue(false);
680 // reportNullValueRetained("string array", m_lastValue != null);
681 // return;
682 // }
683 // if (shouldPublishValue(!Arrays.equals(value, m_lastValue))) {
684 // m_lastValue = Arrays.copyOf(value, value.length);
685 // m_publisher.setStringArray(value);
686 // }
687 // }
688
689 // @Override
690 // public boolean doUpdateTunable(NetworkTableValue value) {
691 // m_tunables.set(value.getStringArray());
692 // return true;
693 // }
694
695 // private final Tunable<String[]> m_tunables;
696 // private String[] m_lastValue;
697 // }
698
699 // private final class TunableStructEntry<T> extends TunableValueEntry {
700 // TunableStructEntry(String path, Tunable.TunableStruct<T> tunable) {
701 // super(path, tunable.getConfig(), tunable.getStruct().getTypeString());
702 // m_tunables = tunable;
703 // m_buf = StructBuffer.create(tunable.getStruct());
704 // updateNetwork();
705 // }
706
707 // @SuppressWarnings("PMD.AvoidCatchingGenericException")
708 // @Override
709 // public void updateNetwork() {
710 // T value = m_tunables.get();
711 // try {
712 // synchronized (m_buf) {
713 // if (!m_schemaPublished) {
714 // m_publisher.getTopic().getInstance().addSchema(m_buf.getStruct());
715 // m_schemaPublished = true;
716 // }
717 // if (value == null) {
718 // m_publisher.setRaw(new byte[0], 0, 0);
719 // } else {
720 // ByteBuffer bb = m_buf.write(value);
721 // m_publisher.setRaw(bb, 0, bb.position());
722 // }
723 // }
724 // } catch (RuntimeException e) {
725 // reportWarning("failed to publish struct value", e);
726 // }
727 // }
728
729 // @SuppressWarnings("PMD.AvoidCatchingGenericException")
730 // @Override
731 // public boolean doUpdateTunable(NetworkTableValue value) {
732 // byte[] data = value.getRaw();
733 // if (data.length == 0) {
734 // m_tunables.set(null);
735 // return true;
736 // }
737 // if (data.length != m_buf.getStruct().getSize()) {
738 // reportWarning(
739 // "rejected struct tune payload with "
740 // + data.length
741 // + " bytes; expected "
742 // + m_buf.getStruct().getSize());
743 // return false;
744 // }
745 // T tunedValue;
746 // try {
747 // synchronized (m_buf) {
748 // tunedValue = m_buf.read(data);
749 // }
750 // } catch (RuntimeException e) {
751 // reportWarning("rejected struct tune payload", e);
752 // return false;
753 // }
754 // m_tunables.set(tunedValue);
755 // return true;
756 // }
757
758 // private final Tunable.TunableStruct<T> m_tunables;
759 // private final StructBuffer<T> m_buf;
760 // private boolean m_schemaPublished;
761 // }
762
763 // private final class TunableStructArrayEntry<T> extends TunableValueEntry {
764 // TunableStructArrayEntry(String path, Tunable.TunableStructArray<T> tunable) {
765 // super(path, tunable.getConfig(), tunable.getStruct().getTypeString() + "[]");
766 // m_tunables = tunable;
767 // m_buf = StructBuffer.create(tunable.getStruct());
768 // updateNetwork();
769 // }
770
771 // @SuppressWarnings("PMD.AvoidCatchingGenericException")
772 // @Override
773 // public void updateNetwork() {
774 // T[] value = m_tunables.get();
775 // if (value == null) {
776 // if (m_hasPublishedValue) {
777 // reportWarning("null struct array value was not published; previous value retained");
778 // }
779 // return;
780 // }
781 // try {
782 // synchronized (m_buf) {
783 // if (!m_schemaPublished) {
784 // m_publisher.getTopic().getInstance().addSchema(m_buf.getStruct());
785 // m_schemaPublished = true;
786 // }
787 // ByteBuffer bb = m_buf.writeArray(value);
788 // m_publisher.setRaw(bb, 0, bb.position());
789 // m_hasPublishedValue = true;
790 // }
791 // } catch (RuntimeException e) {
792 // reportWarning("failed to publish struct array value", e);
793 // }
794 // }
795
796 // @SuppressWarnings("PMD.AvoidCatchingGenericException")
797 // @Override
798 // public boolean doUpdateTunable(NetworkTableValue value) {
799 // byte[] data = value.getRaw();
800 // int size = m_buf.getStruct().getSize();
801 // if (size == 0 || data.length % size != 0) {
802 // reportWarning(
803 // "rejected struct array tune payload with "
804 // + data.length
805 // + " bytes; expected a multiple of "
806 // + size);
807 // return false;
808 // }
809 // T[] tunedValue;
810 // try {
811 // synchronized (m_buf) {
812 // tunedValue = m_buf.readArray(data);
813 // }
814 // } catch (RuntimeException e) {
815 // reportWarning("rejected struct array tune payload", e);
816 // return false;
817 // }
818 // m_tunables.set(tunedValue);
819 // return true;
820 // }
821
822 // private final Tunable.TunableStructArray<T> m_tunables;
823 // private final StructBuffer<T> m_buf;
824 // private boolean m_schemaPublished;
825 // private boolean m_hasPublishedValue;
826 // }
827
828 // private final class TunableProtobufEntry<T> extends TunableValueEntry {
829 // TunableProtobufEntry(String path, Tunable.TunableProtobuf<T> tunable) {
830 // super(path, tunable.getConfig(), tunable.getProtobuf().getTypeString());
831 // m_tunables = tunable;
832 // m_buf = ProtobufBuffer.create(tunable.getProtobuf());
833 // updateNetwork();
834 // }
835
836 // @SuppressWarnings("PMD.AvoidCatchingGenericException")
837 // @Override
838 // public void updateNetwork() {
839 // T value = m_tunables.get();
840 // if (value == null) {
841 // if (m_hasPublishedValue) {
842 // reportWarning("null protobuf value was not published; previous value retained");
843 // }
844 // return;
845 // }
846 // try {
847 // synchronized (m_buf) {
848 // if (!m_schemaPublished) {
849 // m_publisher.getTopic().getInstance().addSchema(m_buf.getProto());
850 // m_schemaPublished = true;
851 // }
852 // ByteBuffer bb = m_buf.write(value);
853 // m_publisher.setRaw(bb, 0, bb.position());
854 // m_hasPublishedValue = true;
855 // }
856 // } catch (IOException e) {
857 // reportWarning("failed to publish protobuf value", e);
858 // } catch (RuntimeException e) {
859 // reportWarning("failed to publish protobuf value", e);
860 // }
861 // }
862
863 // @SuppressWarnings("PMD.AvoidCatchingGenericException")
864 // @Override
865 // public boolean doUpdateTunable(NetworkTableValue value) {
866 // byte[] data = value.getRaw();
867 // T tunedValue;
868 // try {
869 // synchronized (m_buf) {
870 // tunedValue = m_buf.read(data);
871 // }
872 // } catch (IOException e) {
873 // reportWarning("rejected protobuf tune payload", e);
874 // return false;
875 // } catch (RuntimeException e) {
876 // reportWarning("rejected protobuf tune payload", e);
877 // return false;
878 // }
879 // m_tunables.set(tunedValue);
880 // return true;
881 // }
882
883 // private final Tunable.TunableProtobuf<T> m_tunables;
884 // private final ProtobufBuffer<T, ?> m_buf;
885 // private boolean m_schemaPublished;
886 // private boolean m_hasPublishedValue;
887 // }
888
889 // private final class ComplexTunableEntry implements TunableEntry {
890 // ComplexTunableEntry(String path, ComplexTunable tunable) {
891 // m_tunables = tunable;
892 // String type = m_tunables.getTunableType();
893 // if (type == null) {
894 // m_typePublisher = null;
895 // } else {
896 // m_typePublisher =
897 // m_inst.getStringTopic(path + "/.type").publishEx("string", MUTABLE_PROPERTIES);
898 // m_typePublisher.set(type);
899 // }
900 // }
901
902 // @Override
903 // public void close() {
904 // if (m_typePublisher != null) {
905 // m_typePublisher.close();
906 // }
907 // }
908
909 // @Override
910 // public void updateNetwork() {
911 // TunableRegistry.updateComplexIfNeeded(m_tunables);
912 // }
913
914 // private final ComplexTunable m_tunables;
915 // private final StringPublisher m_typePublisher;
916 // }
917
918 // /**
919 // * Construct.
920 // *
921 // * @param inst NetworkTables instance
922 // * @param prefix prefix to put in front of tunable paths in NT
923 // */
924 // public NetworkTablesTunableBackend(NetworkTableInstance inst, String prefix) {
925 // m_inst = inst;
926 // m_prefix = prefix;
927 // m_poller = new NetworkTableListenerPoller(inst);
928 // }
929
930 // private boolean hasActiveEntry(String path) {
931 // StoredEntry entry = m_entries.get(path);
932 // return entry != null && !entry.closed;
933 // }
934
935 // private boolean hasQueuedActiveEntry(String path) {
936 // if (m_updateDepth > 0) {
937 // Boolean pendingState = m_pendingPathStates.get(path);
938 // if (pendingState != null) {
939 // return pendingState;
940 // }
941 // }
942 // return hasActiveEntry(path);
943 // }
944
945 // private void trackEntry(StoredEntry entry) {
946 // if (entry.tunable == null) {
947 // m_complexEntries.add(entry);
948 // return;
949 // }
950
951 // if (isAlwaysGet(entry.tunable)) {
952 // m_alwaysGetEntries.add(entry);
953 // } else if (entry.tunable.supportsChangeNotification()) {
954 // m_entriesByTunable.computeIfAbsent(entry.tunable, k -> new ArrayList<>()).add(entry);
955 // if (entry.tunable.hasChanged()) {
956 // enqueueDirtyEntry(entry);
957 // }
958 // } else {
959 // m_polledEntries.add(entry);
960 // }
961 // }
962
963 // private void untrackEntry(StoredEntry entry) {
964 // m_dirtyEntries.remove(entry);
965 // entry.dirtyQueued = false;
966
967 // if (entry.tunable == null) {
968 // m_complexEntries.remove(entry);
969 // return;
970 // }
971
972 // if (isAlwaysGet(entry.tunable)) {
973 // m_alwaysGetEntries.remove(entry);
974 // } else if (entry.tunable.supportsChangeNotification()) {
975 // List<StoredEntry> entries = m_entriesByTunable.get(entry.tunable);
976 // if (entries != null) {
977 // entries.remove(entry);
978 // if (entries.isEmpty()) {
979 // m_entriesByTunable.remove(entry.tunable);
980 // }
981 // }
982 // } else {
983 // m_polledEntries.remove(entry);
984 // }
985 // }
986
987 // private void clearTrackedEntries() {
988 // m_entries.clear();
989 // m_entriesByTunable.clear();
990 // m_dirtyEntries.clear();
991 // m_alwaysGetEntries.clear();
992 // m_complexEntries.clear();
993 // m_polledEntries.clear();
994 // }
995
996 // private void enqueueDirtyEntry(StoredEntry entry) {
997 // if (!entry.closed && !entry.dirtyQueued) {
998 // entry.dirtyQueued = true;
999 // m_dirtyEntries.add(entry);
1000 // }
1001 // }
1002
1003 // private void closeEntry(StoredEntry entry) {
1004 // if (entry.closed) {
1005 // return;
1006 // }
1007 // entry.closed = true;
1008 // entry.entry.close();
1009 // if (m_updateDepth == 0) {
1010 // untrackEntry(entry);
1011 // }
1012 // }
1013
1014 // private void eraseEntry(String path, StoredEntry entry) {
1015 // if (m_updateDepth > 0) {
1016 // m_pendingPathStates.put(path, false);
1017 // m_pendingMutations.add(() -> eraseEntryNow(path, entry));
1018 // } else {
1019 // eraseEntryNow(path, entry);
1020 // }
1021 // }
1022
1023 // @SuppressWarnings("PMD.CompareObjectsWithEquals")
1024 // private void eraseEntryNow(String path, StoredEntry entry) {
1025 // if (m_entries.get(path) == entry) {
1026 // m_entries.remove(path);
1027 // untrackEntry(entry);
1028 // }
1029 // }
1030
1031 // private void applyPendingMutations() {
1032 // try {
1033 // while (!m_pendingMutations.isEmpty()) {
1034 // List<Runnable> mutations = new ArrayList<>(m_pendingMutations);
1035 // m_pendingMutations.clear();
1036 // for (Runnable mutation : mutations) {
1037 // mutation.run();
1038 // }
1039 // }
1040 // } finally {
1041 // m_pendingPathStates.clear();
1042 // }
1043 // }
1044
1045 // @Override
1046 // public void close() {
1047 // synchronized (m_entries) {
1048 // if (m_closed) {
1049 // return;
1050 // }
1051 // m_closed = true;
1052 // m_pendingMutations.clear();
1053 // m_pendingPathStates.clear();
1054 // for (StoredEntry entry : m_entries.values()) {
1055 // closeEntry(entry);
1056 // }
1057 // if (m_updateDepth > 0) {
1058 // m_pendingMutations.add(this::clearTrackedEntries);
1059 // } else {
1060 // clearTrackedEntries();
1061 // }
1062 // m_subscriberMap.clear();
1063 // m_poller.close();
1064 // }
1065 // }
1066
1067 // @Override
1068 // public boolean publish(String path, TunableBase tunable) {
1069 // InitialUpdate initialUpdate;
1070 // synchronized (m_entries) {
1071 // if (m_closed) {
1072 // return false;
1073 // }
1074 // if (hasQueuedActiveEntry(path)) {
1075 // TunableRegistry.reportWarning(
1076 // "NetworkTables tunable '" + m_prefix + path + "' already exists");
1077 // return false;
1078 // }
1079 // if (m_updateDepth > 0) {
1080 // m_pendingPathStates.put(path, true);
1081 // m_pendingMutations.add(() -> publish(path, tunable));
1082 // return true;
1083 // }
1084 // String ntPath = m_prefix + path;
1085 // TunableValueEntry entry;
1086 // switch (tunable) {
1087 // case TunableBoolean v -> entry = new TunableBooleanEntry(ntPath, v.getConfig(), v, v);
1088 // case TunableInt v -> entry = new TunableIntEntry(ntPath, v.getConfig(), v, v);
1089 // case TunableLong v -> entry = new TunableLongEntry(ntPath, v.getConfig(), v, v);
1090 // case TunableFloat v -> entry = new TunableFloatEntry(ntPath, v.getConfig(), v, v);
1091 // case TunableDouble v -> entry = new TunableDoubleEntry(ntPath, v.getConfig(), v, v);
1092 // case Tunable.TunableStruct<?> v -> entry = new TunableStructEntry<>(ntPath, v);
1093 // case Tunable.TunableStructArray<?> v -> entry = new TunableStructArrayEntry<>(ntPath, v);
1094 // case Tunable.TunableProtobuf<?> v -> entry = new TunableProtobufEntry<>(ntPath, v);
1095 // case Tunable<?> t -> {
1096 // Class<?> cls = t.getTypeClass();
1097 // if (cls == null) {
1098 // TunableRegistry.reportWarning("Tunable type <null> is not supported by NetworkTables");
1099 // return false;
1100 // }
1101 // switch (cls) {
1102 // case Class<?> c when c == String.class -> {
1103 // @SuppressWarnings("unchecked")
1104 // Tunable<String> tt = (Tunable<String>) t;
1105 // entry =
1106 // new NullableTunableValueEntry<>(
1107 // ntPath,
1108 // tt,
1109 // "string",
1110 // GenericPublisher::setString,
1111 // NetworkTableValue::getString);
1112 // }
1113 // case Class<?> c when c == byte[].class -> {
1114 // @SuppressWarnings("unchecked")
1115 // Tunable<byte[]> tt = (Tunable<byte[]>) t;
1116 // entry = new TunableRawEntry(ntPath, tt);
1117 // }
1118 // case Class<?> c when c == boolean[].class -> {
1119 // @SuppressWarnings("unchecked")
1120 // Tunable<boolean[]> tt = (Tunable<boolean[]>) t;
1121 // entry = new TunableBooleanArrayEntry(ntPath, tt);
1122 // }
1123 // case Class<?> c when c == int[].class -> {
1124 // @SuppressWarnings("unchecked")
1125 // Tunable<int[]> tt = (Tunable<int[]>) t;
1126 // entry = new TunableIntArrayEntry(ntPath, tt);
1127 // }
1128 // case Class<?> c when c == long[].class -> {
1129 // @SuppressWarnings("unchecked")
1130 // Tunable<long[]> tt = (Tunable<long[]>) t;
1131 // entry = new TunableLongArrayEntry(ntPath, tt);
1132 // }
1133 // case Class<?> c when c == float[].class -> {
1134 // @SuppressWarnings("unchecked")
1135 // Tunable<float[]> tt = (Tunable<float[]>) t;
1136 // entry = new TunableFloatArrayEntry(ntPath, tt);
1137 // }
1138 // case Class<?> c when c == double[].class -> {
1139 // @SuppressWarnings("unchecked")
1140 // Tunable<double[]> tt = (Tunable<double[]>) t;
1141 // entry = new TunableDoubleArrayEntry(ntPath, tt);
1142 // }
1143 // case Class<?> c when c == String[].class -> {
1144 // @SuppressWarnings("unchecked")
1145 // Tunable<String[]> tt = (Tunable<String[]>) t;
1146 // entry = new TunableStringArrayEntry(ntPath, tt);
1147 // }
1148 // case Class<?> c when c == Boolean.class -> {
1149 // @SuppressWarnings("unchecked")
1150 // Tunable<Boolean> tt = (Tunable<Boolean>) t;
1151 // entry =
1152 // new NullableTunableValueEntry<>(
1153 // ntPath,
1154 // tt,
1155 // "boolean",
1156 // GenericPublisher::setBoolean,
1157 // NetworkTableValue::getBoolean);
1158 // }
1159 // case Class<?> c when c == Integer.class -> {
1160 // @SuppressWarnings("unchecked")
1161 // Tunable<Integer> tt = (Tunable<Integer>) t;
1162 // entry =
1163 // new NullableTunableValueEntry<>(
1164 // ntPath,
1165 // tt,
1166 // "int",
1167 // GenericPublisher::setInteger,
1168 // value -> (int) value.getInteger());
1169 // }
1170 // case Class<?> c when c == Long.class -> {
1171 // @SuppressWarnings("unchecked")
1172 // Tunable<Long> tt = (Tunable<Long>) t;
1173 // entry =
1174 // new NullableTunableValueEntry<>(
1175 // ntPath,
1176 // tt,
1177 // "int",
1178 // GenericPublisher::setInteger,
1179 // NetworkTableValue::getInteger);
1180 // }
1181 // case Class<?> c when c == Float.class -> {
1182 // @SuppressWarnings("unchecked")
1183 // Tunable<Float> tt = (Tunable<Float>) t;
1184 // entry =
1185 // new NullableTunableValueEntry<>(
1186 // ntPath, tt, "float", GenericPublisher::setFloat, NetworkTableValue::getFloat);
1187 // }
1188 // case Class<?> c when c == Double.class -> {
1189 // @SuppressWarnings("unchecked")
1190 // Tunable<Double> tt = (Tunable<Double>) t;
1191 // entry =
1192 // new NullableTunableValueEntry<>(
1193 // ntPath,
1194 // tt,
1195 // "double",
1196 // GenericPublisher::setDouble,
1197 // NetworkTableValue::getDouble);
1198 // }
1199 // default -> {
1200 // TunableRegistry.reportWarning(
1201 // "Tunable type "
1202 // + t.getTypeClass().getName()
1203 // + " is not supported by NetworkTables");
1204 // return false;
1205 // }
1206 // }
1207 // }
1208 // default -> {
1209 // TunableRegistry.reportWarning(
1210 // "Tunable implementation "
1211 // + tunable.getClass().getName()
1212 // + " is not supported by NetworkTables");
1213 // return false;
1214 // }
1215 // }
1216 // StoredEntry storedEntry = new StoredEntry(entry, tunable, null);
1217 // m_entries.put(path, storedEntry);
1218 // trackEntry(storedEntry);
1219 // initialUpdate = entry.updateInitialTunable();
1220 // if (initialUpdate != null) {
1221 // entry.updateNetwork();
1222 // }
1223 // }
1224
1225 // if (initialUpdate != null && initialUpdate.callback() != null) {
1226 // TunableRegistry.runAfterUpdate(initialUpdate.callback());
1227 // }
1228 // return true;
1229 // }
1230
1231 // @Override
1232 // public boolean publishComplex(String path, ComplexTunable tunable) {
1233 // synchronized (m_entries) {
1234 // if (m_closed) {
1235 // return false;
1236 // }
1237 // if (hasQueuedActiveEntry(path)) {
1238 // TunableRegistry.reportWarning(
1239 // "NetworkTables tunable '" + m_prefix + path + "' already exists");
1240 // return false;
1241 // }
1242 // if (m_updateDepth > 0) {
1243 // m_pendingPathStates.put(path, true);
1244 // m_pendingMutations.add(() -> publishComplex(path, tunable));
1245 // return true;
1246 // }
1247 // StoredEntry storedEntry =
1248 // new StoredEntry(new ComplexTunableEntry(m_prefix + path, tunable), null, tunable);
1249 // m_entries.put(path, storedEntry);
1250 // trackEntry(storedEntry);
1251 // }
1252
1253 // TunableRegistry.publishComplexChildren(path, tunable);
1254 // return true;
1255 // }
1256
1257 // @Override
1258 // public void remove(String path) {
1259 // synchronized (m_entries) {
1260 // if (m_closed) {
1261 // return;
1262 // }
1263 // StoredEntry entry = m_entries.get(path);
1264 // if (entry != null && !entry.closed) {
1265 // closeEntry(entry);
1266 // eraseEntry(path, entry);
1267 // } else if (m_updateDepth > 0 && Boolean.TRUE.equals(m_pendingPathStates.get(path))) {
1268 // m_pendingPathStates.put(path, false);
1269 // m_pendingMutations.add(() -> remove(path));
1270 // }
1271 // }
1272 // }
1273
1274 // @Override
1275 // public List<PublishedTunable> removePrefix(String prefix) {
1276 // String normalizedPrefix = PathUtil.normalizePrefix(prefix);
1277 // List<PublishedTunable> removed = new ArrayList<>();
1278 // synchronized (m_entries) {
1279 // var iterator = m_entries.entrySet().iterator();
1280 // while (iterator.hasNext()) {
1281 // var mapEntry = iterator.next();
1282 // if (!PathUtil.isPathOrDescendant(mapEntry.getKey(), normalizedPrefix)) {
1283 // continue;
1284 // }
1285 // StoredEntry entry = mapEntry.getValue();
1286 // if (entry.closed) {
1287 // continue;
1288 // }
1289 // removed.add(new PublishedTunable(mapEntry.getKey(), entry.tunable, entry.complex));
1290 // closeEntry(entry);
1291 // if (m_updateDepth > 0) {
1292 // String path = mapEntry.getKey();
1293 // m_pendingMutations.add(() -> eraseEntryNow(path, entry));
1294 // } else {
1295 // iterator.remove();
1296 // }
1297 // }
1298 // if (m_updateDepth > 0) {
1299 // List<String> pendingRemoves = new ArrayList<>();
1300 // for (var pendingEntry : m_pendingPathStates.entrySet()) {
1301 // if (pendingEntry.getValue()
1302 // && PathUtil.isPathOrDescendant(pendingEntry.getKey(), normalizedPrefix)) {
1303 // pendingRemoves.add(pendingEntry.getKey());
1304 // }
1305 // }
1306 // for (String path : pendingRemoves) {
1307 // m_pendingPathStates.put(path, false);
1308 // m_pendingMutations.add(() -> remove(path));
1309 // }
1310 // }
1311 // }
1312 // return removed;
1313 // }
1314
1315 // @Override
1316 // public void markDirty(TunableBase tunable) {
1317 // synchronized (m_entries) {
1318 // if (m_closed || isAlwaysGet(tunable) || !tunable.supportsChangeNotification()) {
1319 // return;
1320 // }
1321 // List<StoredEntry> entries = m_entriesByTunable.get(tunable);
1322 // if (entries == null) {
1323 // return;
1324 // }
1325 // for (StoredEntry entry : entries) {
1326 // enqueueDirtyEntry(entry);
1327 // }
1328 // }
1329 // }
1330
1331 // private void updateComplexEntries() {
1332 // try {
1333 // m_updatedComplexEntries.clear();
1334 // for (StoredEntry entry : m_complexEntries) {
1335 // if (!entry.closed && m_updatedComplexEntries.put(entry.complex, Boolean.TRUE) == null) {
1336 // entry.entry.updateNetwork();
1337 // }
1338 // }
1339 // } finally {
1340 // m_updatedComplexEntries.clear();
1341 // }
1342 // }
1343
1344 // private void updateAlwaysGetEntries() {
1345 // for (StoredEntry entry : m_alwaysGetEntries) {
1346 // if (!entry.closed) {
1347 // entry.entry.updateNetwork();
1348 // if (entry.tunable.hasChanged()) {
1349 // TunableRegistry.resetChangedAfterUpdate(entry.tunable);
1350 // }
1351 // }
1352 // }
1353 // }
1354
1355 // private void updatePolledEntries() {
1356 // for (StoredEntry entry : m_polledEntries) {
1357 // if (!entry.closed && entry.tunable.hasChanged()) {
1358 // entry.entry.updateNetwork();
1359 // TunableRegistry.resetChangedAfterUpdate(entry.tunable);
1360 // }
1361 // }
1362 // }
1363
1364 // private void updateDirtyEntries() {
1365 // for (StoredEntry entry : m_dirtyEntries) {
1366 // entry.dirtyQueued = false;
1367 // if (!entry.closed && entry.tunable.hasChanged()) {
1368 // entry.entry.updateNetwork();
1369 // TunableRegistry.resetChangedAfterUpdate(entry.tunable);
1370 // }
1371 // }
1372 // m_dirtyEntries.clear();
1373 // }
1374
1375 // private void processTuneEvent(NetworkTableEvent event, List<Runnable> onChangeCallbacks) {
1376 // if (event.valueData == null || event.valueData.value == null) {
1377 // return;
1378 // }
1379 // TunableValueEntry entry = m_subscriberMap.get(event.valueData.subentry);
1380 // if (entry == null) {
1381 // return;
1382 // }
1383 // Runnable callback = entry.updateTunable(event.valueData.value);
1384 // if (callback == null) {
1385 // return;
1386 // }
1387 // onChangeCallbacks.add(callback);
1388 // }
1389
1390 // private void processTuneEvents(NetworkTableEvent[] events, List<Runnable> onChangeCallbacks) {
1391 // for (NetworkTableEvent event : events) {
1392 // processTuneEvent(event, onChangeCallbacks);
1393 // }
1394 // }
1395
1396 // private void scheduleOnChangeCallbacks(List<Runnable> onChangeCallbacks) {
1397 // for (Runnable callback : onChangeCallbacks) {
1398 // TunableRegistry.runAfterUpdate(callback);
1399 // }
1400 // }
1401
1402 // private List<Runnable> acquireOnChangeCallbacks() {
1403 // if (m_usingOnChangeCallbacks) {
1404 // return new ArrayList<>();
1405 // }
1406 // m_usingOnChangeCallbacks = true;
1407 // m_onChangeCallbacks.clear();
1408 // return m_onChangeCallbacks;
1409 // }
1410
1411 // @SuppressWarnings("PMD.CompareObjectsWithEquals")
1412 // private void releaseOnChangeCallbacks(List<Runnable> onChangeCallbacks) {
1413 // onChangeCallbacks.clear();
1414 // synchronized (m_entries) {
1415 // if (onChangeCallbacks == m_onChangeCallbacks) {
1416 // m_usingOnChangeCallbacks = false;
1417 // }
1418 // }
1419 // }
1420
1421 // @Override
1422 // public void update() {
1423 // List<Runnable> onChangeCallbacks;
1424 // synchronized (m_entries) {
1425 // onChangeCallbacks = acquireOnChangeCallbacks();
1426 // }
1427 // try {
1428 // synchronized (m_entries) {
1429 // if (m_closed) {
1430 // return;
1431 // }
1432 // // update tunables from network changes
1433 // processTuneEvents(m_poller.readQueue(), onChangeCallbacks);
1434
1435 // // update network from tunable changes
1436 // // updateNetwork() can run user getters or complex update code that re-enters this backend.
1437 // m_updateDepth++;
1438 // try {
1439 // updateComplexEntries();
1440 // updateAlwaysGetEntries();
1441 // updatePolledEntries();
1442 // updateDirtyEntries();
1443 // } finally {
1444 // m_updateDepth--;
1445 // if (m_updateDepth == 0) {
1446 // applyPendingMutations();
1447 // }
1448 // }
1449 // }
1450
1451 // // onTune callbacks can publish or remove tunables, so run them without the backend lock held.
1452 // scheduleOnChangeCallbacks(onChangeCallbacks);
1453 // } finally {
1454 // releaseOnChangeCallbacks(onChangeCallbacks);
1455 // }
1456 // }
1457}
boolean publishComplex(String path, ComplexTunable tunable)
List< PublishedTunable > removePrefix(String prefix)
boolean publish(String path, TunableBase tunable)