RobotCore
1.0
WPILib port to raspberry Pi
Toggle main menu visibility
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
7
package
org.wpilib.backend;
8
9
import
java.util.List;
10
11
import
org.wpilib.networktables.NetworkTableInstance;
12
import
org.wpilib.tunable.ComplexTunable;
13
import
org.wpilib.tunable.TunableBackend;
14
import
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
61
public
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
}
org.wpilib.backend.NetworkTablesTunableBackend.publishComplex
boolean publishComplex(String path, ComplexTunable tunable)
Definition
NetworkTablesTunableBackend.java:79
org.wpilib.backend.NetworkTablesTunableBackend.removePrefix
List< PublishedTunable > removePrefix(String prefix)
Definition
NetworkTablesTunableBackend.java:91
org.wpilib.backend.NetworkTablesTunableBackend.update
void update()
Definition
NetworkTablesTunableBackend.java:97
org.wpilib.backend.NetworkTablesTunableBackend.publish
boolean publish(String path, TunableBase tunable)
Definition
NetworkTablesTunableBackend.java:73
org.wpilib.networktables.NetworkTableInstance
Definition
NetworkTableInstance.java:47
org.wpilib.tunable.TunableBase
Definition
TunableBase.java:9
org.wpilib.tunable.ComplexTunable
Definition
ComplexTunable.java:9
org.wpilib.tunable.TunableBackend
Definition
TunableBackend.java:10
org
wpilib
backend
NetworkTablesTunableBackend.java
Generated by
1.18.0