Mercurial > hg > orthanc-stone
diff Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp @ 1621:575f512cdf48
Used a weak_ptr as a cookie to RequestAnimationFrame to prevent
accessing a deleted viewport.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Mon, 02 Nov 2020 20:45:04 +0100 |
parents | 9a52bac0c2a7 |
children | 74be0f498b08 |
line wrap: on
line diff
--- a/Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp Mon Nov 02 17:56:49 2020 +0100 +++ b/Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp Mon Nov 02 20:45:04 2020 +0100 @@ -120,19 +120,27 @@ } }; - EM_BOOL WebAssemblyViewport::OnRequestAnimationFrame(double time, void *userData) { LOG(TRACE) << __func__; - WebAssemblyViewport* that = reinterpret_cast<WebAssemblyViewport*>(userData); - if (that->compositor_.get() != NULL && - that->controller_ /* should always be true */) + WebAssemblyViewport* that = + WebAssemblyViewport::DereferenceObjectCookie(userData); + + if (that != NULL) { - that->animationFrameCallbackIds_.clear(); - that->Paint(*that->compositor_, *that->controller_); + if (that->compositor_.get() != NULL && + that->controller_ /* should always be true */) + { + that->Paint(*that->compositor_, *that->controller_); + } + } + else + { + LOG(INFO) << "WebAssemblyViewport::OnRequestAnimationFrame " + << "-- the WebAssemblyViewport is deleted and Paint will " + << "not be called"; } - LOG(TRACE) << "Exiting: " << __func__; return true; } @@ -212,10 +220,48 @@ return true; } + void* WebAssemblyViewport::GetObjectCookie() + { + if(objectCookie_ != NULL) + return objectCookie_; + + boost::shared_ptr<WebAssemblyViewport>* sharedFromThisPtr = + new boost::shared_ptr<WebAssemblyViewport>(); + + *sharedFromThisPtr = shared_from_this(); + + objectCookie_ = reinterpret_cast<void*>(sharedFromThisPtr); + + return objectCookie_; + } + + void WebAssemblyViewport::ReleaseObjectCookie(void* cookie) + { + WebAssemblyViewport* This = DereferenceObjectCookie(cookie); + + if (This != NULL) + This->objectCookie_ = NULL; + + boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = + reinterpret_cast<boost::weak_ptr<WebAssemblyViewport>*>(cookie); + + delete weakThisPtr; + } + + WebAssemblyViewport* WebAssemblyViewport::DereferenceObjectCookie(void* cookie) + { + boost::weak_ptr<WebAssemblyViewport>* weakThisPtr = + reinterpret_cast<boost::weak_ptr<WebAssemblyViewport>*>(cookie); + + boost::shared_ptr<WebAssemblyViewport> sharedThis = weakThisPtr->lock(); + + return sharedThis.get(); + } + void WebAssemblyViewport::Invalidate() { long id = emscripten_request_animation_frame(OnRequestAnimationFrame, - reinterpret_cast<void*>(this)); + GetObjectCookie()); animationFrameCallbackIds_.push_back(id); } @@ -259,7 +305,8 @@ interactor_(new DefaultViewportInteractor), enableEmscriptenMouseEvents_(enableEmscriptenMouseEvents), canvasWidth_(0), - canvasHeight_(0) + canvasHeight_(0), + objectCookie_(NULL) { }