Mercurial > hg > orthanc-stone
comparison Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp @ 1623:74be0f498b08
Updated mechanism to avoid using deleted objects in RequestAnimationFrame callbacks.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 04 Nov 2020 11:39:15 +0100 |
parents | 575f512cdf48 |
children | 2e3b2ed239b9 |
comparison
equal
deleted
inserted
replaced
1622:0f8d6791b403 | 1623:74be0f498b08 |
---|---|
135 that->Paint(*that->compositor_, *that->controller_); | 135 that->Paint(*that->compositor_, *that->controller_); |
136 } | 136 } |
137 } | 137 } |
138 else | 138 else |
139 { | 139 { |
140 LOG(INFO) << "WebAssemblyViewport::OnRequestAnimationFrame " | 140 LOG(TRACE) << "WebAssemblyViewport::OnRequestAnimationFrame: the " << |
141 << "-- the WebAssemblyViewport is deleted and Paint will " | 141 "WebAssemblyViewport is deleted and Paint will not be called."; |
142 << "not be called"; | 142 } |
143 } | 143 WebAssemblyViewport::ReleaseObjectCookie(userData); |
144 LOG(TRACE) << "Exiting: " << __func__; | 144 LOG(TRACE) << "Exiting: " << __func__; |
145 return true; | 145 return true; |
146 } | 146 } |
147 | 147 |
148 EM_BOOL WebAssemblyViewport::OnResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) | 148 EM_BOOL WebAssemblyViewport::OnResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) |
218 | 218 |
219 LOG(TRACE) << "Exiting: " << __func__; | 219 LOG(TRACE) << "Exiting: " << __func__; |
220 return true; | 220 return true; |
221 } | 221 } |
222 | 222 |
223 void* WebAssemblyViewport::GetObjectCookie() | 223 void* WebAssemblyViewport::CreateObjectCookie() |
224 { | 224 { |
225 if(objectCookie_ != NULL) | 225 boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = |
226 return objectCookie_; | 226 new boost::weak_ptr<WebAssemblyViewport>(); |
227 | 227 |
228 boost::shared_ptr<WebAssemblyViewport>* sharedFromThisPtr = | 228 *weakThisPtr = shared_from_this(); |
229 new boost::shared_ptr<WebAssemblyViewport>(); | 229 |
230 | 230 void* cookie = reinterpret_cast<void*>(weakThisPtr); |
231 *sharedFromThisPtr = shared_from_this(); | 231 |
232 | 232 LOG(TRACE) << "WebAssemblyViewport::CreateObjectCookie() => cookie = " |
233 objectCookie_ = reinterpret_cast<void*>(sharedFromThisPtr); | 233 << cookie << "\n"; |
234 | 234 |
235 return objectCookie_; | 235 return cookie; |
236 } | 236 } |
237 | 237 |
238 void WebAssemblyViewport::ReleaseObjectCookie(void* cookie) | 238 WebAssemblyViewport* WebAssemblyViewport::DereferenceObjectCookie(void* cookie) |
239 { | 239 { |
240 WebAssemblyViewport* This = DereferenceObjectCookie(cookie); | 240 LOG(TRACE) << "WebAssemblyViewport::DereferenceObjectCookie(cookie = " |
241 | 241 << cookie << ")\n"; |
242 if (This != NULL) | |
243 This->objectCookie_ = NULL; | |
244 | 242 |
245 boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = | 243 boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = |
246 reinterpret_cast<boost::weak_ptr<WebAssemblyViewport>*>(cookie); | 244 reinterpret_cast<boost::weak_ptr<WebAssemblyViewport>*>(cookie); |
247 | 245 |
248 delete weakThisPtr; | 246 boost::shared_ptr<WebAssemblyViewport> sharedThis = weakThisPtr->lock(); |
249 } | 247 |
250 | 248 return sharedThis.get(); |
251 WebAssemblyViewport* WebAssemblyViewport::DereferenceObjectCookie(void* cookie) | 249 } |
252 { | 250 |
251 void WebAssemblyViewport::ReleaseObjectCookie(void* cookie) | |
252 { | |
253 LOG(TRACE) << "WebAssemblyViewport::ReleaseObjectCookie(cookie = " | |
254 << cookie << ")\n"; | |
255 | |
253 boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = | 256 boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = |
254 reinterpret_cast<boost::weak_ptr<WebAssemblyViewport>*>(cookie); | 257 reinterpret_cast<boost::weak_ptr<WebAssemblyViewport>*>(cookie); |
255 | 258 |
256 boost::shared_ptr<WebAssemblyViewport> sharedThis = weakThisPtr->lock(); | 259 delete weakThisPtr; |
257 | |
258 return sharedThis.get(); | |
259 } | 260 } |
260 | 261 |
261 void WebAssemblyViewport::Invalidate() | 262 void WebAssemblyViewport::Invalidate() |
262 { | 263 { |
264 LOG(TRACE) << "WebAssemblyViewport::Invalidate()\n"; | |
263 long id = emscripten_request_animation_frame(OnRequestAnimationFrame, | 265 long id = emscripten_request_animation_frame(OnRequestAnimationFrame, |
264 GetObjectCookie()); | 266 CreateObjectCookie()); |
265 animationFrameCallbackIds_.push_back(id); | 267 //animationFrameCallbackIds_.push_back(id); |
266 } | 268 } |
267 | 269 |
268 void WebAssemblyViewport::FitForPrint() | 270 void WebAssemblyViewport::FitForPrint() |
269 { | 271 { |
270 if (compositor_.get() != NULL && | 272 if (compositor_.get() != NULL && |
303 canvasCssSelector_(canvasId), | 305 canvasCssSelector_(canvasId), |
304 #endif | 306 #endif |
305 interactor_(new DefaultViewportInteractor), | 307 interactor_(new DefaultViewportInteractor), |
306 enableEmscriptenMouseEvents_(enableEmscriptenMouseEvents), | 308 enableEmscriptenMouseEvents_(enableEmscriptenMouseEvents), |
307 canvasWidth_(0), | 309 canvasWidth_(0), |
308 canvasHeight_(0), | 310 canvasHeight_(0) |
309 objectCookie_(NULL) | |
310 { | 311 { |
311 } | 312 } |
312 | 313 |
313 void WebAssemblyViewport::PostConstructor() | 314 void WebAssemblyViewport::PostConstructor() |
314 { | 315 { |
368 } | 369 } |
369 } | 370 } |
370 | 371 |
371 WebAssemblyViewport::~WebAssemblyViewport() | 372 WebAssemblyViewport::~WebAssemblyViewport() |
372 { | 373 { |
373 // cancel the pending RequestAnimationFrame callbacks | 374 LOG(TRACE) << "WebAssemblyViewport::~WebAssemblyViewport()\n"; |
374 for(size_t i = 0; i < animationFrameCallbackIds_.size(); ++i) | 375 |
375 { | |
376 long id = animationFrameCallbackIds_[i]; | |
377 emscripten_cancel_animation_frame(id); | |
378 } | |
379 | |
380 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, | 376 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, |
381 reinterpret_cast<void*>(this), | 377 reinterpret_cast<void*>(this), |
382 false, | 378 false, |
383 NULL); | 379 NULL); |
384 | 380 |