Mercurial > hg > orthanc-stone
changeset 247:3d523c9a8f0d am
trying to use boost::signals2 even more.
line wrap: on
line diff
--- a/Applications/Samples/SimpleViewerApplication.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Applications/Samples/SimpleViewerApplication.h Mon Jul 02 12:32:02 2018 +0200 @@ -179,7 +179,7 @@ // Once the geometry of the series is downloaded from Orthanc, // display its first slice, and adapt the viewport to fit this // slice - if (source_ == &source) + if (source_.get() == &source) { //SetSlice(source_->GetSliceCount() / 2); } @@ -187,12 +187,8 @@ mainLayout_->SetDefaultView(); } - void OnGeometryReady(const ILayerSource& source) - { - mainLayout_->SetDefaultView(); - } - virtual void NotifyGeometryError(const ILayerSource& source) + void NotifyGeometryError(const ILayerSource& source) { } @@ -205,7 +201,7 @@ { } - virtual void NotifyLayerReady(std::auto_ptr<ILayerRenderer>& layer, + virtual void NotifyLayerReady(boost::shared_ptr<ILayerRenderer> renderer, const ILayerSource& source, const CoordinateSystem3D& slice, bool isError) @@ -215,14 +211,14 @@ std::unique_ptr<Interactor> interactor_; LayoutWidget* mainLayout_; LayoutWidget* thumbnailsLayout_; - LayerWidget* mainViewport_; - std::vector<LayerWidget*> thumbnails_; + boost::shared_ptr<LayerWidget> mainViewport_; + std::vector<boost::shared_ptr<LayerWidget>> thumbnails_; std::vector<std::string> instances_; unsigned int currentInstanceIndex_; OrthancStone::WidgetViewport* wasmViewport1_; OrthancStone::WidgetViewport* wasmViewport2_; - OrthancFrameLayerSource* source_; + boost::shared_ptr<OrthancFrameLayerSource> source_; unsigned int slice_; public: @@ -288,27 +284,30 @@ thumbnailsLayout_->SetBackgroundColor(50, 50, 50); thumbnailsLayout_->SetVertical(); - mainViewport_ = new LayerWidget(); - thumbnails_.push_back(new LayerWidget()); - thumbnails_.push_back(new LayerWidget()); + mainViewport_.reset(new LayerWidget()); + thumbnails_.push_back(boost::shared_ptr<LayerWidget>(new LayerWidget())); + thumbnails_.push_back(boost::shared_ptr<LayerWidget>(new LayerWidget())); // hierarchy mainLayout_->AddWidget(thumbnailsLayout_); - mainLayout_->AddWidget(mainViewport_); - thumbnailsLayout_->AddWidget(thumbnails_[0]); - thumbnailsLayout_->AddWidget(thumbnails_[1]); + mainLayout_->AddWidget(mainViewport_.get()); + thumbnailsLayout_->AddWidget(thumbnails_[0].get()); + thumbnailsLayout_->AddWidget(thumbnails_[1].get()); // sources - source_ = new OrthancFrameLayerSource(context_->GetWebService()); + source_.reset(new OrthancFrameLayerSource()); + source_->Init(context_->GetWebService()); source_->LoadFrame(instances_[currentInstanceIndex_], 0); // source_->Register(*this); - source_->SignalGeometryReady.connect(boost::bind(&SimpleViewerApplication::OnGeometryReady, this, _1)); + //source_->SignalGeometryReady.connect(boost::bind(&SimpleViewerApplication::NotifyGeometryReady, this, _1)); mainViewport_->AddLayer(source_); - OrthancFrameLayerSource* thumb0 = new OrthancFrameLayerSource(context_->GetWebService()); + boost::shared_ptr<OrthancFrameLayerSource> thumb0(new OrthancFrameLayerSource()); + thumb0->Init(context_->GetWebService()); thumb0->LoadFrame(instances_[0], 0); - OrthancFrameLayerSource* thumb1 = new OrthancFrameLayerSource(context_->GetWebService()); + boost::shared_ptr<OrthancFrameLayerSource> thumb1(new OrthancFrameLayerSource()); + thumb1->Init(context_->GetWebService()); thumb1->LoadFrame(instances_[1], 0); thumbnails_[0]->AddLayer(thumb0); @@ -323,7 +322,7 @@ virtual void InitializeWasm() { AttachWidgetToWasmViewport("canvas", thumbnailsLayout_); - AttachWidgetToWasmViewport("canvas2", mainViewport_); + AttachWidgetToWasmViewport("canvas2", mainViewport_.get()); //TODO: check object lifecycle } #endif void NextImage(WorldSceneWidget& widget) { @@ -331,11 +330,16 @@ currentInstanceIndex_ = (currentInstanceIndex_ + 1) % instances_.size(); - std::auto_ptr<OrthancFrameLayerSource> layer - (new OrthancFrameLayerSource(context_->GetWebService())); - layer->LoadFrame(instances_[currentInstanceIndex_], 0); + source_.reset(new OrthancFrameLayerSource()); + source_->Init(context_->GetWebService()); + source_->LoadFrame(instances_[currentInstanceIndex_], 0); + - mainViewport_->ReplaceLayer(0, layer.release()); +// std::auto_ptr<OrthancFrameLayerSource> layer +// (new OrthancFrameLayerSource(context_->GetWebService())); +// layer->LoadFrame(instances_[currentInstanceIndex_], 0); + + mainViewport_->ReplaceLayer(0, source_); // source_->LoadFrame("45b7e6bc-168e8ed1-063dc08d-cffd6431-133a276a", 0); }
--- a/Framework/Layers/DicomStructureSetRendererFactory.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Layers/DicomStructureSetRendererFactory.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -130,7 +130,7 @@ { if (loader_.HasStructureSet()) { - NotifyLayerReady(new Renderer(loader_.GetStructureSet(), viewportSlice), viewportSlice, false); + NotifyLayerReady(boost::shared_ptr<ILayerRenderer>(new Renderer(loader_.GetStructureSet(), viewportSlice)), viewportSlice, false); } } }
--- a/Framework/Layers/ILayerSource.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Layers/ILayerSource.h Mon Jul 02 12:32:02 2018 +0200 @@ -23,6 +23,7 @@ #include "ILayerRenderer.h" #include "../Toolbox/Slice.h" +#include <boost/shared_ptr.hpp> namespace OrthancStone { @@ -52,8 +53,8 @@ const Slice& slice) = 0; // The layer must be deleted by the observer that releases the - // std::auto_ptr - virtual void NotifyLayerReady(std::auto_ptr<ILayerRenderer>& layer, + // std::auto_ptr // TODO: check the lifecycle of the layer since we are not using an std::auto_ptr anymore + virtual void NotifyLayerReady(boost::shared_ptr<ILayerRenderer> renderer, const ILayerSource& source, const CoordinateSystem3D& slice, bool isError) = 0; // TODO Shouldn't this be separate as NotifyLayerError? @@ -63,7 +64,7 @@ { } - virtual void Register(IObserver& observer) = 0; + virtual void Register(boost::shared_ptr<IObserver> observer) = 0; virtual bool GetExtent(std::vector<Vector>& points, const CoordinateSystem3D& viewportSlice) = 0;
--- a/Framework/Layers/LayerSourceBase.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Layers/LayerSourceBase.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -27,65 +27,64 @@ { namespace { - class LayerReadyFunctor : public boost::noncopyable - { - private: - std::auto_ptr<ILayerRenderer> layer_; - const CoordinateSystem3D& slice_; - bool isError_; +// class LayerReadyFunctor : public boost::noncopyable +// { +// private: +// std::auto_ptr<ILayerRenderer> layer_; +// const CoordinateSystem3D& slice_; +// bool isError_; - public: - LayerReadyFunctor(ILayerRenderer* layer, - const CoordinateSystem3D& slice, - bool isError) : - layer_(layer), - slice_(slice), - isError_(isError) - { - } +// public: +// LayerReadyFunctor(ILayerRenderer* layer, +// const CoordinateSystem3D& slice, +// bool isError) : +// layer_(layer), +// slice_(slice), +// isError_(isError) +// { +// } - void operator() (ILayerSource::IObserver& observer, - const ILayerSource& source) - { - observer.NotifyLayerReady(layer_, source, slice_, isError_); - } - }; +// void operator() (ILayerSource::IObserver& observer, +// const ILayerSource& source) +// { +// observer.NotifyLayerReady(layer_, source, slice_, isError_); +// } +// }; } void LayerSourceBase::NotifyGeometryReady() { - //new observers SignalGeometryReady(*this); - - //old observers - observers_.Apply(*this, &IObserver::NotifyGeometryReady); } void LayerSourceBase::NotifyGeometryError() { - observers_.Apply(*this, &IObserver::NotifyGeometryError); + SignalGeometryError(*this); } void LayerSourceBase::NotifyContentChange() { - observers_.Apply(*this, &IObserver::NotifyContentChange); + SignalContentChange(*this); } void LayerSourceBase::NotifySliceChange(const Slice& slice) { - observers_.Apply(*this, &IObserver::NotifySliceChange, slice); + SignalSliceChange(*this, slice); } - void LayerSourceBase::NotifyLayerReady(ILayerRenderer* layer, + void LayerSourceBase::NotifyLayerReady(boost::shared_ptr<ILayerRenderer> renderer, const CoordinateSystem3D& slice, bool isError) { - LayerReadyFunctor functor(layer, slice, isError); - observers_.Notify(*this, functor); + SignalLayerReady(renderer, *this, slice, isError); } - void LayerSourceBase::Register(IObserver& observer) + void LayerSourceBase::Register(boost::shared_ptr<IObserver> observer) { - observers_.Register(observer); + SignalGeometryReady.connect(LayerSourceBase::SignalGeometryReadyType::slot_type(&IObserver::NotifyGeometryReady, observer.get(), _1).track(observer)); + SignalGeometryError.connect(LayerSourceBase::SignalGeometryErrorType::slot_type(&IObserver::NotifyGeometryError, observer.get(), _1).track(observer)); + SignalContentChange.connect(LayerSourceBase::SignalContentChangeType::slot_type(&IObserver::NotifyContentChange, observer.get(), _1).track(observer)); + SignalSliceChange.connect(LayerSourceBase::SignalSliceChangeType::slot_type(&IObserver::NotifySliceChange, observer.get(), _1, _2).track(observer)); + SignalLayerReady.connect(LayerSourceBase::SignalLayerReadyType::slot_type(&IObserver::NotifyLayerReady, observer.get(), _1, _2, _3, _4).track(observer)); } }
--- a/Framework/Layers/LayerSourceBase.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Layers/LayerSourceBase.h Mon Jul 02 12:32:02 2018 +0200 @@ -24,15 +24,16 @@ #include "ILayerSource.h" #include "../Toolbox/ObserversRegistry.h" #include <boost/signals2.hpp> +#include <boost/shared_ptr.hpp> namespace OrthancStone { class LayerSourceBase : public ILayerSource { private: - typedef ObserversRegistry<ILayerSource, IObserver> Observers; + //typedef ObserversRegistry<ILayerSource, IObserver> Observers; - Observers observers_; + //Observers observers_; protected: void NotifyGeometryReady(); @@ -43,12 +44,32 @@ void NotifySliceChange(const Slice& slice); - void NotifyLayerReady(ILayerRenderer* layer, + void NotifyLayerReady(boost::shared_ptr<ILayerRenderer> renderer, const CoordinateSystem3D& slice, bool isError); public: - virtual void Register(IObserver& observer); - boost::signals2::signal<void (const ILayerSource& source)> SignalGeometryReady; + virtual void Register(boost::shared_ptr<IObserver> observer); + + protected: + typedef boost::signals2::signal<void (const ILayerSource& source)> SignalGeometryReadyType; + typedef boost::signals2::signal<void (const ILayerSource& source)> SignalGeometryErrorType; + typedef boost::signals2::signal<void (const ILayerSource& source)> SignalContentChangeType; + typedef boost::signals2::signal<void (const ILayerSource& source, + const Slice& slice)> SignalSliceChangeType; + typedef boost::signals2::signal<void (boost::shared_ptr<ILayerRenderer> renderer, + const ILayerSource& source, + const CoordinateSystem3D& slice, + bool isError)> SignalLayerReadyType; + + SignalGeometryReadyType SignalGeometryReady; + SignalGeometryErrorType SignalGeometryError; + SignalContentChangeType SignalContentChange; + SignalSliceChangeType SignalSliceChange; + SignalLayerReadyType SignalLayerReady; + + + //boost::signals2::signal<void (const ILayerSource& source)> SignalGeometryError; + }; }
--- a/Framework/Layers/OrthancFrameLayerSource.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Layers/OrthancFrameLayerSource.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -55,7 +55,7 @@ SliceImageQuality quality) { bool isFull = (quality == SliceImageQuality_Full); - LayerSourceBase::NotifyLayerReady(FrameRenderer::CreateRenderer(image.release(), slice, isFull), + LayerSourceBase::NotifyLayerReady(boost::shared_ptr<ILayerRenderer>(FrameRenderer::CreateRenderer(image.release(), slice, isFull)), slice.GetGeometry(), false); } @@ -68,29 +68,33 @@ } - OrthancFrameLayerSource::OrthancFrameLayerSource(IWebService& orthanc) : - loader_(*this, orthanc), + OrthancFrameLayerSource::OrthancFrameLayerSource() : quality_(SliceImageQuality_Full) { } - + void OrthancFrameLayerSource::Init(IWebService& orthanc) { + // note: there must have been a shared_ptr created on this object before calling shared_from_this() + + loader_.reset(new OrthancSlicesLoader(shared_from_this(), orthanc)); + } + void OrthancFrameLayerSource::LoadSeries(const std::string& seriesId) { - loader_.ScheduleLoadSeries(seriesId); + loader_->ScheduleLoadSeries(loader_, seriesId); } void OrthancFrameLayerSource::LoadInstance(const std::string& instanceId) { - loader_.ScheduleLoadInstance(instanceId); + loader_->ScheduleLoadInstance(loader_, instanceId); } void OrthancFrameLayerSource::LoadFrame(const std::string& instanceId, unsigned int frame) { - loader_.ScheduleLoadFrame(instanceId, frame); + loader_->ScheduleLoadFrame(loader_, instanceId, frame); } @@ -98,10 +102,10 @@ const CoordinateSystem3D& viewportSlice) { size_t index; - if (loader_.IsGeometryReady() && - loader_.LookupSlice(index, viewportSlice)) + if (loader_->IsGeometryReady() && + loader_->LookupSlice(index, viewportSlice)) { - loader_.GetSlice(index).GetExtent(points); + loader_->GetSlice(index).GetExtent(points); return true; } else @@ -115,11 +119,11 @@ { size_t index; - if (loader_.IsGeometryReady()) + if (loader_->IsGeometryReady()) { - if (loader_.LookupSlice(index, viewportSlice)) + if (loader_->LookupSlice(index, viewportSlice)) { - loader_.ScheduleLoadSliceImage(index, quality_); + loader_->ScheduleLoadSliceImage(loader_, index, quality_); } else {
--- a/Framework/Layers/OrthancFrameLayerSource.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Layers/OrthancFrameLayerSource.h Mon Jul 02 12:32:02 2018 +0200 @@ -24,15 +24,18 @@ #include "LayerSourceBase.h" #include "../Toolbox/IWebService.h" #include "../Toolbox/OrthancSlicesLoader.h" +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> namespace OrthancStone { class OrthancFrameLayerSource : public LayerSourceBase, - private OrthancSlicesLoader::ICallback + public OrthancSlicesLoader::IObserver, + public boost::enable_shared_from_this<OrthancFrameLayerSource> { private: - OrthancSlicesLoader loader_; + boost::shared_ptr<OrthancSlicesLoader> loader_; SliceImageQuality quality_; virtual void NotifyGeometryReady(const OrthancSlicesLoader& loader); @@ -51,8 +54,11 @@ SliceImageQuality quality); public: - OrthancFrameLayerSource(IWebService& orthanc); + OrthancFrameLayerSource(); + void Init(IWebService& orthanc); + virtual ~OrthancFrameLayerSource() { + } void LoadSeries(const std::string& seriesId); void LoadInstance(const std::string& instanceId); @@ -67,12 +73,12 @@ size_t GetSliceCount() const { - return loader_.GetSliceCount(); + return loader_->GetSliceCount(); } const Slice& GetSlice(size_t slice) const { - return loader_.GetSlice(slice); + return loader_->GetSlice(slice); } virtual bool GetExtent(std::vector<Vector>& points,
--- a/Framework/Toolbox/IWebService.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Toolbox/IWebService.h Mon Jul 02 12:32:02 2018 +0200 @@ -24,23 +24,33 @@ #include <Core/IDynamicObject.h> #include <string> +#include <boost/shared_ptr.hpp> +#include <boost/signals2.hpp> namespace OrthancStone { class IWebService : public boost::noncopyable { public: - class ICallback : public boost::noncopyable + class IWebServiceObserver : public boost::noncopyable { public: - virtual ~ICallback() + typedef boost::signals2::signal<void (const std::string& uri, + Orthanc::IDynamicObject* payload)> SignalErrorType; + typedef boost::signals2::signal<void (const std::string& uri, + const void* answer, + size_t answerSize, + Orthanc::IDynamicObject* payload)> SignalSuccessType; + + public: + virtual ~IWebServiceObserver() { } - virtual void NotifyError(const std::string& uri, + virtual void OnRequestError(const std::string& uri, Orthanc::IDynamicObject* payload) = 0; - virtual void NotifySuccess(const std::string& uri, + virtual void OnRequestSuccess(const std::string& uri, const void* answer, size_t answerSize, Orthanc::IDynamicObject* payload) = 0; @@ -50,11 +60,13 @@ { } - virtual void ScheduleGetRequest(ICallback& callback, + virtual void ScheduleGetRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, Orthanc::IDynamicObject* payload) = 0; - virtual void SchedulePostRequest(ICallback& callback, + virtual void SchedulePostRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, const std::string& body, Orthanc::IDynamicObject* payload) = 0;
--- a/Framework/Toolbox/OrthancSlicesLoader.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Toolbox/OrthancSlicesLoader.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -169,18 +169,18 @@ }; - class OrthancSlicesLoader::WebCallback : public IWebService::ICallback - { - private: - OrthancSlicesLoader& that_; +// class OrthancSlicesLoader::WebCallback : public IWebService::ICallback +// { +// private: +// OrthancSlicesLoader& that_; - public: - WebCallback(OrthancSlicesLoader& that) : - that_(that) - { - } +// public: +// WebCallback(OrthancSlicesLoader& that) : +// that_(that) +// { +// } - virtual void NotifySuccess(const std::string& uri, + void OrthancSlicesLoader::OnRequestSuccess(const std::string& uri, const void* answer, size_t answerSize, Orthanc::IDynamicObject* payload) @@ -190,15 +190,15 @@ switch (operation->GetMode()) { case Mode_SeriesGeometry: - that_.ParseSeriesGeometry(answer, answerSize); + ParseSeriesGeometry(answer, answerSize); break; case Mode_InstanceGeometry: - that_.ParseInstanceGeometry(operation->GetInstanceId(), answer, answerSize); + ParseInstanceGeometry(operation->GetInstanceId(), answer, answerSize); break; case Mode_FrameGeometry: - that_.ParseFrameGeometry(operation->GetInstanceId(), + ParseFrameGeometry(operation->GetInstanceId(), operation->GetFrame(), answer, answerSize); break; @@ -206,13 +206,13 @@ switch (operation->GetQuality()) { case SliceImageQuality_Full: - that_.ParseSliceImagePng(*operation, answer, answerSize); + ParseSliceImagePng(*operation, answer, answerSize); break; case SliceImageQuality_Jpeg50: case SliceImageQuality_Jpeg90: case SliceImageQuality_Jpeg95: - that_.ParseSliceImageJpeg(*operation, answer, answerSize); + ParseSliceImageJpeg(*operation, answer, answerSize); break; default: @@ -222,7 +222,7 @@ break; case Mode_LoadRawImage: - that_.ParseSliceRawImage(*operation, answer, answerSize); + ParseSliceRawImage(*operation, answer, answerSize); break; default: @@ -230,7 +230,7 @@ } } - virtual void NotifyError(const std::string& uri, + void OrthancSlicesLoader::OnRequestError(const std::string& uri, Orthanc::IDynamicObject* payload) { std::auto_ptr<Operation> operation(dynamic_cast<Operation*>(payload)); @@ -240,12 +240,12 @@ { case Mode_FrameGeometry: case Mode_SeriesGeometry: - that_.userCallback_.NotifyGeometryError(that_); - that_.state_ = State_Error; + SignalGeometryError(*this); + state_ = State_Error; break; case Mode_LoadImage: - that_.userCallback_.NotifySliceImageError(that_, operation->GetSliceIndex(), + SignalSliceImageError(*this, operation->GetSliceIndex(), operation->GetSlice(), operation->GetQuality()); break; @@ -254,7 +254,7 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } } - }; +// }; @@ -267,16 +267,14 @@ } else { - userCallback_.NotifySliceImageReady - (*this, operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality()); + SignalSliceImageReady(*this, operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality()); } } void OrthancSlicesLoader::NotifySliceImageError(const Operation& operation) const { - userCallback_.NotifySliceImageError - (*this, operation.GetSliceIndex(), operation.GetSlice(), operation.GetQuality()); + SignalSliceImageError(*this, operation.GetSliceIndex(), operation.GetSlice(), operation.GetQuality()); } @@ -301,12 +299,12 @@ if (ok) { LOG(INFO) << "Loaded a series with " << slices_.GetSliceCount() << " slice(s)"; - userCallback_.NotifyGeometryReady(*this); + SignalGeometryReady(*this); } else { LOG(ERROR) << "This series is empty"; - userCallback_.NotifyGeometryError(*this); + SignalGeometryError(*this); } } @@ -318,7 +316,7 @@ if (!MessagingToolbox::ParseJson(series, answer, size) || series.type() != Json::objectValue) { - userCallback_.NotifyGeometryError(*this); + SignalGeometryError(*this); return; } @@ -365,7 +363,7 @@ if (!MessagingToolbox::ParseJson(tags, answer, size) || tags.type() != Json::objectValue) { - userCallback_.NotifyGeometryError(*this); + SignalGeometryError(*this); return; } @@ -392,7 +390,7 @@ else { LOG(WARNING) << "Skipping invalid multi-frame instance " << instanceId; - userCallback_.NotifyGeometryError(*this); + SignalGeometryError(*this); return; } } @@ -410,7 +408,7 @@ if (!MessagingToolbox::ParseJson(tags, answer, size) || tags.type() != Json::objectValue) { - userCallback_.NotifyGeometryError(*this); + SignalGeometryError(*this); return; } @@ -426,12 +424,12 @@ { LOG(INFO) << "Loaded instance " << instanceId; slices_.AddSlice(slice.release()); - userCallback_.NotifyGeometryReady(*this); + SignalGeometryReady(*this); } else { LOG(WARNING) << "Skipping invalid instance " << instanceId; - userCallback_.NotifyGeometryError(*this); + SignalGeometryError(*this); } } @@ -715,17 +713,22 @@ } - OrthancSlicesLoader::OrthancSlicesLoader(ICallback& callback, + OrthancSlicesLoader::OrthancSlicesLoader(boost::shared_ptr<OrthancSlicesLoader::IObserver> observer, IWebService& orthanc) : - webCallback_(new WebCallback(*this)), - userCallback_(callback), + //webCallback_(new WebCallback(*this)), +// userCallback_(callback), + observer_(observer), orthanc_(orthanc), state_(State_Initialization) { + SignalGeometryReady.connect(OrthancSlicesLoader::IObserver::SignalGeometryReadyType::slot_type(&OrthancSlicesLoader::IObserver::NotifyGeometryReady, observer.get(), _1).track(observer)); + SignalGeometryError.connect(OrthancSlicesLoader::IObserver::SignalGeometryErrorType::slot_type(&OrthancSlicesLoader::IObserver::NotifyGeometryError, observer.get(), _1).track(observer)); + SignalSliceImageReady.connect(OrthancSlicesLoader::IObserver::SignalSliceImageReadyType::slot_type(&OrthancSlicesLoader::IObserver::NotifySliceImageReady, observer.get(), _1, _2, _3, _4, _5).track(observer)); + SignalSliceImageError.connect(OrthancSlicesLoader::IObserver::SignalSliceImageErrorType::slot_type(&OrthancSlicesLoader::IObserver::NotifySliceImageError, observer.get(), _1, _2, _3, _4).track(observer)); } - void OrthancSlicesLoader::ScheduleLoadSeries(const std::string& seriesId) + void OrthancSlicesLoader::ScheduleLoadSeries(boost::shared_ptr<boost::noncopyable> tracker, const std::string& seriesId) { if (state_ != State_Initialization) { @@ -735,12 +738,12 @@ { state_ = State_LoadingGeometry; std::string uri = "/series/" + seriesId + "/instances-tags"; - orthanc_.ScheduleGetRequest(*webCallback_, uri, Operation::DownloadSeriesGeometry()); + orthanc_.ScheduleGetRequest(this, tracker, uri, Operation::DownloadSeriesGeometry()); } } - void OrthancSlicesLoader::ScheduleLoadInstance(const std::string& instanceId) + void OrthancSlicesLoader::ScheduleLoadInstance(boost::shared_ptr<boost::noncopyable> tracker, const std::string& instanceId) { if (state_ != State_Initialization) { @@ -754,12 +757,12 @@ // mandatory to read RT DOSE, but is too long to be returned by default std::string uri = "/instances/" + instanceId + "/tags?ignore-length=3004-000c"; orthanc_.ScheduleGetRequest - (*webCallback_, uri, Operation::DownloadInstanceGeometry(instanceId)); + (this, tracker, uri, Operation::DownloadInstanceGeometry(instanceId)); } } - void OrthancSlicesLoader::ScheduleLoadFrame(const std::string& instanceId, + void OrthancSlicesLoader::ScheduleLoadFrame(boost::shared_ptr<boost::noncopyable> tracker, const std::string& instanceId, unsigned int frame) { if (state_ != State_Initialization) @@ -771,7 +774,7 @@ state_ = State_LoadingGeometry; std::string uri = "/instances/" + instanceId + "/tags"; orthanc_.ScheduleGetRequest - (*webCallback_, uri, Operation::DownloadFrameGeometry(instanceId, frame)); + (this, tracker, uri, Operation::DownloadFrameGeometry(instanceId, frame)); } } @@ -816,7 +819,7 @@ } - void OrthancSlicesLoader::ScheduleSliceImagePng(const Slice& slice, + void OrthancSlicesLoader::ScheduleSliceImagePng(boost::shared_ptr<boost::noncopyable> tracker, const Slice& slice, size_t index) { std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + @@ -840,12 +843,12 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - orthanc_.ScheduleGetRequest(*webCallback_, uri, + orthanc_.ScheduleGetRequest(this, tracker, uri, Operation::DownloadSliceImage(index, slice, SliceImageQuality_Full)); } - void OrthancSlicesLoader::ScheduleSliceImageJpeg(const Slice& slice, + void OrthancSlicesLoader::ScheduleSliceImageJpeg(boost::shared_ptr<boost::noncopyable> tracker, const Slice& slice, size_t index, SliceImageQuality quality) { @@ -875,13 +878,13 @@ "-" + slice.GetOrthancInstanceId() + "_" + boost::lexical_cast<std::string>(slice.GetFrame())); - orthanc_.ScheduleGetRequest(*webCallback_, uri, + orthanc_.ScheduleGetRequest(this, tracker, uri, Operation::DownloadSliceImage(index, slice, quality)); } - void OrthancSlicesLoader::ScheduleLoadSliceImage(size_t index, + void OrthancSlicesLoader::ScheduleLoadSliceImage(boost::shared_ptr<boost::noncopyable> tracker, size_t index, SliceImageQuality quality) { if (state_ != State_GeometryReady) @@ -895,18 +898,18 @@ { if (quality == SliceImageQuality_Full) { - ScheduleSliceImagePng(slice, index); + ScheduleSliceImagePng(tracker, slice, index); } else { - ScheduleSliceImageJpeg(slice, index, quality); + ScheduleSliceImageJpeg(tracker, slice, index, quality); } } else { std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + boost::lexical_cast<std::string>(slice.GetFrame()) + "/raw.gz"); - orthanc_.ScheduleGetRequest(*webCallback_, uri, + orthanc_.ScheduleGetRequest(this, tracker, uri, Operation::DownloadSliceRawImage(index, slice)); } }
--- a/Framework/Toolbox/OrthancSlicesLoader.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Toolbox/OrthancSlicesLoader.h Mon Jul 02 12:32:02 2018 +0200 @@ -26,16 +26,31 @@ #include "../StoneEnumerations.h" #include <boost/shared_ptr.hpp> +#include <boost/signals2.hpp> namespace OrthancStone { - class OrthancSlicesLoader : public boost::noncopyable + class OrthancSlicesLoader : public IWebService::IWebServiceObserver { public: - class ICallback : public boost::noncopyable + class IObserver : public boost::noncopyable { public: - virtual ~ICallback() + typedef boost::signals2::signal<void (const OrthancSlicesLoader& loader)> SignalGeometryReadyType; + typedef boost::signals2::signal<void (const OrthancSlicesLoader& loader)> SignalGeometryErrorType; + typedef boost::signals2::signal<void (const OrthancSlicesLoader& loader, + unsigned int sliceIndex, + const Slice& slice, + std::auto_ptr<Orthanc::ImageAccessor>& image, + SliceImageQuality effectiveQuality)> SignalSliceImageReadyType; + typedef boost::signals2::signal<void (const OrthancSlicesLoader& loader, + unsigned int sliceIndex, + const Slice& slice, + SliceImageQuality quality)> SignalSliceImageErrorType; + + + public: + virtual ~IObserver() { } @@ -54,7 +69,13 @@ const Slice& slice, SliceImageQuality quality) = 0; }; - + + private: + IObserver::SignalGeometryReadyType SignalGeometryReady; + IObserver::SignalGeometryErrorType SignalGeometryError; + IObserver::SignalSliceImageReadyType SignalSliceImageReady; + IObserver::SignalSliceImageErrorType SignalSliceImageError; + private: enum State { @@ -74,11 +95,12 @@ }; class Operation; - class WebCallback; + //class WebCallback; - boost::shared_ptr<WebCallback> webCallback_; // This is a PImpl pattern + //boost::shared_ptr<WebCallback> webCallback_; // This is a PImpl pattern - ICallback& userCallback_; + //ICallback& userCallback_; + boost::shared_ptr<OrthancSlicesLoader::IObserver> observer_; IWebService& orthanc_; State state_; SlicesSorter slices_; @@ -112,24 +134,24 @@ const void* answer, size_t size); - void ScheduleSliceImagePng(const Slice& slice, + void ScheduleSliceImagePng(boost::shared_ptr<boost::noncopyable> tracker, const Slice& slice, size_t index); - void ScheduleSliceImageJpeg(const Slice& slice, + void ScheduleSliceImageJpeg(boost::shared_ptr<boost::noncopyable> tracker, const Slice& slice, size_t index, SliceImageQuality quality); void SortAndFinalizeSlices(); public: - OrthancSlicesLoader(ICallback& callback, + OrthancSlicesLoader(boost::shared_ptr<OrthancSlicesLoader::IObserver> observer, IWebService& orthanc); - void ScheduleLoadSeries(const std::string& seriesId); + void ScheduleLoadSeries(boost::shared_ptr<boost::noncopyable> tracker, const std::string& seriesId); - void ScheduleLoadInstance(const std::string& instanceId); + void ScheduleLoadInstance(boost::shared_ptr<boost::noncopyable> tracker, const std::string& instanceId); - void ScheduleLoadFrame(const std::string& instanceId, + void ScheduleLoadFrame(boost::shared_ptr<boost::noncopyable> tracker, const std::string& instanceId, unsigned int frame); bool IsGeometryReady() const; @@ -141,7 +163,17 @@ bool LookupSlice(size_t& index, const CoordinateSystem3D& plane) const; - void ScheduleLoadSliceImage(size_t index, + void ScheduleLoadSliceImage(boost::shared_ptr<boost::noncopyable> tracker, size_t index, SliceImageQuality requestedQuality); + + + void OnRequestSuccess(const std::string& uri, + const void* answer, + size_t answerSize, + Orthanc::IDynamicObject* payload); + + void OnRequestError(const std::string& uri, + Orthanc::IDynamicObject* payload); + }; }
--- a/Framework/Volumes/StructureSetLoader.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Volumes/StructureSetLoader.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -61,14 +61,14 @@ }; - void StructureSetLoader::NotifyError(const std::string& uri, + void StructureSetLoader::OnRequestError(const std::string& uri, Orthanc::IDynamicObject* payload) { // TODO } - void StructureSetLoader::NotifySuccess(const std::string& uri, + void StructureSetLoader::OnRequestSuccess(const std::string& uri, const void* answer, size_t answerSize, Orthanc::IDynamicObject* payload)
--- a/Framework/Volumes/StructureSetLoader.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Volumes/StructureSetLoader.h Mon Jul 02 12:32:02 2018 +0200 @@ -29,15 +29,15 @@ { class StructureSetLoader : public VolumeLoaderBase, - private IWebService::ICallback + private IWebService::IWebServiceObserver { private: class Operation; - virtual void NotifyError(const std::string& uri, + virtual void OnRequestError(const std::string& uri, Orthanc::IDynamicObject* payload); - virtual void NotifySuccess(const std::string& uri, + virtual void OnRequestSuccess(const std::string& uri, const void* answer, size_t answerSize, Orthanc::IDynamicObject* payload);
--- a/Framework/Widgets/LayerWidget.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Widgets/LayerWidget.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -36,7 +36,7 @@ CoordinateSystem3D slice_; double thickness_; size_t countMissing_; - std::vector<ILayerRenderer*> renderers_; + std::vector<boost::shared_ptr<ILayerRenderer>> renderers_; void DeleteLayer(size_t index) { @@ -47,11 +47,10 @@ assert(countMissing_ <= renderers_.size()); - if (renderers_[index] != NULL) + if (renderers_[index].get() != NULL) { assert(countMissing_ < renderers_.size()); - delete renderers_[index]; - renderers_[index] = NULL; + renderers_[index].reset(); countMissing_++; } } @@ -63,7 +62,7 @@ slice_(slice), thickness_(thickness), countMissing_(countLayers), - renderers_(countLayers, NULL) + renderers_(countLayers) { if (thickness <= 0) { @@ -80,9 +79,9 @@ } void SetLayer(size_t index, - ILayerRenderer* renderer) // Takes ownership + boost::shared_ptr<ILayerRenderer> renderer) { - if (renderer == NULL) + if (renderer.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } @@ -100,7 +99,7 @@ bool HasRenderer(size_t index) { - return renderers_[index] != NULL; + return renderers_[index].get() != NULL; } bool IsComplete() const @@ -122,7 +121,7 @@ for (size_t i = 0; i < renderers_.size(); i++) { - if (renderers_[i] != NULL) + if (renderers_[i].get() != NULL) { const CoordinateSystem3D& frameSlice = renderers_[i]->GetLayerSlice(); @@ -161,7 +160,7 @@ cairo_restore(cr); } - if (renderers_[i] != NULL && + if (renderers_[i].get() != NULL && !renderers_[i]->IsFullQuality()) { fullQuality = false; @@ -196,7 +195,7 @@ void SetLayerStyle(size_t index, const RenderStyle& style) { - if (renderers_[index] != NULL) + if (renderers_[index].get() != NULL) { renderers_[index]->SetLayerStyle(style); } @@ -245,7 +244,7 @@ { index = found->second; assert(index < layers_.size() && - layers_[index] == &layer); + layers_[index].get() == &layer); return true; } } @@ -317,14 +316,12 @@ void LayerWidget::UpdateLayer(size_t index, - ILayerRenderer* renderer, + boost::shared_ptr<ILayerRenderer> renderer, const CoordinateSystem3D& slice) { LOG(INFO) << "Updating layer " << index; - std::auto_ptr<ILayerRenderer> tmp(renderer); - - if (renderer == NULL) + if (renderer.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } @@ -340,13 +337,13 @@ if (currentScene_.get() != NULL && currentScene_->ContainsPlane(slice)) { - currentScene_->SetLayer(index, tmp.release()); + currentScene_->SetLayer(index, renderer); NotifyChange(); } else if (pendingScene_.get() != NULL && pendingScene_->ContainsPlane(slice)) { - pendingScene_->SetLayer(index, tmp.release()); + pendingScene_->SetLayer(index, renderer); if (currentScene_.get() == NULL || !currentScene_->IsComplete() || @@ -370,14 +367,14 @@ { for (size_t i = 0; i < layers_.size(); i++) { - delete layers_[i]; + layers_[i].reset(); } } - size_t LayerWidget::AddLayer(ILayerSource* layer) // Takes ownership + size_t LayerWidget::AddLayer(boost::shared_ptr<ILayerSource> layer) { - if (layer == NULL) + if (layer.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } @@ -385,19 +382,19 @@ size_t index = layers_.size(); layers_.push_back(layer); styles_.push_back(RenderStyle()); - layersIndex_[layer] = index; + layersIndex_[layer.get()] = index; ResetPendingScene(); - layer->Register(*this); + layer->Register(reinterpret_cast<boost::enable_shared_from_this<ILayerSource::IObserver>&>(*this).shared_from_this()); ResetChangedLayers(); return index; } - void LayerWidget::ReplaceLayer(size_t index, ILayerSource* layer) // Takes ownership + void LayerWidget::ReplaceLayer(size_t index, boost::shared_ptr<ILayerSource> layer) { - if (layer == NULL) + if (layer.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } @@ -407,12 +404,11 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - delete layers_[index]; - layers_[index] = layer; - layersIndex_[layer] = index; + layers_[index]= layer; + layersIndex_[layer.get()] = index; ResetPendingScene(); - layer->Register(*this); + layer->Register(shared_from_this()); InvalidateLayer(index); } @@ -549,7 +545,7 @@ } - void LayerWidget::NotifyLayerReady(std::auto_ptr<ILayerRenderer>& renderer, + void LayerWidget::NotifyLayerReady(boost::shared_ptr<ILayerRenderer> renderer, const ILayerSource& source, const CoordinateSystem3D& slice, bool isError) @@ -566,9 +562,10 @@ LOG(INFO) << "Renderer ready for layer " << index; } - if (renderer.get() != NULL) + if (renderer) { - UpdateLayer(index, renderer.release(), slice); + UpdateLayer(index, renderer, slice); + //delete renderer; // TODO: find a better way to handle lifecycle ! } else if (isError) {
--- a/Framework/Widgets/LayerWidget.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/Widgets/LayerWidget.h Mon Jul 02 12:32:02 2018 +0200 @@ -24,6 +24,7 @@ #include "WorldSceneWidget.h" #include "../Layers/ILayerSource.h" #include "../Toolbox/Extent2D.h" +#include <boost/enable_shared_from_this.hpp> #include <map> @@ -31,7 +32,10 @@ { class LayerWidget : public WorldSceneWidget, - private ILayerSource::IObserver + public ILayerSource::IObserver, + public boost::enable_shared_from_this<ILayerSource::IObserver> + //public boost::enable_shared_from_this<LayerWidget> + { private: class Scene; @@ -40,7 +44,7 @@ bool started_; LayersIndex layersIndex_; - std::vector<ILayerSource*> layers_; + std::vector<boost::shared_ptr<ILayerSource>> layers_; std::vector<RenderStyle> styles_; CoordinateSystem3D slice_; std::auto_ptr<Scene> currentScene_; @@ -62,7 +66,7 @@ virtual void NotifySliceChange(const ILayerSource& source, const Slice& slice); - virtual void NotifyLayerReady(std::auto_ptr<ILayerRenderer>& renderer, + virtual void NotifyLayerReady(boost::shared_ptr<ILayerRenderer> renderer, const ILayerSource& source, const CoordinateSystem3D& slice, bool isError); @@ -79,7 +83,7 @@ void ResetPendingScene(); void UpdateLayer(size_t index, - ILayerRenderer* renderer, + boost::shared_ptr<ILayerRenderer> renderer, const CoordinateSystem3D& slice); void InvalidateAllLayers(); @@ -91,9 +95,9 @@ virtual ~LayerWidget(); - size_t AddLayer(ILayerSource* layer); // Takes ownership + size_t AddLayer(boost::shared_ptr<ILayerSource> layer); - void ReplaceLayer(size_t layerIndex, ILayerSource* layer); // Takes ownership + void ReplaceLayer(size_t layerIndex, boost::shared_ptr<ILayerSource> layer); // Takes ownership size_t GetLayerCount() const {
--- a/Framework/dev.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Framework/dev.h Mon Jul 02 12:32:02 2018 +0200 @@ -43,10 +43,10 @@ // TODO: Handle errors while loading class OrthancVolumeImage : public SlicedVolumeBase, - private OrthancSlicesLoader::ICallback + public OrthancSlicesLoader::IObserver { private: - OrthancSlicesLoader loader_; + boost::shared_ptr<OrthancSlicesLoader> loader_; std::auto_ptr<ImageBuffer3D> image_; std::auto_ptr<DownloadStack> downloadStack_; bool computeRange_; @@ -59,7 +59,7 @@ unsigned int slice; if (downloadStack_->Pop(slice)) { - loader_.ScheduleLoadSliceImage(slice, SliceImageQuality_Jpeg90); + loader_->ScheduleLoadSliceImage(loader_, slice, SliceImageQuality_Jpeg90); } } @@ -217,36 +217,36 @@ public: OrthancVolumeImage(IWebService& orthanc, bool computeRange) : - loader_(*this, orthanc), computeRange_(computeRange), pendingSlices_(0) { + loader_.reset(new OrthancSlicesLoader(boost::shared_ptr<OrthancSlicesLoader::IObserver>(this), orthanc)); } void ScheduleLoadSeries(const std::string& seriesId) { - loader_.ScheduleLoadSeries(seriesId); + loader_->ScheduleLoadSeries(loader_, seriesId); } void ScheduleLoadInstance(const std::string& instanceId) { - loader_.ScheduleLoadInstance(instanceId); + loader_->ScheduleLoadInstance(loader_, instanceId); } void ScheduleLoadFrame(const std::string& instanceId, unsigned int frame) { - loader_.ScheduleLoadFrame(instanceId, frame); + loader_->ScheduleLoadFrame(loader_, instanceId, frame); } virtual size_t GetSliceCount() const { - return loader_.GetSliceCount(); + return loader_->GetSliceCount(); } virtual const Slice& GetSlice(size_t index) const { - return loader_.GetSlice(index); + return loader_->GetSlice(index); } ImageBuffer3D& GetImage() const @@ -629,8 +629,8 @@ } std::auto_ptr<Slice> slice(geometry.GetSlice(closest)); - LayerSourceBase::NotifyLayerReady( - FrameRenderer::CreateRenderer(frame.release(), *slice, isFullQuality), + LayerSourceBase::NotifyLayerReady(boost::shared_ptr<ILayerRenderer>( + FrameRenderer::CreateRenderer(frame.release(), *slice, isFullQuality)), //new SliceOutlineRenderer(slice), slice->GetGeometry(), false); return; @@ -855,7 +855,7 @@ extent.GetX1(), extent.GetY1(), extent.GetX2(), extent.GetY2())) { - NotifyLayerReady(new LineLayerRenderer(x1, y1, x2, y2, slice), reference.GetGeometry(), false); + NotifyLayerReady(boost::shared_ptr<ILayerRenderer>(new LineLayerRenderer(x1, y1, x2, y2, slice)), reference.GetGeometry(), false); } else {
--- a/Platforms/Generic/OracleWebService.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Generic/OracleWebService.h Mon Jul 02 12:32:02 2018 +0200 @@ -42,20 +42,22 @@ { } - virtual void ScheduleGetRequest(ICallback& callback, + virtual void ScheduleGetRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, Orthanc::IDynamicObject* payload) { - oracle_.Submit(new WebServiceGetCommand(callback, parameters_, uri, payload)); + oracle_.Submit(new WebServiceGetCommand(observer, tracker, parameters_, uri, payload)); } - virtual void SchedulePostRequest(ICallback& callback, + virtual void SchedulePostRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, const std::string& body, Orthanc::IDynamicObject* payload) { - oracle_.Submit(new WebServicePostCommand(callback, parameters_, uri, body, payload)); + oracle_.Submit(new WebServicePostCommand(observer, tracker, parameters_, uri, body, payload)); } void Start()
--- a/Platforms/Generic/WebServiceGetCommand.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Generic/WebServiceGetCommand.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -25,16 +25,18 @@ namespace OrthancStone { - WebServiceGetCommand::WebServiceGetCommand(IWebService::ICallback& callback, - const Orthanc::WebServiceParameters& parameters, + WebServiceGetCommand::WebServiceGetCommand(IWebService::IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker,const Orthanc::WebServiceParameters& parameters, const std::string& uri, Orthanc::IDynamicObject* payload /* takes ownership */) : - callback_(callback), + observer_(observer), parameters_(parameters), uri_(uri), payload_(payload) { - //SignalSuccess.connect(boost::bind(&IWebService::ICallback::NotifySuccess, callback, _1, _2, _3, _4)); + // connect the signals and track the deletion of the observer + SignalSuccess.connect(IWebService::IWebServiceObserver::SignalSuccessType::slot_type(&IWebService::IWebServiceObserver::OnRequestSuccess, observer_, _1, _2, _3, _4).track(tracker)); + SignalError.connect(IWebService::IWebServiceObserver::SignalErrorType::slot_type(&IWebService::IWebServiceObserver::OnRequestError, observer_, _1, _2).track(tracker)); } @@ -52,11 +54,10 @@ if (success_) { SignalSuccess(uri_, answer_.c_str(), answer_.size(), payload_.release()); - //callback_.NotifySuccess(uri_, answer_.c_str(), answer_.size(), payload_.release()); } else { - callback_.NotifyError(uri_, payload_.release()); + SignalError(uri_, payload_.release()); } } }
--- a/Platforms/Generic/WebServiceGetCommand.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Generic/WebServiceGetCommand.h Mon Jul 02 12:32:02 2018 +0200 @@ -35,7 +35,7 @@ class WebServiceGetCommand : public IOracleCommand { private: - IWebService::ICallback& callback_; + IWebService::IWebServiceObserver* observer_; Orthanc::WebServiceParameters parameters_; std::string uri_; std::auto_ptr<Orthanc::IDynamicObject> payload_; @@ -43,7 +43,8 @@ std::string answer_; public: - WebServiceGetCommand(IWebService::ICallback& callback, + WebServiceGetCommand(IWebService::IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const Orthanc::WebServiceParameters& parameters, const std::string& uri, Orthanc::IDynamicObject* payload /* takes ownership */); @@ -52,10 +53,10 @@ virtual void Commit(); - boost::signals2::signal<void (const std::string& uri, - const void* answer, - size_t answerSize, - Orthanc::IDynamicObject* payload)> SignalSuccess; + private: + + IWebService::IWebServiceObserver::SignalSuccessType SignalSuccess; + IWebService::IWebServiceObserver::SignalErrorType SignalError; }; }
--- a/Platforms/Generic/WebServicePostCommand.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Generic/WebServicePostCommand.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -25,17 +25,21 @@ namespace OrthancStone { - WebServicePostCommand::WebServicePostCommand(IWebService::ICallback& callback, + WebServicePostCommand::WebServicePostCommand(IWebService::IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const Orthanc::WebServiceParameters& parameters, const std::string& uri, const std::string& body, Orthanc::IDynamicObject* payload /* takes ownership */) : - callback_(callback), + observer_(observer), parameters_(parameters), uri_(uri), body_(body), payload_(payload) { + // connect the signals and track the deletion of the observer + SignalSuccess.connect(IWebService::IWebServiceObserver::SignalSuccessType::slot_type(&IWebService::IWebServiceObserver::OnRequestSuccess, observer_, _1, _2, _3, _4).track(tracker)); + SignalError.connect(IWebService::IWebServiceObserver::SignalErrorType::slot_type(&IWebService::IWebServiceObserver::OnRequestError, observer_, _1, _2).track(tracker)); } void WebServicePostCommand::Execute() @@ -51,11 +55,11 @@ { if (success_) { - callback_.NotifySuccess(uri_, answer_.c_str(), answer_.size(), payload_.release()); + SignalSuccess(uri_, answer_.c_str(), answer_.size(), payload_.release()); } else { - callback_.NotifyError(uri_, payload_.release()); + SignalError(uri_, payload_.release()); } } }
--- a/Platforms/Generic/WebServicePostCommand.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Generic/WebServicePostCommand.h Mon Jul 02 12:32:02 2018 +0200 @@ -34,7 +34,7 @@ class WebServicePostCommand : public IOracleCommand { private: - IWebService::ICallback& callback_; + IWebService::IWebServiceObserver* observer_; Orthanc::WebServiceParameters parameters_; std::string uri_; std::string body_; @@ -43,7 +43,8 @@ std::string answer_; public: - WebServicePostCommand(IWebService::ICallback& callback, + WebServicePostCommand(IWebService::IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const Orthanc::WebServiceParameters& parameters, const std::string& uri, const std::string& body, @@ -52,5 +53,10 @@ virtual void Execute(); virtual void Commit(); + + private: + + IWebService::IWebServiceObserver::SignalSuccessType SignalSuccess; + IWebService::IWebServiceObserver::SignalErrorType SignalError; }; }
--- a/Platforms/Wasm/WasmWebService.cpp Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Wasm/WasmWebService.cpp Mon Jul 02 12:32:02 2018 +0200 @@ -16,35 +16,35 @@ size_t bodySize, void* payload); - void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifyError(void* callback, + void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifyError(void* observer, const char* uri, void* payload) { - if (callback == NULL) + if (observer == NULL) { throw; } else { - reinterpret_cast<OrthancStone::IWebService::ICallback*>(callback)-> - NotifyError(uri, reinterpret_cast<Orthanc::IDynamicObject*>(payload)); + reinterpret_cast<OrthancStone::IWebService::IWebServiceObserver*>(observer)-> + OnRequestError(uri, reinterpret_cast<Orthanc::IDynamicObject*>(payload)); } } - void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifySuccess(void* callback, + void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifySuccess(void* observer, const char* uri, const void* body, size_t bodySize, void* payload) { - if (callback == NULL) + if (observer == NULL) { throw; } else { - reinterpret_cast<OrthancStone::IWebService::ICallback*>(callback)-> - NotifySuccess(uri, body, bodySize, reinterpret_cast<Orthanc::IDynamicObject*>(payload)); + reinterpret_cast<OrthancStone::IWebService::IWebServiceObserver*>(observer)-> + OnRequestSuccess(uri, body, bodySize, reinterpret_cast<Orthanc::IDynamicObject*>(payload)); } } @@ -75,21 +75,23 @@ } } - void WasmWebService::ScheduleGetRequest(ICallback& callback, + void WasmWebService::ScheduleGetRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, Orthanc::IDynamicObject* payload) { std::string url = base_ + uri; - WasmWebService_ScheduleGetRequest(&callback, url.c_str(), payload); + WasmWebService_ScheduleGetRequest(observer, url.c_str(), payload); } - void WasmWebService::SchedulePostRequest(ICallback& callback, + void WasmWebService::SchedulePostRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, const std::string& body, Orthanc::IDynamicObject* payload) { std::string url = base_ + uri; - WasmWebService_SchedulePostRequest(&callback, url.c_str(), + WasmWebService_SchedulePostRequest(observer, url.c_str(), body.c_str(), body.size(), payload); } }
--- a/Platforms/Wasm/WasmWebService.h Tue Jun 26 13:55:17 2018 +0200 +++ b/Platforms/Wasm/WasmWebService.h Mon Jul 02 12:32:02 2018 +0200 @@ -24,11 +24,13 @@ void SetBaseUrl(const std::string base); - virtual void ScheduleGetRequest(ICallback& callback, + virtual void ScheduleGetRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, Orthanc::IDynamicObject* payload); - virtual void SchedulePostRequest(ICallback& callback, + virtual void SchedulePostRequest(IWebServiceObserver* observer, + boost::shared_ptr<boost::noncopyable> tracker, const std::string& uri, const std::string& body, Orthanc::IDynamicObject* payload);
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Tue Jun 26 13:55:17 2018 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Mon Jul 02 12:32:02 2018 +0200 @@ -175,6 +175,7 @@ ${ORTHANC_STONE_ROOT}/Framework/Layers/DicomStructureSetRendererFactory.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/FrameRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/GrayscaleFrameRenderer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Layers/ILayerSource.h ${ORTHANC_STONE_ROOT}/Framework/Layers/LayerSourceBase.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/LineLayerRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/LineMeasureTracker.cpp @@ -206,7 +207,7 @@ ${ORTHANC_STONE_ROOT}/Framework/Viewport/WidgetViewport.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/ImageBuffer3D.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/SlicedVolumeBase.cpp - ${ORTHANC_STONE_ROOT}/Framework/Volumes/StructureSetLoader.cpp +# ${ORTHANC_STONE_ROOT}/Framework/Volumes/StructureSetLoader.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/VolumeLoaderBase.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/VolumeReslicer.cpp ${ORTHANC_STONE_ROOT}/Framework/Widgets/CairoWidget.cpp