1
1
import functools
2
2
import inspect
3
+ from typing import Generic , Optional , TypeVar
3
4
4
5
from networktables import NetworkTables
5
6
from ntcore .value import Value
6
7
7
- # Only used as a marker
8
- class _TunableProperty (property ):
9
- pass
8
+ V = TypeVar ("V" )
10
9
11
10
12
- class _AutosendProperty (_TunableProperty ):
13
- pass
14
-
15
-
16
- def tunable (default , * , writeDefault = True , subtable = None , doc = None ):
11
+ class tunable (Generic [V ]):
17
12
"""
18
13
This allows you to define simple properties that allow you to easily
19
14
communicate with other programs via NetworkTables.
@@ -23,18 +18,17 @@ def tunable(default, *, writeDefault=True, subtable=None, doc=None):
23
18
24
19
class MyRobot(magicbot.MagicRobot):
25
20
26
- my_component = MyComponent
21
+ my_component: MyComponent
27
22
28
- ...
23
+ ...
29
24
30
25
from magicbot import tunable
31
26
32
27
class MyComponent:
33
28
34
29
# define the tunable property
35
30
foo = tunable(True)
36
-
37
-
31
+
38
32
def execute(self):
39
33
40
34
# set the variable
@@ -65,33 +59,48 @@ def execute(self):
65
59
# the name of the key is related to the name of the variable name in the
66
60
# robot class
67
61
68
- nt = NetworkTables
69
- mkv = Value .getFactory (default )
70
-
71
- def _get (self ):
72
- return getattr (self , prop ._ntattr ).value
73
-
74
- def _set (self , value ):
75
- v = getattr (self , prop ._ntattr )
76
- nt ._api .setEntryValueById (v ._local_id , mkv (value ))
77
-
78
- prop = _TunableProperty (fget = _get , fset = _set , doc = doc )
79
- prop ._ntdefault = default
80
- prop ._ntsubtable = subtable
81
- prop ._ntwritedefault = writeDefault
82
-
83
- return prop
84
-
85
-
86
- def setup_tunables (component , cname , prefix = "components" ):
62
+ __slots__ = (
63
+ "_ntdefault" ,
64
+ "_ntsubtable" ,
65
+ "_ntwritedefault" ,
66
+ # "__doc__",
67
+ "_mkv" ,
68
+ "_nt" ,
69
+ )
70
+
71
+ def __init__ (
72
+ self ,
73
+ default : V ,
74
+ * ,
75
+ writeDefault : bool = True ,
76
+ subtable : Optional [str ] = None
77
+ # , doc: Optional[str] = None
78
+ ) -> None :
79
+ self ._ntdefault = default
80
+ self ._ntsubtable = subtable
81
+ self ._ntwritedefault = writeDefault
82
+ # self.__doc__ = doc
83
+
84
+ self ._mkv = Value .getFactory (default )
85
+ self ._nt = NetworkTables
86
+
87
+ def __get__ (self , instance , owner ) -> V :
88
+ if instance is not None :
89
+ return instance ._tunables [self ].value
90
+ return self
91
+
92
+ def __set__ (self , instance , value ) -> None :
93
+ v = instance ._tunables [self ]
94
+ self ._nt ._api .setEntryValueById (v ._local_id , self ._mkv (value ))
95
+
96
+
97
+ def setup_tunables (component , cname : str , prefix : Optional [str ] = "components" ) -> None :
87
98
"""
88
99
Connects the tunables on an object to NetworkTables.
89
100
90
101
:param component: Component object
91
102
:param cname: Name of component
92
- :type cname: str
93
103
:param prefix: Prefix to use, or no prefix if None
94
- :type prefix: str
95
104
96
105
.. note:: This is not needed in normal use, only useful
97
106
for testing
@@ -104,27 +113,27 @@ def setup_tunables(component, cname, prefix="components"):
104
113
else :
105
114
prefix = "/%s/%s" % (prefix , cname )
106
115
116
+ tunables = {}
117
+
107
118
for n in dir (cls ):
108
119
if n .startswith ("_" ):
109
120
continue
110
121
111
122
prop = getattr (cls , n )
112
- if not isinstance (prop , _TunableProperty ):
123
+ if not isinstance (prop , tunable ):
113
124
continue
114
125
115
126
if prop ._ntsubtable :
116
127
key = "%s/%s/%s" % (prefix , prop ._ntsubtable , n )
117
128
else :
118
129
key = "%s/%s" % (prefix , n )
119
130
120
- ntattr = "_Tunable__%s" % n
121
-
122
131
ntvalue = NetworkTables .getGlobalAutoUpdateValue (
123
132
key , prop ._ntdefault , prop ._ntwritedefault
124
133
)
125
- # double indirection
126
- setattr ( component , ntattr , ntvalue )
127
- prop . _ntattr = ntattr
134
+ tunables [ prop ] = ntvalue
135
+
136
+ component . _tunables = tunables
128
137
129
138
130
139
def feedback (f = None , * , key : str = None ):
0 commit comments