1
1
import functools
2
2
import inspect
3
+ import typing
3
4
import warnings
4
5
from typing import Callable , Generic , Optional , TypeVar , overload
5
6
7
+ import ntcore
6
8
from ntcore import NetworkTableInstance , Value
7
9
from ntcore .types import ValueT
8
10
@@ -222,6 +224,40 @@ class MyRobot(magicbot.MagicRobot):
222
224
return f
223
225
224
226
227
+ _topic_types = {
228
+ bool : ntcore .BooleanTopic ,
229
+ int : ntcore .IntegerTopic ,
230
+ float : ntcore .DoubleTopic ,
231
+ str : ntcore .StringTopic ,
232
+ bytes : ntcore .RawTopic ,
233
+ }
234
+ _array_topic_types = {
235
+ bool : ntcore .BooleanArrayTopic ,
236
+ int : ntcore .IntegerArrayTopic ,
237
+ float : ntcore .DoubleArrayTopic ,
238
+ str : ntcore .StringArrayTopic ,
239
+ }
240
+
241
+
242
+ def _get_topic_type (
243
+ return_annotation ,
244
+ ) -> Optional [Callable [[ntcore .Topic ], typing .Any ]]:
245
+ if return_annotation in _topic_types :
246
+ return _topic_types [return_annotation ]
247
+
248
+ # Check for PEP 484 generic types
249
+ origin = getattr (return_annotation , "__origin__" , None )
250
+ args = typing .get_args (return_annotation )
251
+ if origin in (list , tuple ) and args :
252
+ # Ensure tuples are tuple[T, ...]
253
+ if origin is tuple and not (len (args ) == 2 and args [1 ] is Ellipsis ):
254
+ return None
255
+
256
+ inner_type = args [0 ]
257
+ if inner_type in _array_topic_types :
258
+ return _array_topic_types [inner_type ]
259
+
260
+
225
261
def collect_feedbacks (component , cname : str , prefix : Optional [str ] = "components" ):
226
262
"""
227
263
Finds all methods decorated with :func:`feedback` on an object
@@ -246,8 +282,19 @@ def collect_feedbacks(component, cname: str, prefix: Optional[str] = "components
246
282
else :
247
283
key = name
248
284
249
- entry = nt .getEntry (key )
250
- setter = entry .setValue
285
+ return_annotation = typing .get_type_hints (method ).get ("return" , None )
286
+ if return_annotation is not None :
287
+ topic_type = _get_topic_type (return_annotation )
288
+ else :
289
+ topic_type = None
290
+
291
+ if topic_type is None :
292
+ entry = nt .getEntry (key )
293
+ setter = entry .setValue
294
+ else :
295
+ publisher = topic_type (nt .getTopic (key )).publish ()
296
+ setter = publisher .set
297
+
251
298
feedbacks .append ((method , setter ))
252
299
253
300
return feedbacks
0 commit comments