11import functools
22import inspect
3+ import typing
34import warnings
45from typing import Callable , Generic , Optional , TypeVar , overload
56
7+ import ntcore
68from ntcore import NetworkTableInstance , Value
79from ntcore .types import ValueT
810
@@ -222,6 +224,40 @@ class MyRobot(magicbot.MagicRobot):
222224 return f
223225
224226
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+
225261def collect_feedbacks (component , cname : str , prefix : Optional [str ] = "components" ):
226262 """
227263 Finds all methods decorated with :func:`feedback` on an object
@@ -246,8 +282,19 @@ def collect_feedbacks(component, cname: str, prefix: Optional[str] = "components
246282 else :
247283 key = name
248284
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+
251298 feedbacks .append ((method , setter ))
252299
253300 return feedbacks
0 commit comments