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
22
3- __all__ = [ 'Component' , 'get_component' , 'find_components' , 'components' ]
3+ import event
44
5- PRIMARY_COMPONENTS = {}
5+ _list = list
6+ 7+ __all__ = ['Component' , 'is_available' , 'get_primary' , 'get_primary_checked' , 'set_primary' ]
8+ 9+ primaries = {}
610
711
812class ComponentMethod :
13+ __slots__ = "component" , "name"
14+ 915 def __init__ (self , component , name ):
1016 self .component = component
1117 self .name = name
@@ -15,7 +21,7 @@ def __call__(self, *args):
1521
1622 @property
1723 def __doc__ (self ):
18- return get_doc (self .component .address , self .name )
24+ return doc (self .component .address , self .name )
1925
2026 def __repr__ (self ):
2127 doc = self .__doc__
@@ -28,47 +34,119 @@ def __repr__(self):
2834
2935
3036class Component :
31- def __init__ (self , address , type ):
37+ __slots__ = "address" ,
38+ 39+ def __init__ (self , address ):
3240 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 )
3449
3550 def __getattr__ (self , name ):
3651 return ComponentMethod (self , name )
3752
3853 def __dir__ (self ):
39- return dir (object ()) + ["address" , "type" ] + list ( get_methods ( self .address ) )
54+ return dir (object ()) + ["address" , "type" , "slot" ] + methods ( self .address )
4055
4156 def __repr__ (self ):
4257 return "Component<{0}:{1}>" .format (self .type , self .address )
4358
4459
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 ]
46121
47122
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 )
50125
51126
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 )
56129
57- for address in get_list (component_type ):
58- component = Component (address , component_type )
59- set_primary (component )
60- return component
61130
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 )
63136
64137
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 ]
67143
68144
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 )
71147
72148
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