RobotCore 1.0
WPILib port to raspberry Pi
Loading...
Searching...
No Matches
TunableConfig.java
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5package org.wpilib.tunable;
6
7import io.avaje.json.JsonException;
8import io.avaje.jsonb.JsonType;
9import io.avaje.jsonb.Jsonb;
10import java.util.HashMap;
11import java.util.Map;
12import java.util.Objects;
13
15public final class TunableConfig {
16 private static final class NoCopy {}
17
18 private static final Jsonb s_json = Jsonb.instance();
19 private static final JsonType<Object> s_jsonValue = s_json.type(Object.class);
20 private static final NoCopy NO_COPY = new NoCopy();
21
33
34 private final Map<String, String> m_properties;
35 private final boolean m_robust;
36 private final String m_typeString;
37 private final boolean m_mutable;
38 private final Runnable m_onTune;
39 private final Polling m_polling;
40
45 public TunableConfig() {
46 m_properties = Map.of();
47 m_robust = false;
48 m_typeString = null;
49 m_mutable = true;
50 m_onTune = null;
51 m_polling = Polling.DEFAULT;
52 }
53
65 Map<String, String> propertiesMap,
66 boolean robust,
67 String typeString,
68 boolean isMutable,
69 Runnable onTune,
70 boolean alwaysGet) {
71 this(
72 propertiesMap,
73 robust,
74 typeString,
76 onTune,
78 }
79
91 Map<String, String> propertiesMap,
92 boolean robust,
93 String typeString,
94 boolean isMutable,
95 Runnable onTune,
96 Polling polling) {
97 m_properties = validateProperties(propertiesMap);
98 m_robust = robust;
99 m_typeString = typeString;
100 m_mutable = isMutable;
101 m_onTune = onTune;
102 m_polling = Objects.requireNonNull(polling, "polling");
103 }
104
105 @SuppressWarnings("PMD.UnusedFormalParameter")
106 private TunableConfig(
107 Map<String, String> propertiesMap,
108 boolean robust,
109 String typeString,
110 boolean isMutable,
111 Runnable onTune,
112 Polling polling,
113 NoCopy noCopy) {
114 m_properties = propertiesMap;
115 m_robust = robust;
116 m_typeString = typeString;
117 m_mutable = isMutable;
118 m_onTune = onTune;
119 m_polling = Objects.requireNonNull(polling, "polling");
120 }
121
128 public static TunableConfig of(TunableOption... options) {
129 Map<String, String> propertiesMap = new HashMap<>();
130 boolean robust = false;
131 String typeString = null;
132 boolean isMutable = true;
133 Runnable onTune = null;
134 Polling polling = Polling.DEFAULT;
135 for (TunableOption option : options) {
136 switch (option) {
137 case TunableOption.Robust(boolean v) -> robust = v;
138 case TunableOption.Property(String k, String v) -> addProperty(propertiesMap, k, v);
139 case TunableOption.TypeString(String v) -> typeString = v;
140 case TunableOption.Mutable(boolean v) -> isMutable = v;
141 case TunableOption.OnTune(Runnable v) -> onTune = v;
142 case TunableOption.Polling(TunableConfig.Polling v) -> polling = v;
143 }
144 }
145 return new TunableConfig(
146 propertiesMap, robust, typeString, isMutable, onTune, polling, NO_COPY);
147 }
148
157 public TunableConfig withProperty(String key, String value) {
158 Map<String, String> newProperties = new HashMap<>(m_properties);
159 addProperty(newProperties, key, value);
160 TunableConfig config =
161 new TunableConfig(
162 newProperties, m_robust, m_typeString, m_mutable, m_onTune, m_polling, NO_COPY);
163 return config;
164 }
165
166 private static Map<String, String> validateProperties(Map<String, String> propertiesMap) {
167 Objects.requireNonNull(propertiesMap, "propertiesMap");
168 Map<String, String> validProperties = new HashMap<>();
169 propertiesMap.forEach((key, value) -> addProperty(validProperties, key, value));
170 return Map.copyOf(validProperties);
171 }
172
173 private static void addProperty(Map<String, String> propertiesMap, String key, String value) {
174 if (key == null) {
175 TunableRegistry.reportWarning("invalid property key");
176 return;
177 }
178 if (!isValidPropertyJson(value)) {
179 TunableRegistry.reportWarning("invalid property JSON for property '" + key + "'");
180 return;
181 }
182 propertiesMap.put(key, value);
183 }
184
185 private static boolean isValidPropertyJson(String value) {
186 if (value == null) {
187 return false;
188 }
189 try {
190 s_jsonValue.fromJson(value);
191 return true;
192 } catch (JsonException e) {
193 return false;
194 }
195 }
196
203 public TunableConfig withRobust(boolean robust) {
204 return new TunableConfig(
205 m_properties, robust, m_typeString, m_mutable, m_onTune, m_polling, NO_COPY);
206 }
207
214 public TunableConfig withTypeString(String typeString) {
215 return new TunableConfig(
216 m_properties, m_robust, typeString, m_mutable, m_onTune, m_polling, NO_COPY);
217 }
218
227 return new TunableConfig(
228 m_properties, m_robust, m_typeString, isMutable, m_onTune, m_polling, NO_COPY);
229 }
230
239 public TunableConfig withOnTune(Runnable onTune) {
240 return new TunableConfig(
241 m_properties, m_robust, m_typeString, m_mutable, onTune, m_polling, NO_COPY);
242 }
243
250 public TunableConfig withAlwaysGet(boolean alwaysGet) {
251 return withPolling(alwaysGet ? Polling.ALWAYS_GET : Polling.GET_ON_CHANGE);
252 }
253
261 return new TunableConfig(
262 m_properties, m_robust, m_typeString, m_mutable, m_onTune, polling, NO_COPY);
263 }
264
270 public String getProperties() {
271 StringBuilder sb = new StringBuilder(64);
272 sb.append('{');
273 m_properties.forEach(
274 (k, v) -> {
275 sb.append(s_json.toJson(k)).append(':').append(v).append(',');
276 });
277 if (sb.length() > 1) {
278 sb.setCharAt(sb.length() - 1, '}');
279 } else {
280 sb.append('}');
281 }
282 return sb.toString();
283 }
284
290 public boolean isRobust() {
291 return m_robust;
292 }
293
299 public String getTypeString() {
300 return m_typeString;
301 }
302
309 public boolean isMutable() {
310 return m_mutable;
311 }
312
320 public Runnable getOnTune() {
321 return m_onTune;
322 }
323
329 public boolean isAlwaysGet() {
330 return m_polling == Polling.ALWAYS_GET;
331 }
332
339 return m_polling;
340 }
341}
TunableConfig(Map< String, String > propertiesMap, boolean robust, String typeString, boolean isMutable, Runnable onTune, boolean alwaysGet)
TunableConfig withMutable(boolean isMutable)
TunableConfig withRobust(boolean robust)
TunableConfig withOnTune(Runnable onTune)
TunableConfig withProperty(String key, String value)
TunableConfig withPolling(Polling polling)
TunableConfig withAlwaysGet(boolean alwaysGet)
static TunableConfig of(TunableOption... options)
TunableConfig withTypeString(String typeString)
TunableConfig(Map< String, String > propertiesMap, boolean robust, String typeString, boolean isMutable, Runnable onTune, Polling polling)
record Robust(boolean value) implements TunableOption
record Polling(TunableConfig.Polling polling) implements TunableOption
record OnTune(Runnable callback) implements TunableOption
record TypeString(String typeString) implements TunableOption
record Property(String key, String value) implements TunableOption
record Mutable(boolean isMutable) implements TunableOption