@@ -40,9 +40,10 @@ class LayoutEvent(NamedTuple):
4040class ElementState (NamedTuple ):
4141 model : Dict [str , Any ]
4242 path : str
43+ element_id : int
4344 element_obj : AbstractElement
4445 event_handler_ids : Set [str ]
45- child_elements_ids : List [str ]
46+ child_elements_ids : List [int ]
4647 life_cycle_hook : LifeCycleHook
4748
4849
@@ -80,7 +81,7 @@ async def dispatch(self, event: LayoutEvent) -> None:
8081 async def render (self ) -> LayoutUpdate :
8182 while True :
8283 element = await self ._rendering_queue .get ()
83- if element . id in self ._element_states :
84+ if self ._has_element_state ( element ) :
8485 return self ._create_layout_update (element )
8586
8687 @async_resource
@@ -90,15 +91,15 @@ async def _rendering_queue(self) -> AsyncIterator["_ElementQueue"]:
9091 yield queue
9192
9293 @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 )
9596 try :
96- yield {self . root . id : root_element_state }
97+ yield {root_element_state . element_id : root_element_state }
9798 finally :
9899 self ._delete_element_state (root_element_state )
99100
100101 def _create_layout_update (self , element : AbstractElement ) -> LayoutUpdate :
101- element_state = self ._element_states [ element . id ]
102+ element_state = self ._get_element_state ( element )
102103
103104 element_state .life_cycle_hook .element_will_render ()
104105
@@ -169,10 +170,9 @@ def _render_model_children(
169170 resolved_children .append (self ._render_model (element_state , child ))
170171 elif isinstance (child , AbstractElement ):
171172 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 )
174174 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 ) )
176176 else :
177177 resolved_children .append (str (child ))
178178 return resolved_children
@@ -201,22 +201,36 @@ def _render_model_event_targets(
201201
202202 return {e : h .serialize () for e , h in handlers .items ()}
203203
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+
204210 def _create_element_state (
205- self , element : AbstractElement , path : str
211+ self ,
212+ element : AbstractElement ,
213+ path : str ,
214+ save : bool ,
206215 ) -> ElementState :
207- return ElementState (
216+ element_id = id (element )
217+ state = ElementState (
208218 model = {},
209219 path = path ,
220+ element_id = element_id ,
210221 element_obj = element ,
211222 event_handler_ids = set (),
212223 child_elements_ids = [],
213224 life_cycle_hook = LifeCycleHook (element , self .update ),
214225 )
226+ if save :
227+ self ._element_states [element_id ] = state
228+ return state
215229
216230 def _delete_element_state (self , element_state : ElementState ) -> None :
217231 self ._clear_element_state_event_handlers (element_state )
218232 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 ]
220234
221235 def _clear_element_state_event_handlers (self , element_state : ElementState ) -> None :
222236 for handler_id in element_state .event_handler_ids :
@@ -258,15 +272,16 @@ class _ElementQueue:
258272
259273 def __init__ (self ) -> None :
260274 self ._queue : "asyncio.Queue[AbstractElement]" = asyncio .Queue ()
261- self ._pending : Set [str ] = set ()
275+ self ._pending : Set [int ] = set ()
262276
263277 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 )
266281 self ._queue .put_nowait (element )
267282 return None
268283
269284 async def get (self ) -> AbstractElement :
270285 element = await self ._queue .get ()
271- self ._pending .remove (element . id )
286+ self ._pending .remove (id ( element ) )
272287 return element
0 commit comments