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