@@ -40,9 +40,10 @@ class LayoutEvent(NamedTuple):
40
40
class ElementState (NamedTuple ):
41
41
model : Dict [str , Any ]
42
42
path : str
43
+ element_id : int
43
44
element_obj : AbstractElement
44
45
event_handler_ids : Set [str ]
45
- child_elements_ids : List [str ]
46
+ child_elements_ids : List [int ]
46
47
life_cycle_hook : LifeCycleHook
47
48
48
49
@@ -80,7 +81,7 @@ async def dispatch(self, event: LayoutEvent) -> None:
80
81
async def render (self ) -> LayoutUpdate :
81
82
while True :
82
83
element = await self ._rendering_queue .get ()
83
- if element . id in self ._element_states :
84
+ if self ._has_element_state ( element ) :
84
85
return self ._create_layout_update (element )
85
86
86
87
@async_resource
@@ -90,15 +91,15 @@ async def _rendering_queue(self) -> AsyncIterator["_ElementQueue"]:
90
91
yield queue
91
92
92
93
@async_resource
93
- async def _element_states (self ) -> AsyncIterator [Dict [str , ElementState ]]:
94
- root_element_state = self ._create_element_state (self .root , "" )
94
+ async def _element_states (self ) -> AsyncIterator [Dict [int , ElementState ]]:
95
+ root_element_state = self ._create_element_state (self .root , "" , save = False )
95
96
try :
96
- yield {self . root . id : root_element_state }
97
+ yield {root_element_state . element_id : root_element_state }
97
98
finally :
98
99
self ._delete_element_state (root_element_state )
99
100
100
101
def _create_layout_update (self , element : AbstractElement ) -> LayoutUpdate :
101
- element_state = self ._element_states [ element . id ]
102
+ element_state = self ._get_element_state ( element )
102
103
103
104
element_state .life_cycle_hook .element_will_render ()
104
105
@@ -169,10 +170,9 @@ def _render_model_children(
169
170
resolved_children .append (self ._render_model (element_state , child ))
170
171
elif isinstance (child , AbstractElement ):
171
172
child_path = f"{ element_state .path } /children/{ index } "
172
- child_state = self ._create_element_state (child , child_path )
173
- self ._element_states [child .id ] = child_state
173
+ child_state = self ._create_element_state (child , child_path , save = True )
174
174
resolved_children .append (self ._render_element (child_state ))
175
- element_state .child_elements_ids .append (child . id )
175
+ element_state .child_elements_ids .append (id ( child ) )
176
176
else :
177
177
resolved_children .append (str (child ))
178
178
return resolved_children
@@ -201,22 +201,36 @@ def _render_model_event_targets(
201
201
202
202
return {e : h .serialize () for e , h in handlers .items ()}
203
203
204
+ def _get_element_state (self , element : AbstractElement ) -> ElementState :
205
+ return self ._element_states [id (element )]
206
+
207
+ def _has_element_state (self , element : AbstractElement ) -> bool :
208
+ return id (element ) in self ._element_states
209
+
204
210
def _create_element_state (
205
- self , element : AbstractElement , path : str
211
+ self ,
212
+ element : AbstractElement ,
213
+ path : str ,
214
+ save : bool ,
206
215
) -> ElementState :
207
- return ElementState (
216
+ element_id = id (element )
217
+ state = ElementState (
208
218
model = {},
209
219
path = path ,
220
+ element_id = element_id ,
210
221
element_obj = element ,
211
222
event_handler_ids = set (),
212
223
child_elements_ids = [],
213
224
life_cycle_hook = LifeCycleHook (element , self .update ),
214
225
)
226
+ if save :
227
+ self ._element_states [element_id ] = state
228
+ return state
215
229
216
230
def _delete_element_state (self , element_state : ElementState ) -> None :
217
231
self ._clear_element_state_event_handlers (element_state )
218
232
self ._delete_element_state_children (element_state )
219
- del self ._element_states [element_state .element_obj . id ]
233
+ del self ._element_states [element_state .element_id ]
220
234
221
235
def _clear_element_state_event_handlers (self , element_state : ElementState ) -> None :
222
236
for handler_id in element_state .event_handler_ids :
@@ -258,15 +272,16 @@ class _ElementQueue:
258
272
259
273
def __init__ (self ) -> None :
260
274
self ._queue : "asyncio.Queue[AbstractElement]" = asyncio .Queue ()
261
- self ._pending : Set [str ] = set ()
275
+ self ._pending : Set [int ] = set ()
262
276
263
277
def put (self , element : AbstractElement ) -> None :
264
- if element .id not in self ._pending :
265
- self ._pending .add (element .id )
278
+ element_id = id (element )
279
+ if element_id not in self ._pending :
280
+ self ._pending .add (element_id )
266
281
self ._queue .put_nowait (element )
267
282
return None
268
283
269
284
async def get (self ) -> AbstractElement :
270
285
element = await self ._queue .get ()
271
- self ._pending .remove (element . id )
286
+ self ._pending .remove (id ( element ) )
272
287
return element
0 commit comments