1
- from ucomponent import invoke , get_methods , get_doc , get_list
1
+ from ucomponent import invoke , get_methods , get_doc , get_list , get_type , get_slot
2
2
3
- __all__ = [ 'Component' , 'get_component' , 'find_components' , 'components' ]
3
+ import event
4
4
5
- PRIMARY_COMPONENTS = {}
5
+ _list = list
6
+
7
+ __all__ = ['Component' , 'is_available' , 'get_primary' , 'get_primary_checked' , 'set_primary' ]
8
+
9
+ primaries = {}
6
10
7
11
8
12
class ComponentMethod :
13
+ __slots__ = "component" , "name"
14
+
9
15
def __init__ (self , component , name ):
10
16
self .component = component
11
17
self .name = name
@@ -15,7 +21,7 @@ def __call__(self, *args):
15
21
16
22
@property
17
23
def __doc__ (self ):
18
- return get_doc (self .component .address , self .name )
24
+ return doc (self .component .address , self .name )
19
25
20
26
def __repr__ (self ):
21
27
doc = self .__doc__
@@ -28,47 +34,119 @@ def __repr__(self):
28
34
29
35
30
36
class Component :
31
- def __init__ (self , address , type ):
37
+ __slots__ = "address" ,
38
+
39
+ def __init__ (self , address ):
32
40
self .address = address
33
- self .type = type
41
+
42
+ @property
43
+ def type (self ):
44
+ return get_type (self .address )
45
+
46
+ @property
47
+ def slot (self ):
48
+ return get_slot (self .address )
34
49
35
50
def __getattr__ (self , name ):
36
51
return ComponentMethod (self , name )
37
52
38
53
def __dir__ (self ):
39
- return dir (object ()) + ["address" , "type" ] + list ( get_methods ( self .address ) )
54
+ return dir (object ()) + ["address" , "type" , "slot" ] + methods ( self .address )
40
55
41
56
def __repr__ (self ):
42
57
return "Component<{0}:{1}>" .format (self .type , self .address )
43
58
44
59
45
- components = get_list # TODO: ?
60
+ def doc (address : str , method : str ):
61
+ return get_doc (address , method )
62
+
63
+
64
+ # noinspection PyShadowingBuiltins
65
+ def list (filter : str = None , exact : bool = True ):
66
+ if filter is None :
67
+ return [proxy (address ) for address in get_list ()]
68
+ elif exact :
69
+ return [proxy (address ) for address in get_list (filter )]
70
+ else :
71
+ return [proxy (address )
72
+ for address , component_type
73
+ in get_list ().items ()
74
+ if filter in component_type ]
75
+
76
+
77
+ def methods (address : str ) -> _list :
78
+ return _list (get_methods (address ))
79
+
80
+
81
+ def proxy (address : str ):
82
+ return Component (address )
83
+
84
+
85
+ def type (address : str ):
86
+ return get_type (address )
87
+
88
+
89
+ def slot (address : str ) -> int :
90
+ slot = get_slot (address )
91
+ return slot if slot is not None else - 1
92
+
93
+
94
+ def fields (address : str ):
95
+ raise NotImplementedError
96
+
97
+
98
+ def get (address : str , component_type : str ):
99
+ size = len (address )
100
+
101
+ for addr , compType in get_list (component_type ):
102
+ if addr [:size ] == address :
103
+ return proxy (addr )
104
+
105
+ raise Exception ("no such component" )
106
+
107
+
108
+ def is_available (component_type : str ):
109
+ return primaries .get (component_type ) is not None
110
+
111
+
112
+ def get_primary (component_type : str ) -> Component :
113
+ return primaries .get (component_type )
114
+
115
+
116
+ def get_primary_checked (component_type : str ) -> Component :
117
+ if not is_available (component_type ):
118
+ raise Exception ("no primary {!r} available" .format (component_type ))
119
+
120
+ return primaries [component_type ]
46
121
47
122
48
- def set_primary ( compoent ) :
49
- PRIMARY_COMPONENTS [ compoent . type ] = compoent
123
+ def load_primary ( component_type : str ) -> Component :
124
+ return primaries . get ( component_type )
50
125
51
126
52
- def get_component (component_type ):
53
- component = PRIMARY_COMPONENTS .get (component_type )
54
- if component :
55
- return component
127
+ def set_primary (component_type : str , address : str ):
128
+ primaries [component_type ] = proxy (address )
56
129
57
- for address in get_list (component_type ):
58
- component = Component (address , component_type )
59
- set_primary (component )
60
- return component
61
130
62
- return None
131
+ @event .register ("component_added" )
132
+ def on_component_added (_ , address , component_type ):
133
+ prev = primaries .get (component_type )
134
+ if prev is None :
135
+ primaries [component_type ] = proxy (address )
63
136
64
137
65
- # alias
66
- get = get_component
138
+ @event .register ("component_removed" )
139
+ def on_component_removed (_ , address , component_type ):
140
+ prev = primaries .get (component_type )
141
+ if prev is not None and prev .address == address :
142
+ del primaries [component_type ]
67
143
68
144
69
- def find_components ( component_type ) :
70
- return [ Component ( address , component_type ) for address in get_list ( component_type )]
145
+ def __getattr__ ( name : str ) -> Component :
146
+ return get_primary_checked ( name )
71
147
72
148
73
- # alias
74
- find = find_components
149
+ def setup ():
150
+ for address , component_type in get_list ().items ():
151
+ if not is_available (component_type ):
152
+ set_primary (component_type , address )
0 commit comments