@@ -13,16 +13,17 @@ class vtkWebPublishImageDelivery(vtkWebProtocol):
1313 def __init__ (self , decode = True ):
1414 super ().__init__ ()
1515 self .tracking_views = {}
16- self .last_stale_time = 0
17- self .stale_handler_count = 0
16+ self .last_stale_time = {}
17+ self .stale_handler_count = {}
1818 self .delta_stale_time_before_render = 0.5 # 0.5s
19+ self .stale_count_limit = 10
1920 self .decode = decode
2021 self .views_in_animations = []
2122 self .target_frame_rate = 30.0
2223 self .min_frame_rate = 12.0
2324 self .max_frame_rate = 30.0
2425
25- def push_render (self , v_id , ignore_animation = False ):
26+ def push_render (self , v_id , ignore_animation = False , stale_count = 0 ):
2627 if v_id not in self .tracking_views :
2728 return
2829
@@ -63,29 +64,36 @@ def push_render(self, v_id, ignore_animation=False):
6364 reply ["id" ] = v_id
6465 self .publish ("viewport.image.push.subscription" , reply )
6566 if stale :
66- self .last_stale_time = time .time ()
67- if self .stale_handler_count == 0 :
68- self .stale_handler_count += 1
67+ # The image has not been encoded yet.
68+ self .last_stale_time [v_id ] = time .time ()
69+ if self .stale_handler_count [v_id ] == 0 :
70+ self .stale_handler_count [v_id ] += 1
6971 schedule_callback (
7072 self .delta_stale_time_before_render ,
71- lambda : self .render_stale_image (v_id ),
73+ lambda : self .render_stale_image (v_id , stale_count ),
7274 )
7375 else :
74- self .last_stale_time = 0
75-
76- def render_stale_image (self , v_id ):
77- self .stale_handler_count -= 1
78-
79- if self .last_stale_time != 0 :
80- delta = time .time () - self .last_stale_time
81- if delta >= self .delta_stale_time_before_render :
82- self .push_render (v_id )
83- else :
84- self .stale_handler_count += 1
85- schedule_callback (
86- self .delta_stale_time_before_render - delta + 0.001 ,
87- lambda : self .render_stale_image (v_id ),
88- )
76+ self .last_stale_time [v_id ] = 0
77+
78+ def render_stale_image (self , v_id , stale_count = 0 ):
79+ if v_id in self .stale_handler_count and self .stale_handler_count [v_id ] > 0 :
80+ self .stale_handler_count [v_id ] -= 1
81+
82+ if self .last_stale_time [v_id ] != 0 :
83+ delta = time .time () - self .last_stale_time [v_id ]
84+ # Break on stale_count otherwise linked view will always report to be stale
85+ # And loop forever
86+ if (
87+ delta >= (self .delta_stale_time_before_render * (stale_count + 1 ))
88+ and stale_count < self .stale_count_limit
89+ ):
90+ self .push_render (v_id , False , stale_count + 1 )
91+ elif delta < self .delta_stale_time_before_render :
92+ self .stale_handler_count [v_id ] += 1
93+ schedule_callback (
94+ self .delta_stale_time_before_render - delta + 0.001 ,
95+ lambda : self .render_stale_image (v_id , stale_count ),
96+ )
8997
9098 def animate (self ):
9199 if len (self .views_in_animations ) == 0 :
@@ -155,6 +163,17 @@ def still_render(self, options):
155163 """
156164 begin_time = int (round (time .time () * 1000 ))
157165 view = self .get_view (options ["view" ])
166+ if not view :
167+ # The view has been deleted, we can not render it...
168+ # Clean up old view state
169+ real_view_id = str (self .get_global_id (view ))
170+ if real_view_id in self .views_in_animations :
171+ self .views_in_animations .remove (real_view_id )
172+ if real_view_id in self .tracking_views :
173+ del self .tracking_views [real_view_id ]
174+ if real_view_id in self .stale_handler_count :
175+ del self .stale_handler_count [real_view_id ]
176+
158177 size = view .GetSize ()[0 :2 ]
159178 resize = size != options .get ("size" , size )
160179 if resize :
@@ -245,6 +264,7 @@ def stop_callback(*_, **__):
245264 "enabled" : True ,
246265 "quality" : 100 ,
247266 }
267+ self .stale_handler_count [real_view_id ] = 0
248268 else :
249269 # There is an observer on this view already
250270 self .tracking_views [real_view_id ]["observerCount" ] += 1
0 commit comments