Mercurial > hg > orthanc-stone
changeset 1089:998d9e4402e0 broker
integration mainline->broker
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Oct 2019 11:04:47 +0200 |
parents | fe723ea10d98 (diff) b8521df3944a (current diff) |
children | 71c2dc28a85b |
files | Applications/Samples/SingleFrameEditorApplication.h Resources/CMake/OrthancStoneConfiguration.cmake |
diffstat | 132 files changed, 1127 insertions(+), 1540 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/Generic/NativeStoneApplicationContext.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Generic/NativeStoneApplicationContext.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -24,10 +24,10 @@ namespace OrthancStone { - Deprecated::IWidget& NativeStoneApplicationContext::GlobalMutexLocker::SetCentralWidget(Deprecated::IWidget* widget) + void NativeStoneApplicationContext::GlobalMutexLocker::SetCentralWidget( + boost::shared_ptr<Deprecated::IWidget> widget) { that_.centralViewport_.SetCentralWidget(widget); - return *widget; } @@ -45,9 +45,7 @@ } - NativeStoneApplicationContext::NativeStoneApplicationContext(MessageBroker& broker) : - StoneApplicationContext(broker), - centralViewport_(broker), + NativeStoneApplicationContext::NativeStoneApplicationContext() : stopped_(true), updateDelayInMs_(100) // By default, 100ms between each refresh of the content {
--- a/Applications/Generic/NativeStoneApplicationContext.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Generic/NativeStoneApplicationContext.h Wed Oct 23 11:04:47 2019 +0200 @@ -56,7 +56,7 @@ { } - Deprecated::IWidget& SetCentralWidget(Deprecated::IWidget* widget); // Takes ownership + void SetCentralWidget(boost::shared_ptr<Deprecated::IWidget> widget); Deprecated::IViewport& GetCentralViewport() { @@ -67,14 +67,9 @@ { that_.updateDelayInMs_ = delayInMs; } - - MessageBroker& GetMessageBroker() - { - return that_.GetMessageBroker(); - } }; - NativeStoneApplicationContext(MessageBroker& broker); + NativeStoneApplicationContext(); void Start();
--- a/Applications/Generic/NativeStoneApplicationRunner.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Generic/NativeStoneApplicationRunner.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -97,7 +97,7 @@ DeclareCommandLineOptions(options); // application specific options - application_.DeclareStartupOptions(options); + application_->DeclareStartupOptions(options); boost::program_options::variables_map parameters; bool error = false; @@ -197,7 +197,7 @@ LogStatusBar statusBar; - NativeStoneApplicationContext context(broker_); + NativeStoneApplicationContext context; { // use multiple threads to execute asynchronous tasks like @@ -206,24 +206,23 @@ oracle.Start(); { - Deprecated::OracleWebService webService( - broker_, oracle, webServiceParameters, context); - + boost::shared_ptr<Deprecated::OracleWebService> webService + (new Deprecated::OracleWebService(oracle, webServiceParameters, context)); context.SetWebService(webService); context.SetOrthancBaseUrl(webServiceParameters.GetUrl()); - Deprecated::OracleDelayedCallExecutor delayedExecutor(broker_, oracle, context); + Deprecated::OracleDelayedCallExecutor delayedExecutor(oracle, context); context.SetDelayedCallExecutor(delayedExecutor); - application_.Initialize(&context, statusBar, parameters); + application_->Initialize(&context, statusBar, parameters); { NativeStoneApplicationContext::GlobalMutexLocker locker(context); - locker.SetCentralWidget(application_.GetCentralWidget()); + locker.SetCentralWidget(application_->GetCentralWidget()); locker.GetCentralViewport().SetStatusBar(statusBar); } - std::string title = application_.GetTitle(); + std::string title = application_->GetTitle(); if (title.empty()) { title = "Stone of Orthanc"; @@ -244,7 +243,7 @@ } LOG(WARNING) << "The application is stopping"; - application_.Finalize(); + application_->Finalize(); } catch (Orthanc::OrthancException& e) {
--- a/Applications/Generic/NativeStoneApplicationRunner.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Generic/NativeStoneApplicationRunner.h Wed Oct 23 11:04:47 2019 +0200 @@ -34,14 +34,11 @@ class NativeStoneApplicationRunner { protected: - MessageBroker& broker_; - IStoneApplication& application_; + boost::shared_ptr<IStoneApplication> application_; + public: - - NativeStoneApplicationRunner(MessageBroker& broker, - IStoneApplication& application) - : broker_(broker), - application_(application) + NativeStoneApplicationRunner(boost::shared_ptr<IStoneApplication> application) + : application_(application) { } int Execute(int argc,
--- a/Applications/IStoneApplication.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/IStoneApplication.h Wed Oct 23 11:04:47 2019 +0200 @@ -64,7 +64,11 @@ #endif virtual std::string GetTitle() const = 0; - virtual Deprecated::IWidget* GetCentralWidget() = 0; + + virtual void SetCentralWidget(boost::shared_ptr<Deprecated::IWidget> widget) = 0; + + virtual boost::shared_ptr<Deprecated::IWidget> GetCentralWidget() = 0; + virtual void Finalize() = 0; }; }
--- a/Applications/Samples/SampleApplicationBase.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Samples/SampleApplicationBase.h Wed Oct 23 11:04:47 2019 +0200 @@ -40,9 +40,8 @@ { class SampleApplicationBase : public IStoneApplication { - protected: - // ownership is transferred to the application context - Deprecated::WorldSceneWidget* mainWidget_; + private: + boost::shared_ptr<Deprecated::IWidget> mainWidget_; public: virtual void Initialize(StoneApplicationContext* context, @@ -64,7 +63,16 @@ virtual void Finalize() ORTHANC_OVERRIDE {} - virtual Deprecated::IWidget* GetCentralWidget() ORTHANC_OVERRIDE {return mainWidget_;} + + virtual void SetCentralWidget(boost::shared_ptr<Deprecated::IWidget> widget) ORTHANC_OVERRIDE + { + mainWidget_ = widget; + } + + virtual boost::shared_ptr<Deprecated::IWidget> GetCentralWidget() ORTHANC_OVERRIDE + { + return mainWidget_; + } #if ORTHANC_ENABLE_WASM==1 // default implementations for a single canvas named "canvas" in the HTML and an emtpy WasmApplicationAdapter
--- a/Applications/Samples/SampleMainNative.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Samples/SampleMainNative.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,19 +26,18 @@ #if ORTHANC_ENABLE_QT==1 #include "Qt/SampleQtApplicationRunner.h" #endif -#include "../../Framework/Messages/MessageBroker.h" int main(int argc, char* argv[]) { - OrthancStone::MessageBroker broker; - SampleApplication sampleStoneApplication(broker); + boost::shared_ptr<SampleApplication> sampleStoneApplication(new SampleApplication); #if ORTHANC_ENABLE_SDL==1 - OrthancStone::SdlStoneApplicationRunner sdlApplicationRunner(broker, sampleStoneApplication); + OrthancStone::SdlStoneApplicationRunner sdlApplicationRunner(sampleStoneApplication); return sdlApplicationRunner.Execute(argc, argv); #endif + #if ORTHANC_ENABLE_QT==1 - OrthancStone::Samples::SampleQtApplicationRunner qtAppRunner(broker, sampleStoneApplication); + OrthancStone::Samples::SampleQtApplicationRunner qtAppRunner(sampleStoneApplication); return qtAppRunner.Execute(argc, argv); #endif }
--- a/Applications/Samples/SimpleViewerApplicationSingleFile.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Samples/SimpleViewerApplicationSingleFile.h Wed Oct 23 11:04:47 2019 +0200 @@ -44,7 +44,7 @@ { class SimpleViewerApplication : public SampleSingleCanvasWithButtonsApplicationBase, - public IObserver + public ObserverBase<SimpleViewerApplication> { private: class ThumbnailInteractor : public Deprecated::IWorldSceneInteractor @@ -199,8 +199,8 @@ SimpleViewerApplication& viewerApplication_; public: - SimpleViewerApplicationAdapter(MessageBroker& broker, SimpleViewerApplication& application) - : WasmPlatformApplicationAdapter(broker, application), + SimpleViewerApplicationAdapter(SimpleViewerApplication& application) + : WasmPlatformApplicationAdapter(application), viewerApplication_(application) { } @@ -243,7 +243,7 @@ std::auto_ptr<ThumbnailInteractor> thumbnailInteractor_; Deprecated::LayoutWidget* mainLayout_; Deprecated::LayoutWidget* thumbnailsLayout_; - std::vector<Deprecated::SliceViewerWidget*> thumbnails_; + std::vector<boost::shared_ptr<Deprecated::SliceViewerWidget> > thumbnails_; std::map<std::string, std::vector<std::string> > instancesIdsPerSeriesId_; std::map<std::string, Json::Value> seriesTags_; @@ -258,8 +258,7 @@ Orthanc::Font font_; public: - SimpleViewerApplication(MessageBroker& broker) : - IObserver(broker), + SimpleViewerApplication() : currentTool_(Tool_LineMeasure), mainLayout_(NULL), currentInstanceIndex_(0), @@ -297,26 +296,28 @@ mainLayout_->SetBackgroundColor(0, 0, 0); mainLayout_->SetHorizontal(); - thumbnailsLayout_ = new Deprecated::LayoutWidget("thumbnail-layout"); + boost::shared_ptr<Deprecated::LayoutWidget> thumbnailsLayout_(new Deprecated::LayoutWidget("thumbnail-layout")); thumbnailsLayout_->SetPadding(10); thumbnailsLayout_->SetBackgroundCleared(true); thumbnailsLayout_->SetBackgroundColor(50, 50, 50); thumbnailsLayout_->SetVertical(); - mainWidget_ = new Deprecated::SliceViewerWidget(GetBroker(), "main-viewport"); + boost::shared_ptr<Deprecated::SliceViewerWidget> widget + (new Deprecated::SliceViewerWidget("main-viewport")); + SetCentralWidget(widget); //mainWidget_->RegisterObserver(*this); // hierarchy mainLayout_->AddWidget(thumbnailsLayout_); - mainLayout_->AddWidget(mainWidget_); + mainLayout_->AddWidget(widget); // sources - smartLoader_.reset(new Deprecated::SmartLoader(GetBroker(), context->GetOrthancApiClient())); + smartLoader_.reset(new Deprecated::SmartLoader(context->GetOrthancApiClient())); smartLoader_->SetImageQuality(Deprecated::SliceImageQuality_FullPam); mainLayout_->SetTransmitMouseOver(true); mainWidgetInteractor_.reset(new MainWidgetInteractor(*this)); - mainWidget_->SetInteractor(*mainWidgetInteractor_); + widget->SetInteractor(*mainWidgetInteractor_); thumbnailInteractor_.reset(new ThumbnailInteractor(*this)); } @@ -327,10 +328,10 @@ if (parameters.count("studyId") < 1) { LOG(WARNING) << "The study ID is missing, will take the first studyId found in Orthanc"; - context->GetOrthancApiClient().GetJsonAsync( + context->GetOrthancApiClient()->GetJsonAsync( "/studies", new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage> - (*this, &SimpleViewerApplication::OnStudyListReceived)); + (GetSharedObserver(), &SimpleViewerApplication::OnStudyListReceived)); } else { @@ -357,10 +358,10 @@ { for (size_t i=0; i < response["Series"].size(); i++) { - context_->GetOrthancApiClient().GetJsonAsync( + context_->GetOrthancApiClient()->GetJsonAsync( "/series/" + response["Series"][(int)i].asString(), new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage> - (*this, &SimpleViewerApplication::OnSeriesReceived)); + (GetSharedObserver(), &SimpleViewerApplication::OnSeriesReceived)); } } } @@ -387,7 +388,7 @@ LoadThumbnailForSeries(seriesId, instancesIdsPerSeriesId_[seriesId][0]); // if this is the first thumbnail loaded, load the first instance in the mainWidget - Deprecated::SliceViewerWidget& widget = *dynamic_cast<Deprecated::SliceViewerWidget*>(mainWidget_); + Deprecated::SliceViewerWidget& widget = dynamic_cast<Deprecated::SliceViewerWidget&>(*GetCentralWidget()); if (widget.GetLayerCount() == 0) { smartLoader_->SetFrameInWidget(widget, 0, instancesIdsPerSeriesId_[seriesId][0], 0); @@ -398,10 +399,10 @@ void LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId) { LOG(INFO) << "Loading thumbnail for series " << seriesId; - Deprecated::SliceViewerWidget* thumbnailWidget = new Deprecated::SliceViewerWidget(GetBroker(), "thumbnail-series-" + seriesId); + boost::shared_ptr<Deprecated::SliceViewerWidget> thumbnailWidget(new Deprecated::SliceViewerWidget("thumbnail-series-" + seriesId)); thumbnails_.push_back(thumbnailWidget); thumbnailsLayout_->AddWidget(thumbnailWidget); - thumbnailWidget->RegisterObserverCallback(new Callable<SimpleViewerApplication, Deprecated::SliceViewerWidget::GeometryChangedMessage>(*this, &SimpleViewerApplication::OnWidgetGeometryChanged)); + Register<Deprecated::SliceViewerWidget::GeometryChangedMessage>(*thumbnailWidget, &SimpleViewerApplication::OnWidgetGeometryChanged); smartLoader_->SetFrameInWidget(*thumbnailWidget, 0, instanceId, 0); thumbnailWidget->SetInteractor(*thumbnailInteractor_); } @@ -409,9 +410,9 @@ void SelectStudy(const std::string& studyId) { LOG(INFO) << "Selecting study: " << studyId; - context_->GetOrthancApiClient().GetJsonAsync( + context_->GetOrthancApiClient()->GetJsonAsync( "/studies/" + studyId, new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage> - (*this, &SimpleViewerApplication::OnStudyReceived)); + (GetSharedObserver(), &SimpleViewerApplication::OnStudyReceived)); } void OnWidgetGeometryChanged(const Deprecated::SliceViewerWidget::GeometryChangedMessage& message) @@ -422,7 +423,7 @@ void SelectSeriesInMainViewport(const std::string& seriesId) { - Deprecated::SliceViewerWidget& widget = *dynamic_cast<Deprecated::SliceViewerWidget*>(mainWidget_); + Deprecated::SliceViewerWidget& widget = dynamic_cast<Deprecated::SliceViewerWidget&>(*GetCentralWidget()); smartLoader_->SetFrameInWidget(widget, 0, instancesIdsPerSeriesId_[seriesId][0], 0); } @@ -451,7 +452,7 @@ virtual void InitializeWasm() { AttachWidgetToWasmViewport("canvas", thumbnailsLayout_); - AttachWidgetToWasmViewport("canvas2", mainWidget_); + AttachWidgetToWasmViewport("canvas2", widget); } #endif
--- a/Applications/Samples/SingleFrameApplication.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Samples/SingleFrameApplication.h Wed Oct 23 11:04:47 2019 +0200 @@ -38,7 +38,7 @@ { class SingleFrameApplication : public SampleSingleCanvasApplicationBase, - public IObserver + public ObserverBase<SingleFrameApplication> { private: class Interactor : public Deprecated::IWorldSceneInteractor @@ -127,7 +127,7 @@ void OffsetSlice(int offset) { - if (source_ != NULL) + if (source_) { int slice = static_cast<int>(slice_) + offset; @@ -149,21 +149,15 @@ } - Deprecated::SliceViewerWidget& GetMainWidget() - { - return *dynamic_cast<Deprecated::SliceViewerWidget*>(mainWidget_); - } - - void SetSlice(size_t index) { - if (source_ != NULL && + if (source_ && index < source_->GetSlicesCount()) { slice_ = static_cast<unsigned int>(index); #if 1 - GetMainWidget().SetSlice(source_->GetSlice(slice_).GetGeometry()); + widget_->SetSlice(source_->GetSlice(slice_).GetGeometry()); #else // TEST for scene extents - Rotate the axes double a = 15.0 / 180.0 * boost::math::constants::pi<double>(); @@ -189,22 +183,22 @@ // Once the geometry of the series is downloaded from Orthanc, // display its middle slice, and adapt the viewport to fit this // slice - if (source_ == &message.GetOrigin()) + if (source_ && + source_.get() == &message.GetOrigin()) { SetSlice(source_->GetSlicesCount() / 2); } - GetMainWidget().FitContent(); + widget_->FitContent(); } - + + boost::shared_ptr<Deprecated::SliceViewerWidget> widget_; std::auto_ptr<Interactor> mainWidgetInteractor_; - const Deprecated::DicomSeriesVolumeSlicer* source_; + boost::shared_ptr<Deprecated::DicomSeriesVolumeSlicer> source_; unsigned int slice_; public: - SingleFrameApplication(MessageBroker& broker) : - IObserver(broker), - source_(NULL), + SingleFrameApplication() : slice_(0) { } @@ -243,13 +237,15 @@ std::string instance = parameters["instance"].as<std::string>(); int frame = parameters["frame"].as<unsigned int>(); - mainWidget_ = new Deprecated::SliceViewerWidget(GetBroker(), "main-widget"); + widget_.reset(new Deprecated::SliceViewerWidget("main-widget")); + SetCentralWidget(widget_); - std::auto_ptr<Deprecated::DicomSeriesVolumeSlicer> layer(new Deprecated::DicomSeriesVolumeSlicer(GetBroker(), context->GetOrthancApiClient())); - source_ = layer.get(); + boost::shared_ptr<Deprecated::DicomSeriesVolumeSlicer> layer(new Deprecated::DicomSeriesVolumeSlicer); + layer->Connect(context->GetOrthancApiClient()); + source_ = layer; layer->LoadFrame(instance, frame); - layer->RegisterObserverCallback(new Callable<SingleFrameApplication, Deprecated::IVolumeSlicer::GeometryReadyMessage>(*this, &SingleFrameApplication::OnMainWidgetGeometryReady)); - GetMainWidget().AddLayer(layer.release()); + Register<Deprecated::IVolumeSlicer::GeometryReadyMessage>(*layer, &SingleFrameApplication::OnMainWidgetGeometryReady); + widget_->AddLayer(layer); Deprecated::RenderStyle s; @@ -258,11 +254,11 @@ s.interpolation_ = ImageInterpolation_Bilinear; } - GetMainWidget().SetLayerStyle(0, s); - GetMainWidget().SetTransmitMouseOver(true); + widget_->SetLayerStyle(0, s); + widget_->SetTransmitMouseOver(true); mainWidgetInteractor_.reset(new Interactor(*this)); - GetMainWidget().SetInteractor(*mainWidgetInteractor_); + widget_->SetInteractor(*mainWidgetInteractor_); } };
--- a/Applications/Samples/SingleFrameEditorApplication.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Samples/SingleFrameEditorApplication.h Wed Oct 23 11:04:47 2019 +0200 @@ -28,15 +28,14 @@ #include "../../Framework/Radiography/RadiographyLayerMoveTracker.h" #include "../../Framework/Radiography/RadiographyLayerResizeTracker.h" #include "../../Framework/Radiography/RadiographyLayerRotateTracker.h" +#include "../../Framework/Radiography/RadiographyMaskLayer.h" #include "../../Framework/Radiography/RadiographyScene.h" #include "../../Framework/Radiography/RadiographySceneCommand.h" +#include "../../Framework/Radiography/RadiographySceneReader.h" +#include "../../Framework/Radiography/RadiographySceneWriter.h" #include "../../Framework/Radiography/RadiographyWidget.h" #include "../../Framework/Radiography/RadiographyWindowingTracker.h" -#include "../../Framework/Radiography/RadiographySceneWriter.h" -#include "../../Framework/Radiography/RadiographySceneReader.h" -#include "../../Framework/Radiography/RadiographyMaskLayer.h" - -#include <../../Framework/Toolbox/TextRenderer.h> +#include "../../Framework/Toolbox/TextRenderer.h" #include <Core/HttpClient.h> #include <Core/Images/FontRegistry.h> @@ -57,7 +56,7 @@ { class RadiographyEditorInteractor : public Deprecated::IWorldSceneInteractor, - public IObserver + public ObserverBase<RadiographyEditorInteractor> { private: enum Tool @@ -84,8 +83,7 @@ public: - RadiographyEditorInteractor(MessageBroker& broker) : - IObserver(broker), + RadiographyEditorInteractor() : context_(NULL), tool_(Tool_Move), maskLayer_(NULL) @@ -317,7 +315,7 @@ LOG(INFO) << "JSON export was successful: " << snapshot.toStyledString(); - boost::shared_ptr<RadiographyScene> scene(new RadiographyScene(GetBroker())); + boost::shared_ptr<RadiographyScene> scene(new RadiographyScene); RadiographySceneReader reader(*scene, context_->GetOrthancApiClient()); Orthanc::FontRegistry fontRegistry; @@ -353,7 +351,7 @@ if (context_ != NULL) { - widget.GetScene().ExportDicom(context_->GetOrthancApiClient(), + widget.GetScene().ExportDicom(*context_->GetOrthancApiClient(), tags, std::string(), 0.1, 0.1, widget.IsInverted(), widget.GetInterpolation(), EXPORT_USING_PAM); } @@ -437,12 +435,6 @@ RadiographyMaskLayer* maskLayer_; public: - SingleFrameEditorApplication(MessageBroker& broker) : - IObserver(broker), - interactor_(broker) - { - } - virtual ~SingleFrameEditorApplication() { LOG(WARNING) << "Destroying the application"; @@ -496,9 +488,9 @@ fontRegistry_.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); - scene_.reset(new RadiographyScene(GetBroker())); + scene_.reset(new RadiographyScene); - RadiographyLayer& dicomLayer = scene_->LoadDicomFrame(context->GetOrthancApiClient(), instance, 0, false, NULL); + RadiographyLayer& dicomLayer = scene_->LoadDicomFrame(*context->GetOrthancApiClient(), instance, 0, false, NULL); //scene_->LoadDicomFrame(instance, frame, false); //.SetPan(200, 0); // = scene_->LoadDicomFrame(context->GetOrthancApiClient(), "61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", 0, false, NULL); @@ -535,10 +527,10 @@ layer.SetPan(0, 200); } - - mainWidget_ = new RadiographyWidget(GetBroker(), scene_, "main-widget"); - mainWidget_->SetTransmitMouseOver(true); - mainWidget_->SetInteractor(interactor_); + boost::shared_ptr<RadiographyWidget> widget(new RadiographyWidget(scene_, "main-widget")); + widget->SetTransmitMouseOver(true); + widget->SetInteractor(interactor_); + SetCentralWidget(widget); //scene_->SetWindowing(128, 256); }
--- a/Applications/Sdl/SdlEngine.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Sdl/SdlEngine.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -99,9 +99,7 @@ SdlEngine::SdlEngine(SdlWindow& window, - NativeStoneApplicationContext& context, - MessageBroker& broker) : - IObserver(broker), + NativeStoneApplicationContext& context) : window_(window), context_(context), surface_(window),
--- a/Applications/Sdl/SdlEngine.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Sdl/SdlEngine.h Wed Oct 23 11:04:47 2019 +0200 @@ -23,12 +23,13 @@ #if ORTHANC_ENABLE_SDL == 1 +#include "../../Framework/Messages/ObserverBase.h" +#include "../Generic/NativeStoneApplicationContext.h" #include "SdlCairoSurface.h" -#include "../Generic/NativeStoneApplicationContext.h" namespace OrthancStone { - class SdlEngine : public IObserver + class SdlEngine : public ObserverBase<SdlEngine> { private: SdlWindow& window_; @@ -46,8 +47,7 @@ public: SdlEngine(SdlWindow& window, - NativeStoneApplicationContext& context, - MessageBroker& broker); + NativeStoneApplicationContext& context); void OnViewportChanged(const Deprecated::IViewport::ViewportChangedMessage& message) {
--- a/Applications/Sdl/SdlStoneApplicationRunner.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Sdl/SdlStoneApplicationRunner.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -103,20 +103,19 @@ LOG(WARNING) << "Starting the application"; SdlWindow window(title.c_str(), width_, height_, enableOpenGl_); - SdlEngine sdl(window, context, broker_); + boost::shared_ptr<SdlEngine> sdl(new SdlEngine(window, context)); { NativeStoneApplicationContext::GlobalMutexLocker locker(context); - locker.GetCentralViewport().RegisterObserverCallback( - new Callable<SdlEngine, Deprecated::IViewport::ViewportChangedMessage> - (sdl, &SdlEngine::OnViewportChanged)); + sdl->Register<Deprecated::IViewport::ViewportChangedMessage> + (locker.GetCentralViewport(), &SdlEngine::OnViewportChanged); //context.GetCentralViewport().Register(sdl); // (*) } context.Start(); - sdl.Run(); + sdl->Run(); LOG(WARNING) << "Stopping the application";
--- a/Applications/Sdl/SdlStoneApplicationRunner.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/Sdl/SdlStoneApplicationRunner.h Wed Oct 23 11:04:47 2019 +0200 @@ -39,9 +39,8 @@ bool enableOpenGl_; public: - SdlStoneApplicationRunner(MessageBroker& broker, - IStoneApplication& application) : - NativeStoneApplicationRunner(broker, application) + SdlStoneApplicationRunner(boost::shared_ptr<IStoneApplication> application) : + NativeStoneApplicationRunner(application) { }
--- a/Applications/StoneApplicationContext.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/StoneApplicationContext.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -32,35 +32,35 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } - orthanc_.reset(new Deprecated::OrthancApiClient(broker_, *webService_, orthancBaseUrl_)); + orthanc_.reset(new Deprecated::OrthancApiClient(*webService_, orthancBaseUrl_)); } - Deprecated::IWebService& StoneApplicationContext::GetWebService() + boost::shared_ptr<Deprecated::IWebService> StoneApplicationContext::GetWebService() { if (webService_ == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } - return *webService_; + return webService_; } - Deprecated::OrthancApiClient& StoneApplicationContext::GetOrthancApiClient() + boost::shared_ptr<Deprecated::OrthancApiClient> StoneApplicationContext::GetOrthancApiClient() { if (orthanc_.get() == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } - return *orthanc_; + return orthanc_; } - void StoneApplicationContext::SetWebService(Deprecated::IWebService& webService) + void StoneApplicationContext::SetWebService(boost::shared_ptr<Deprecated::IWebService> webService) { - webService_ = &webService; + webService_ = webService; InitializeOrthanc(); }
--- a/Applications/StoneApplicationContext.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Applications/StoneApplicationContext.h Wed Oct 23 11:04:47 2019 +0200 @@ -59,18 +59,15 @@ class StoneApplicationContext : public boost::noncopyable { private: - MessageBroker& broker_; - Deprecated::IWebService* webService_; - Deprecated::IDelayedCallExecutor* delayedCallExecutor_; - std::auto_ptr<Deprecated::OrthancApiClient> orthanc_; + boost::shared_ptr<Deprecated::IWebService> webService_; + Deprecated::IDelayedCallExecutor* delayedCallExecutor_; // TODO => shared_ptr ?? + boost::shared_ptr<Deprecated::OrthancApiClient> orthanc_; std::string orthancBaseUrl_; void InitializeOrthanc(); public: - StoneApplicationContext(MessageBroker& broker) : - broker_(broker), - webService_(NULL), + StoneApplicationContext() : delayedCallExecutor_(NULL) { } @@ -79,21 +76,11 @@ { } - MessageBroker& GetMessageBroker() - { - return broker_; - } + boost::shared_ptr<Deprecated::IWebService> GetWebService(); - bool HasWebService() const - { - return webService_ != NULL; - } + boost::shared_ptr<Deprecated::OrthancApiClient> GetOrthancApiClient(); - Deprecated::IWebService& GetWebService(); - - Deprecated::OrthancApiClient& GetOrthancApiClient(); - - void SetWebService(Deprecated::IWebService& webService); + void SetWebService(boost::shared_ptr<Deprecated::IWebService> webService); void SetOrthancBaseUrl(const std::string& baseUrl);
--- a/Framework/Deprecated/Layers/DicomSeriesVolumeSlicer.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Layers/DicomSeriesVolumeSlicer.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -87,59 +87,73 @@ } - DicomSeriesVolumeSlicer::DicomSeriesVolumeSlicer(OrthancStone::MessageBroker& broker, - OrthancApiClient& orthanc) : - IVolumeSlicer(broker), - IObserver(broker), - loader_(broker, orthanc), + DicomSeriesVolumeSlicer::DicomSeriesVolumeSlicer() : quality_(SliceImageQuality_FullPng) { - loader_.RegisterObserverCallback( - new OrthancStone::Callable<DicomSeriesVolumeSlicer, OrthancSlicesLoader::SliceGeometryReadyMessage> - (*this, &DicomSeriesVolumeSlicer::OnSliceGeometryReady)); - - loader_.RegisterObserverCallback( - new OrthancStone::Callable<DicomSeriesVolumeSlicer, OrthancSlicesLoader::SliceGeometryErrorMessage> - (*this, &DicomSeriesVolumeSlicer::OnSliceGeometryError)); + } - loader_.RegisterObserverCallback( - new OrthancStone::Callable<DicomSeriesVolumeSlicer, OrthancSlicesLoader::SliceImageReadyMessage> - (*this, &DicomSeriesVolumeSlicer::OnSliceImageReady)); - - loader_.RegisterObserverCallback( - new OrthancStone::Callable<DicomSeriesVolumeSlicer, OrthancSlicesLoader::SliceImageErrorMessage> - (*this, &DicomSeriesVolumeSlicer::OnSliceImageError)); + void DicomSeriesVolumeSlicer::Connect(boost::shared_ptr<OrthancApiClient> orthanc) + { + loader_.reset(new OrthancSlicesLoader(orthanc)); + Register<OrthancSlicesLoader::SliceGeometryReadyMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceGeometryReady); + Register<OrthancSlicesLoader::SliceGeometryErrorMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceGeometryError); + Register<OrthancSlicesLoader::SliceImageReadyMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceImageReady); + Register<OrthancSlicesLoader::SliceImageErrorMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceImageError); } void DicomSeriesVolumeSlicer::LoadSeries(const std::string& seriesId) { - loader_.ScheduleLoadSeries(seriesId); + if (loader_.get() == NULL) + { + // Should have called "Connect()" + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + + loader_->ScheduleLoadSeries(seriesId); } void DicomSeriesVolumeSlicer::LoadInstance(const std::string& instanceId) { - loader_.ScheduleLoadInstance(instanceId); + if (loader_.get() == NULL) + { + // Should have called "Connect()" + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + + loader_->ScheduleLoadInstance(instanceId); } void DicomSeriesVolumeSlicer::LoadFrame(const std::string& instanceId, unsigned int frame) { - loader_.ScheduleLoadFrame(instanceId, frame); + if (loader_.get() == NULL) + { + // Should have called "Connect()" + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + + loader_->ScheduleLoadFrame(instanceId, frame); } bool DicomSeriesVolumeSlicer::GetExtent(std::vector<OrthancStone::Vector>& points, const OrthancStone::CoordinateSystem3D& viewportSlice) { + if (loader_.get() == NULL) + { + // Should have called "Connect()" + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + 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 @@ -151,12 +165,18 @@ void DicomSeriesVolumeSlicer::ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice) { + if (loader_.get() == NULL) + { + // Should have called "Connect()" + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + size_t index; - if (loader_.IsGeometryReady() && - loader_.LookupSlice(index, viewportSlice)) + if (loader_->IsGeometryReady() && + loader_->LookupSlice(index, viewportSlice)) { - loader_.ScheduleLoadSliceImage(index, quality_); + loader_->ScheduleLoadSliceImage(index, quality_); } } }
--- a/Framework/Deprecated/Layers/DicomSeriesVolumeSlicer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Layers/DicomSeriesVolumeSlicer.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,6 +22,7 @@ #pragma once #include "IVolumeSlicer.h" +#include "../../Messages/ObserverBase.h" #include "../Toolbox/IWebService.h" #include "../Toolbox/OrthancSlicesLoader.h" #include "../Toolbox/OrthancApiClient.h" @@ -33,7 +34,7 @@ // messages are sent to observers so they can use it class DicomSeriesVolumeSlicer : public IVolumeSlicer, - public OrthancStone::IObserver + public OrthancStone::ObserverBase<DicomSeriesVolumeSlicer> //private OrthancSlicesLoader::ISliceLoaderObserver { public: @@ -79,13 +80,14 @@ private: class RendererFactory; - OrthancSlicesLoader loader_; + boost::shared_ptr<OrthancSlicesLoader> loader_; SliceImageQuality quality_; public: - DicomSeriesVolumeSlicer(OrthancStone::MessageBroker& broker, - OrthancApiClient& orthanc); + DicomSeriesVolumeSlicer(); + void Connect(boost::shared_ptr<OrthancApiClient> orthanc); + void LoadSeries(const std::string& seriesId); void LoadInstance(const std::string& instanceId); @@ -105,12 +107,12 @@ size_t GetSlicesCount() const { - return loader_.GetSlicesCount(); + return loader_->GetSlicesCount(); } const Slice& GetSlice(size_t slice) const { - return loader_.GetSlice(slice); + return loader_->GetSlice(slice); } virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
--- a/Framework/Deprecated/Layers/DicomStructureSetSlicer.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Layers/DicomStructureSetSlicer.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -140,15 +140,10 @@ }; - DicomStructureSetSlicer::DicomStructureSetSlicer(OrthancStone::MessageBroker& broker, - StructureSetLoader& loader) : - IVolumeSlicer(broker), - IObserver(broker), + DicomStructureSetSlicer::DicomStructureSetSlicer(StructureSetLoader& loader) : loader_(loader) { - loader_.RegisterObserverCallback( - new OrthancStone::Callable<DicomStructureSetSlicer, StructureSetLoader::ContentChangedMessage> - (*this, &DicomStructureSetSlicer::OnStructureSetLoaded)); + Register<StructureSetLoader::ContentChangedMessage>(loader_, &DicomStructureSetSlicer::OnStructureSetLoaded); }
--- a/Framework/Deprecated/Layers/DicomStructureSetSlicer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Layers/DicomStructureSetSlicer.h Wed Oct 23 11:04:47 2019 +0200 @@ -28,7 +28,7 @@ { class DicomStructureSetSlicer : public IVolumeSlicer, - public OrthancStone::IObserver + public OrthancStone::ObserverBase<DicomStructureSetSlicer> { private: class Renderer; @@ -42,8 +42,7 @@ } public: - DicomStructureSetSlicer(OrthancStone::MessageBroker& broker, - StructureSetLoader& loader); + DicomStructureSetSlicer(StructureSetLoader& loader); virtual bool GetExtent(std::vector<OrthancStone::Vector>& points, const OrthancStone::CoordinateSystem3D& viewportPlane)
--- a/Framework/Deprecated/Layers/IVolumeSlicer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Layers/IVolumeSlicer.h Wed Oct 23 11:04:47 2019 +0200 @@ -122,11 +122,6 @@ }; - IVolumeSlicer(OrthancStone::MessageBroker& broker) : - IObservable(broker) - { - } - virtual ~IVolumeSlicer() { }
--- a/Framework/Deprecated/SmartLoader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/SmartLoader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -21,7 +21,6 @@ #include "SmartLoader.h" -#include "../Messages/MessageForwarder.h" #include "../StoneException.h" #include "Core/Images/Image.h" #include "Core/Logging.h" @@ -68,11 +67,6 @@ CachedSliceStatus status_; public: - CachedSlice(OrthancStone::MessageBroker& broker) : - IVolumeSlicer(broker) - { - } - virtual ~CachedSlice() { } @@ -106,7 +100,7 @@ CachedSlice* Clone() const { - CachedSlice* output = new CachedSlice(GetBroker()); + CachedSlice* output = new CachedSlice; output->sliceIndex_ = sliceIndex_; output->slice_.reset(slice_->Clone()); output->image_ = image_; @@ -119,10 +113,7 @@ }; - SmartLoader::SmartLoader(OrthancStone::MessageBroker& broker, - OrthancApiClient& orthancApiClient) : - IObservable(broker), - IObserver(broker), + SmartLoader::SmartLoader(boost::shared_ptr<OrthancApiClient> orthancApiClient) : imageQuality_(SliceImageQuality_FullPam), orthancApiClient_(orthancApiClient) { @@ -140,7 +131,7 @@ // the messages to its observables // in both cases, we must be carefull about objects lifecycle !!! - std::auto_ptr<IVolumeSlicer> layerSource; + boost::shared_ptr<IVolumeSlicer> layerSource; std::string sliceKeyId = instanceId + ":" + boost::lexical_cast<std::string>(frame); SmartLoader::CachedSlice* cachedSlice = NULL; @@ -151,22 +142,23 @@ } else { - layerSource.reset(new DicomSeriesVolumeSlicer(IObserver::GetBroker(), orthancApiClient_)); + layerSource.reset(new DicomSeriesVolumeSlicer); + dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->Connect(orthancApiClient_); dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_); - layerSource->RegisterObserverCallback(new OrthancStone::Callable<SmartLoader, IVolumeSlicer::GeometryReadyMessage>(*this, &SmartLoader::OnLayerGeometryReady)); - layerSource->RegisterObserverCallback(new OrthancStone::Callable<SmartLoader, DicomSeriesVolumeSlicer::FrameReadyMessage>(*this, &SmartLoader::OnFrameReady)); - layerSource->RegisterObserverCallback(new OrthancStone::Callable<SmartLoader, IVolumeSlicer::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady)); + Register<IVolumeSlicer::GeometryReadyMessage>(*layerSource, &SmartLoader::OnLayerGeometryReady); + Register<DicomSeriesVolumeSlicer::FrameReadyMessage>(*layerSource, &SmartLoader::OnFrameReady); + Register<IVolumeSlicer::LayerReadyMessage>(*layerSource, &SmartLoader::OnLayerReady); dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->LoadFrame(instanceId, frame); } // make sure that the widget registers the events before we trigger them if (sliceViewer.GetLayerCount() == layerIndex) { - sliceViewer.AddLayer(layerSource.release()); + sliceViewer.AddLayer(layerSource); } else if (sliceViewer.GetLayerCount() > layerIndex) { - sliceViewer.ReplaceLayer(layerIndex, layerSource.release()); + sliceViewer.ReplaceLayer(layerIndex, layerSource); } else { @@ -190,7 +182,7 @@ // create the slice in the cache with "empty" data - boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::GetBroker())); + boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice); cachedSlice->slice_.reset(new Slice(instanceId, frame)); cachedSlice->status_ = CachedSliceStatus_ScheduledToLoad; std::string sliceKeyId = instanceId + ":" + boost::lexical_cast<std::string>(frame); @@ -199,12 +191,12 @@ cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice); - std::auto_ptr<IVolumeSlicer> layerSource(new DicomSeriesVolumeSlicer(IObserver::GetBroker(), orthancApiClient_)); - + std::auto_ptr<IVolumeSlicer> layerSource(new DicomSeriesVolumeSlicer); + dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->Connect(orthancApiClient_); dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_); - layerSource->RegisterObserverCallback(new OrthancStone::Callable<SmartLoader, IVolumeSlicer::GeometryReadyMessage>(*this, &SmartLoader::OnLayerGeometryReady)); - layerSource->RegisterObserverCallback(new OrthancStone::Callable<SmartLoader, DicomSeriesVolumeSlicer::FrameReadyMessage>(*this, &SmartLoader::OnFrameReady)); - layerSource->RegisterObserverCallback(new OrthancStone::Callable<SmartLoader, IVolumeSlicer::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady)); + Register<IVolumeSlicer::GeometryReadyMessage>(*layerSource, &SmartLoader::OnLayerGeometryReady); + Register<DicomSeriesVolumeSlicer::FrameReadyMessage>(*layerSource, &SmartLoader::OnFrameReady); + Register<IVolumeSlicer::LayerReadyMessage>(*layerSource, &SmartLoader::OnLayerReady); dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->LoadFrame(instanceId, frame); // keep a ref to the VolumeSlicer until the slice is fully loaded and saved to cache @@ -235,7 +227,7 @@ LOG(WARNING) << "Geometry ready: " << sliceKeyId; - boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::GetBroker())); + boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice); cachedSlice->slice_.reset(slice.Clone()); cachedSlice->effectiveQuality_ = source.GetImageQuality(); cachedSlice->status_ = CachedSliceStatus_GeometryLoaded; @@ -256,7 +248,7 @@ LOG(WARNING) << "Image ready: " << sliceKeyId; - boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::GetBroker())); + boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice); cachedSlice->image_.reset(Orthanc::Image::Clone(message.GetFrame())); cachedSlice->effectiveQuality_ = message.GetImageQuality(); cachedSlice->slice_.reset(message.GetSlice().Clone());
--- a/Framework/Deprecated/SmartLoader.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/SmartLoader.h Wed Oct 23 11:04:47 2019 +0200 @@ -30,7 +30,7 @@ { class SliceViewerWidget; - class SmartLoader : public OrthancStone::IObservable, public OrthancStone::IObserver + class SmartLoader : public OrthancStone::IObservable, public OrthancStone::ObserverBase<SmartLoader> { class CachedSlice; @@ -42,10 +42,10 @@ PreloadingInstances preloadingInstances_; SliceImageQuality imageQuality_; - OrthancApiClient& orthancApiClient_; + boost::shared_ptr<OrthancApiClient> orthancApiClient_; public: - SmartLoader(OrthancStone::MessageBroker& broker, OrthancApiClient& orthancApiClient); // TODO: add maxPreloadStorageSizeInBytes + SmartLoader(boost::shared_ptr<OrthancApiClient> orthancApiClient); // TODO: add maxPreloadStorageSizeInBytes // void PreloadStudy(const std::string studyId); // void PreloadSeries(const std::string seriesId);
--- a/Framework/Deprecated/Toolbox/BaseWebService.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/BaseWebService.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -97,9 +97,9 @@ GetAsyncInternal(uri, headers, new BaseWebService::BaseWebServicePayload(successCallback, failureCallback, payload), // ownership is transfered new OrthancStone::Callable<BaseWebService, IWebService::HttpRequestSuccessMessage> - (*this, &BaseWebService::CacheAndNotifyHttpSuccess), + (GetSharedObserver(), &BaseWebService::CacheAndNotifyHttpSuccess), new OrthancStone::Callable<BaseWebService, IWebService::HttpRequestErrorMessage> - (*this, &BaseWebService::NotifyHttpError), + (GetSharedObserver(), &BaseWebService::NotifyHttpError), timeoutInSeconds); } else
--- a/Framework/Deprecated/Toolbox/BaseWebService.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/BaseWebService.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,6 +22,7 @@ #pragma once #include "IWebService.h" +#include "../../Messages/ObserverBase.h" #include <string> #include <map> @@ -31,7 +32,7 @@ { // This is an intermediate of IWebService that implements some caching on // the HTTP GET requests - class BaseWebService : public IWebService, public OrthancStone::IObserver + class BaseWebService : public IWebService, public OrthancStone::ObserverBase<BaseWebService> { public: class CachedHttpRequestSuccessMessage @@ -90,10 +91,7 @@ std::deque<std::string> orderedCacheKeys_; public: - - BaseWebService(OrthancStone::MessageBroker& broker) : - IWebService(broker), - IObserver(broker), + BaseWebService() : cacheEnabled_(false), cacheCurrentSize_(0), cacheMaxSize_(100*1024*1024)
--- a/Framework/Deprecated/Toolbox/IDelayedCallExecutor.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/IDelayedCallExecutor.h Wed Oct 23 11:04:47 2019 +0200 @@ -35,22 +35,12 @@ // The IDelayedCall executes a callback after a delay (equivalent to timeout() function in javascript). class IDelayedCallExecutor : public boost::noncopyable { - protected: - OrthancStone::MessageBroker& broker_; - public: ORTHANC_STONE_DEFINE_EMPTY_MESSAGE(__FILE__, __LINE__, TimeoutMessage); - IDelayedCallExecutor(OrthancStone::MessageBroker& broker) : - broker_(broker) - { - } - - virtual ~IDelayedCallExecutor() { } - virtual void Schedule(OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback, unsigned int timeoutInMs = 1000) = 0;
--- a/Framework/Deprecated/Toolbox/IWebService.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/IWebService.h Wed Oct 23 11:04:47 2019 +0200 @@ -40,9 +40,6 @@ // and you'll be notified when the response/error is ready. class IWebService : public boost::noncopyable { - protected: - OrthancStone::MessageBroker& broker_; - public: typedef std::map<std::string, std::string> HttpHeaders; @@ -138,12 +135,6 @@ }; - IWebService(OrthancStone::MessageBroker& broker) : - broker_(broker) - { - } - - virtual ~IWebService() { }
--- a/Framework/Deprecated/Toolbox/OrthancApiClient.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/OrthancApiClient.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -73,7 +73,6 @@ std::auto_ptr< OrthancStone::MessageHandler<BinaryResponseReadyMessage> > binaryHandler_; std::auto_ptr< OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage> > failureHandler_; std::auto_ptr< Orthanc::IDynamicObject > userPayload_; - OrthancStone::MessageBroker& broker_; void NotifyConversionError(const IWebService::HttpRequestSuccessMessage& message) const { if (failureHandler_.get() != NULL) @@ -84,14 +83,12 @@ } public: - WebServicePayload(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<EmptyResponseReadyMessage>* handler, + WebServicePayload(OrthancStone::MessageHandler<EmptyResponseReadyMessage>* handler, OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureHandler, Orthanc::IDynamicObject* userPayload) : emptyHandler_(handler), failureHandler_(failureHandler), - userPayload_(userPayload), - broker_(broker) + userPayload_(userPayload) { if (handler == NULL) @@ -100,14 +97,12 @@ } } - WebServicePayload(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<BinaryResponseReadyMessage>* handler, + WebServicePayload(OrthancStone::MessageHandler<BinaryResponseReadyMessage>* handler, OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureHandler, Orthanc::IDynamicObject* userPayload) : binaryHandler_(handler), failureHandler_(failureHandler), - userPayload_(userPayload), - broker_(broker) + userPayload_(userPayload) { if (handler == NULL) { @@ -115,14 +110,12 @@ } } - WebServicePayload(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<JsonResponseReadyMessage>* handler, + WebServicePayload(OrthancStone::MessageHandler<JsonResponseReadyMessage>* handler, OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureHandler, Orthanc::IDynamicObject* userPayload) : jsonHandler_(handler), failureHandler_(failureHandler), - userPayload_(userPayload), - broker_(broker) + userPayload_(userPayload) { if (handler == NULL) { @@ -134,35 +127,26 @@ { if (emptyHandler_.get() != NULL) { - if (broker_.IsActive(*(emptyHandler_->GetObserver()))) - { - emptyHandler_->Apply(OrthancApiClient::EmptyResponseReadyMessage - (message.GetUri(), userPayload_.get())); - } + emptyHandler_->Apply(OrthancApiClient::EmptyResponseReadyMessage + (message.GetUri(), userPayload_.get())); } else if (binaryHandler_.get() != NULL) { - if (broker_.IsActive(*(binaryHandler_->GetObserver()))) - { - binaryHandler_->Apply(OrthancApiClient::BinaryResponseReadyMessage - (message.GetUri(), message.GetAnswer(), - message.GetAnswerSize(), userPayload_.get())); - } + binaryHandler_->Apply(OrthancApiClient::BinaryResponseReadyMessage + (message.GetUri(), message.GetAnswer(), + message.GetAnswerSize(), userPayload_.get())); } else if (jsonHandler_.get() != NULL) { - if (broker_.IsActive(*(jsonHandler_->GetObserver()))) + Json::Value response; + if (MessagingToolbox::ParseJson(response, message.GetAnswer(), message.GetAnswerSize())) { - Json::Value response; - if (MessagingToolbox::ParseJson(response, message.GetAnswer(), message.GetAnswerSize())) - { - jsonHandler_->Apply(OrthancApiClient::JsonResponseReadyMessage - (message.GetUri(), response, userPayload_.get())); - } - else - { - NotifyConversionError(message); - } + jsonHandler_->Apply(OrthancApiClient::JsonResponseReadyMessage + (message.GetUri(), response, userPayload_.get())); + } + else + { + NotifyConversionError(message); } } else @@ -182,11 +166,8 @@ }; - OrthancApiClient::OrthancApiClient(OrthancStone::MessageBroker& broker, - IWebService& web, + OrthancApiClient::OrthancApiClient(IWebService& web, const std::string& baseUrl) : - IObservable(broker), - IObserver(broker), web_(web), baseUrl_(baseUrl) { @@ -202,11 +183,11 @@ IWebService::HttpHeaders emptyHeaders; web_.GetAsync(baseUrl_ + uri, emptyHeaders, - new WebServicePayload(IObservable::GetBroker(), successCallback, failureCallback, payload), + new WebServicePayload(successCallback, failureCallback, payload), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> - (*this, &OrthancApiClient::NotifyHttpSuccess), + (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> - (*this, &OrthancApiClient::NotifyHttpError)); + (GetSharedObserver(), &OrthancApiClient::NotifyHttpError)); } @@ -232,11 +213,11 @@ // printf("GET [%s] [%s]\n", baseUrl_.c_str(), uri.c_str()); web_.GetAsync(baseUrl_ + uri, headers, - new WebServicePayload(IObservable::GetBroker(), successCallback, failureCallback, payload), + new WebServicePayload(successCallback, failureCallback, payload), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> - (*this, &OrthancApiClient::NotifyHttpSuccess), + (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> - (*this, &OrthancApiClient::NotifyHttpError)); + (GetSharedObserver(), &OrthancApiClient::NotifyHttpError)); } @@ -248,11 +229,11 @@ Orthanc::IDynamicObject* payload) { web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body, - new WebServicePayload(IObservable::GetBroker(), successCallback, failureCallback, payload), + new WebServicePayload(successCallback, failureCallback, payload), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> - (*this, &OrthancApiClient::NotifyHttpSuccess), + (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> - (*this, &OrthancApiClient::NotifyHttpError)); + (GetSharedObserver(), &OrthancApiClient::NotifyHttpError)); } @@ -271,11 +252,11 @@ Orthanc::IDynamicObject* payload /* takes ownership */) { web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body, - new WebServicePayload(IObservable::GetBroker(), successCallback, failureCallback, payload), + new WebServicePayload(successCallback, failureCallback, payload), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> - (*this, &OrthancApiClient::NotifyHttpSuccess), + (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> - (*this, &OrthancApiClient::NotifyHttpError)); + (GetSharedObserver(), &OrthancApiClient::NotifyHttpError)); } void OrthancApiClient::PostJsonAsyncExpectJson( @@ -318,11 +299,11 @@ Orthanc::IDynamicObject* payload) { web_.DeleteAsync(baseUrl_ + uri, IWebService::HttpHeaders(), - new WebServicePayload(IObservable::GetBroker(), successCallback, failureCallback, payload), + new WebServicePayload(successCallback, failureCallback, payload), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestSuccessMessage> - (*this, &OrthancApiClient::NotifyHttpSuccess), + (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess), new OrthancStone::Callable<OrthancApiClient, IWebService::HttpRequestErrorMessage> - (*this, &OrthancApiClient::NotifyHttpError)); + (GetSharedObserver(), &OrthancApiClient::NotifyHttpError)); }
--- a/Framework/Deprecated/Toolbox/OrthancApiClient.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/OrthancApiClient.h Wed Oct 23 11:04:47 2019 +0200 @@ -25,13 +25,13 @@ #include <json/json.h> #include "IWebService.h" -#include "../../Messages/IObservable.h" +#include "../../Messages/ObserverBase.h" namespace Deprecated { class OrthancApiClient : public OrthancStone::IObservable, - public OrthancStone::IObserver + public OrthancStone::ObserverBase<OrthancApiClient> { public: class JsonResponseReadyMessage : public OrthancStone::IMessage @@ -157,8 +157,7 @@ std::string baseUrl_; public: - OrthancApiClient(OrthancStone::MessageBroker& broker, - IWebService& web, + OrthancApiClient(IWebService& web, const std::string& baseUrl); virtual ~OrthancApiClient()
--- a/Framework/Deprecated/Toolbox/OrthancSlicesLoader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/OrthancSlicesLoader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -639,10 +639,7 @@ } - OrthancSlicesLoader::OrthancSlicesLoader(OrthancStone::MessageBroker& broker, - OrthancApiClient& orthanc) : - OrthancStone::IObservable(broker), - OrthancStone::IObserver(broker), + OrthancSlicesLoader::OrthancSlicesLoader(boost::shared_ptr<OrthancApiClient> orthanc) : orthanc_(orthanc), state_(State_Initialization) { @@ -658,10 +655,10 @@ else { state_ = State_LoadingGeometry; - orthanc_.GetJsonAsync("/series/" + seriesId + "/instances-tags", - new OrthancStone::Callable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseSeriesGeometry), - new OrthancStone::Callable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(*this, &OrthancSlicesLoader::OnGeometryError), - NULL); + orthanc_->GetJsonAsync("/series/" + seriesId + "/instances-tags", + new OrthancStone::Callable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &OrthancSlicesLoader::ParseSeriesGeometry), + new OrthancStone::Callable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(GetSharedObserver(), &OrthancSlicesLoader::OnGeometryError), + NULL); } } @@ -677,10 +674,10 @@ // Tag "3004-000c" is "Grid Frame Offset Vector", which is // mandatory to read RT DOSE, but is too long to be returned by default - orthanc_.GetJsonAsync("/instances/" + instanceId + "/tags?ignore-length=3004-000c", - new OrthancStone::Callable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseInstanceGeometry), - new OrthancStone::Callable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(*this, &OrthancSlicesLoader::OnGeometryError), - Operation::DownloadInstanceGeometry(instanceId)); + orthanc_->GetJsonAsync("/instances/" + instanceId + "/tags?ignore-length=3004-000c", + new OrthancStone::Callable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &OrthancSlicesLoader::ParseInstanceGeometry), + new OrthancStone::Callable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(GetSharedObserver(), &OrthancSlicesLoader::OnGeometryError), + Operation::DownloadInstanceGeometry(instanceId)); } } @@ -696,10 +693,10 @@ { state_ = State_LoadingGeometry; - orthanc_.GetJsonAsync("/instances/" + instanceId + "/tags", - new OrthancStone::Callable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseFrameGeometry), - new OrthancStone::Callable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(*this, &OrthancSlicesLoader::OnGeometryError), - Operation::DownloadFrameGeometry(instanceId, frame)); + orthanc_->GetJsonAsync("/instances/" + instanceId + "/tags", + new OrthancStone::Callable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &OrthancSlicesLoader::ParseFrameGeometry), + new OrthancStone::Callable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(GetSharedObserver(), &OrthancSlicesLoader::OnGeometryError), + Operation::DownloadFrameGeometry(instanceId, frame)); } } @@ -770,23 +767,23 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - orthanc_.GetBinaryAsync(uri, "image/png", - new OrthancStone::Callable<OrthancSlicesLoader, - OrthancApiClient::BinaryResponseReadyMessage> - (*this, &OrthancSlicesLoader::ParseSliceImagePng), - new OrthancStone::Callable<OrthancSlicesLoader, - IWebService::HttpRequestErrorMessage> - (*this, &OrthancSlicesLoader::OnSliceImageError), - Operation::DownloadSliceImage( - static_cast<unsigned int>(index), slice, SliceImageQuality_FullPng)); -} + orthanc_->GetBinaryAsync(uri, "image/png", + new OrthancStone::Callable<OrthancSlicesLoader, + OrthancApiClient::BinaryResponseReadyMessage> + (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceImagePng), + new OrthancStone::Callable<OrthancSlicesLoader, + IWebService::HttpRequestErrorMessage> + (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError), + Operation::DownloadSliceImage( + static_cast<unsigned int>(index), slice, SliceImageQuality_FullPng)); + } void OrthancSlicesLoader::ScheduleSliceImagePam(const Slice& slice, size_t index) { std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + - boost::lexical_cast<std::string>(slice.GetFrame())); + boost::lexical_cast<std::string>(slice.GetFrame())); switch (slice.GetConverter().GetExpectedPixelFormat()) { @@ -806,15 +803,15 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - orthanc_.GetBinaryAsync(uri, "image/x-portable-arbitrarymap", - new OrthancStone::Callable<OrthancSlicesLoader, - OrthancApiClient::BinaryResponseReadyMessage> - (*this, &OrthancSlicesLoader::ParseSliceImagePam), - new OrthancStone::Callable<OrthancSlicesLoader, - IWebService::HttpRequestErrorMessage> - (*this, &OrthancSlicesLoader::OnSliceImageError), - Operation::DownloadSliceImage(static_cast<unsigned int>(index), - slice, SliceImageQuality_FullPam)); + orthanc_->GetBinaryAsync(uri, "image/x-portable-arbitrarymap", + new OrthancStone::Callable<OrthancSlicesLoader, + OrthancApiClient::BinaryResponseReadyMessage> + (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceImagePam), + new OrthancStone::Callable<OrthancSlicesLoader, + IWebService::HttpRequestErrorMessage> + (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError), + Operation::DownloadSliceImage(static_cast<unsigned int>(index), + slice, SliceImageQuality_FullPam)); } @@ -849,15 +846,15 @@ "-" + slice.GetOrthancInstanceId() + "_" + boost::lexical_cast<std::string>(slice.GetFrame())); - orthanc_.GetJsonAsync(uri, - new OrthancStone::Callable<OrthancSlicesLoader, - OrthancApiClient::JsonResponseReadyMessage> - (*this, &OrthancSlicesLoader::ParseSliceImageJpeg), - new OrthancStone::Callable<OrthancSlicesLoader, - IWebService::HttpRequestErrorMessage> - (*this, &OrthancSlicesLoader::OnSliceImageError), - Operation::DownloadSliceImage( - static_cast<unsigned int>(index), slice, quality)); + orthanc_->GetJsonAsync(uri, + new OrthancStone::Callable<OrthancSlicesLoader, + OrthancApiClient::JsonResponseReadyMessage> + (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceImageJpeg), + new OrthancStone::Callable<OrthancSlicesLoader, + IWebService::HttpRequestErrorMessage> + (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError), + Operation::DownloadSliceImage( + static_cast<unsigned int>(index), slice, quality)); } @@ -890,15 +887,15 @@ { std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + boost::lexical_cast<std::string>(slice.GetFrame()) + "/raw.gz"); - orthanc_.GetBinaryAsync(uri, IWebService::HttpHeaders(), - new OrthancStone::Callable<OrthancSlicesLoader, - OrthancApiClient::BinaryResponseReadyMessage> - (*this, &OrthancSlicesLoader::ParseSliceRawImage), - new OrthancStone::Callable<OrthancSlicesLoader, - IWebService::HttpRequestErrorMessage> - (*this, &OrthancSlicesLoader::OnSliceImageError), - Operation::DownloadSliceRawImage( - static_cast<unsigned int>(index), slice)); + orthanc_->GetBinaryAsync(uri, IWebService::HttpHeaders(), + new OrthancStone::Callable<OrthancSlicesLoader, + OrthancApiClient::BinaryResponseReadyMessage> + (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceRawImage), + new OrthancStone::Callable<OrthancSlicesLoader, + IWebService::HttpRequestErrorMessage> + (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError), + Operation::DownloadSliceRawImage( + static_cast<unsigned int>(index), slice)); } } }
--- a/Framework/Deprecated/Toolbox/OrthancSlicesLoader.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Toolbox/OrthancSlicesLoader.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,6 +22,7 @@ #pragma once #include "../../Messages/IObservable.h" +#include "../../Messages/ObserverBase.h" #include "../../StoneEnumerations.h" #include "../../Toolbox/SlicesSorter.h" #include "IWebService.h" @@ -33,7 +34,9 @@ namespace Deprecated { - class OrthancSlicesLoader : public OrthancStone::IObservable, public OrthancStone::IObserver + class OrthancSlicesLoader : + public OrthancStone::IObservable, + public OrthancStone::ObserverBase<OrthancSlicesLoader> { public: ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, SliceGeometryReadyMessage, OrthancSlicesLoader); @@ -143,7 +146,7 @@ class Operation; - OrthancApiClient& orthanc_; + boost::shared_ptr<OrthancApiClient> orthanc_; State state_; OrthancStone::SlicesSorter slices_; @@ -183,9 +186,8 @@ void SortAndFinalizeSlices(); public: - OrthancSlicesLoader(OrthancStone::MessageBroker& broker, - //ISliceLoaderObserver& callback, - OrthancApiClient& orthancApi); + OrthancSlicesLoader(//ISliceLoaderObserver& callback, + boost::shared_ptr<OrthancApiClient> orthancApi); void ScheduleLoadSeries(const std::string& seriesId);
--- a/Framework/Deprecated/Viewport/IViewport.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Viewport/IViewport.h Wed Oct 23 11:04:47 2019 +0200 @@ -37,15 +37,6 @@ public: ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ViewportChangedMessage, IViewport); - IViewport(OrthancStone::MessageBroker& broker) : - IObservable(broker) - { - } - - virtual ~IViewport() - { - } - virtual void FitContent() = 0; virtual void SetStatusBar(IStatusBar& statusBar) = 0;
--- a/Framework/Deprecated/Viewport/WidgetViewport.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Viewport/WidgetViewport.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,8 +26,7 @@ namespace Deprecated { - WidgetViewport::WidgetViewport(OrthancStone::MessageBroker& broker) : - IViewport(broker), + WidgetViewport::WidgetViewport() : statusBar_(NULL), isMouseOver_(false), lastMouseX_(0), @@ -57,7 +56,7 @@ } - IWidget& WidgetViewport::SetCentralWidget(IWidget* widget) + void WidgetViewport::SetCentralWidget(boost::shared_ptr<IWidget> widget) { if (widget == NULL) { @@ -66,7 +65,7 @@ mouseTracker_.reset(NULL); - centralWidget_.reset(widget); + centralWidget_ = widget; centralWidget_->SetViewport(*this); if (statusBar_ != NULL) @@ -75,8 +74,6 @@ } NotifyBackgroundChanged(); - - return *widget; }
--- a/Framework/Deprecated/Viewport/WidgetViewport.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Viewport/WidgetViewport.h Wed Oct 23 11:04:47 2019 +0200 @@ -31,7 +31,7 @@ class WidgetViewport : public IViewport { private: - std::auto_ptr<IWidget> centralWidget_; + boost::shared_ptr<IWidget> centralWidget_; IStatusBar* statusBar_; std::auto_ptr<IMouseTracker> mouseTracker_; bool isMouseOver_; @@ -41,13 +41,13 @@ bool backgroundChanged_; public: - WidgetViewport(OrthancStone::MessageBroker& broker); + WidgetViewport(); virtual void FitContent(); virtual void SetStatusBar(IStatusBar& statusBar); - IWidget& SetCentralWidget(IWidget* widget); // Takes ownership + void SetCentralWidget(boost::shared_ptr<IWidget> widget); virtual void NotifyBackgroundChanged();
--- a/Framework/Deprecated/Volumes/ISlicedVolume.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Volumes/ISlicedVolume.h Wed Oct 23 11:04:47 2019 +0200 @@ -65,11 +65,6 @@ }; - ISlicedVolume(OrthancStone::MessageBroker& broker) : - IObservable(broker) - { - } - virtual size_t GetSliceCount() const = 0; virtual const Slice& GetSlice(size_t slice) const = 0;
--- a/Framework/Deprecated/Volumes/IVolumeLoader.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Volumes/IVolumeLoader.h Wed Oct 23 11:04:47 2019 +0200 @@ -31,10 +31,5 @@ ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryReadyMessage, IVolumeLoader); ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryErrorMessage, IVolumeLoader); ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ContentChangedMessage, IVolumeLoader); - - IVolumeLoader(OrthancStone::MessageBroker& broker) : - IObservable(broker) - { - } }; }
--- a/Framework/Deprecated/Volumes/StructureSetLoader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Volumes/StructureSetLoader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -27,10 +27,7 @@ namespace Deprecated { - StructureSetLoader::StructureSetLoader(OrthancStone::MessageBroker& broker, - OrthancApiClient& orthanc) : - IVolumeLoader(broker), - IObserver(broker), + StructureSetLoader::StructureSetLoader(OrthancApiClient& orthanc) : orthanc_(orthanc) { } @@ -60,7 +57,7 @@ it != instances.end(); ++it) { orthanc_.PostBinaryAsyncExpectJson("/tools/lookup", *it, - new OrthancStone::Callable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(*this, &StructureSetLoader::OnLookupCompleted)); + new OrthancStone::Callable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &StructureSetLoader::OnLookupCompleted)); } BroadcastMessage(GeometryReadyMessage(*this)); @@ -84,7 +81,7 @@ const std::string& instance = lookup[0]["ID"].asString(); orthanc_.GetJsonAsync("/instances/" + instance + "/tags", - new OrthancStone::Callable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(*this, &StructureSetLoader::OnReferencedSliceLoaded)); + new OrthancStone::Callable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &StructureSetLoader::OnReferencedSliceLoaded)); } @@ -97,7 +94,7 @@ else { orthanc_.GetJsonAsync("/instances/" + instance + "/tags?ignore-length=3006-0050", - new OrthancStone::Callable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(*this, &StructureSetLoader::OnStructureSetLoaded)); + new OrthancStone::Callable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &StructureSetLoader::OnStructureSetLoaded)); } }
--- a/Framework/Deprecated/Volumes/StructureSetLoader.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Volumes/StructureSetLoader.h Wed Oct 23 11:04:47 2019 +0200 @@ -21,6 +21,7 @@ #pragma once +#include "../../Messages/ObserverBase.h" #include "../../Toolbox/DicomStructureSet.h" #include "../Toolbox/OrthancApiClient.h" #include "IVolumeLoader.h" @@ -29,7 +30,7 @@ { class StructureSetLoader : public IVolumeLoader, - public OrthancStone::IObserver + public OrthancStone::ObserverBase<StructureSetLoader> { private: OrthancApiClient& orthanc_; @@ -42,8 +43,7 @@ void OnLookupCompleted(const OrthancApiClient::JsonResponseReadyMessage& message); public: - StructureSetLoader(OrthancStone::MessageBroker& broker, - OrthancApiClient& orthanc); + StructureSetLoader(OrthancApiClient& orthanc); void ScheduleLoadInstance(const std::string& instance);
--- a/Framework/Deprecated/Widgets/LayoutWidget.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Widgets/LayoutWidget.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -85,14 +85,14 @@ class LayoutWidget::ChildWidget : public boost::noncopyable { private: - std::auto_ptr<IWidget> widget_; + boost::shared_ptr<IWidget> widget_; int left_; int top_; unsigned int width_; unsigned int height_; public: - ChildWidget(IWidget* widget) : + ChildWidget(boost::shared_ptr<IWidget> widget) : widget_(widget) { assert(widget != NULL); @@ -354,7 +354,7 @@ } - IWidget& LayoutWidget::AddWidget(IWidget* widget) // Takes ownership + void LayoutWidget::AddWidget(boost::shared_ptr<IWidget> widget) // Takes ownership { if (widget == NULL) { @@ -375,8 +375,6 @@ { hasAnimation_ = true; } - - return *widget; }
--- a/Framework/Deprecated/Widgets/LayoutWidget.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Widgets/LayoutWidget.h Wed Oct 23 11:04:47 2019 +0200 @@ -94,7 +94,7 @@ return paddingInternal_; } - IWidget& AddWidget(IWidget* widget); // Takes ownership + void AddWidget(boost::shared_ptr<IWidget> widget); virtual void SetStatusBar(IStatusBar& statusBar);
--- a/Framework/Deprecated/Widgets/SliceViewerWidget.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Widgets/SliceViewerWidget.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -250,7 +250,7 @@ { index = found->second; assert(index < layers_.size() && - layers_[index] == &layer); + layers_[index].get() == &layer); return true; } } @@ -364,42 +364,27 @@ } - SliceViewerWidget::SliceViewerWidget(OrthancStone::MessageBroker& broker, - const std::string& name) : + SliceViewerWidget::SliceViewerWidget(const std::string& name) : WorldSceneWidget(name), - IObserver(broker), - IObservable(broker), started_(false) { SetBackgroundCleared(true); } - SliceViewerWidget::~SliceViewerWidget() - { - for (size_t i = 0; i < layers_.size(); i++) - { - delete layers_[i]; - } - } - void SliceViewerWidget::ObserveLayer(IVolumeSlicer& layer) { - layer.RegisterObserverCallback(new OrthancStone::Callable<SliceViewerWidget, IVolumeSlicer::GeometryReadyMessage> - (*this, &SliceViewerWidget::OnGeometryReady)); - // currently ignore errors layer->RegisterObserverCallback(new Callable<SliceViewerWidget, IVolumeSlicer::GeometryErrorMessage>(*this, &SliceViewerWidget::...)); - layer.RegisterObserverCallback(new OrthancStone::Callable<SliceViewerWidget, IVolumeSlicer::SliceContentChangedMessage> - (*this, &SliceViewerWidget::OnSliceChanged)); - layer.RegisterObserverCallback(new OrthancStone::Callable<SliceViewerWidget, IVolumeSlicer::ContentChangedMessage> - (*this, &SliceViewerWidget::OnContentChanged)); - layer.RegisterObserverCallback(new OrthancStone::Callable<SliceViewerWidget, IVolumeSlicer::LayerReadyMessage> - (*this, &SliceViewerWidget::OnLayerReady)); - layer.RegisterObserverCallback(new OrthancStone::Callable<SliceViewerWidget, IVolumeSlicer::LayerErrorMessage> - (*this, &SliceViewerWidget::OnLayerError)); + // currently ignoring errors of type IVolumeSlicer::GeometryErrorMessage + + Register<IVolumeSlicer::GeometryReadyMessage>(layer, &SliceViewerWidget::OnGeometryReady); + Register<IVolumeSlicer::SliceContentChangedMessage>(layer, &SliceViewerWidget::OnSliceChanged); + Register<IVolumeSlicer::ContentChangedMessage>(layer, &SliceViewerWidget::OnContentChanged); + Register<IVolumeSlicer::LayerReadyMessage>(layer, &SliceViewerWidget::OnLayerReady); + Register<IVolumeSlicer::LayerErrorMessage>(layer, &SliceViewerWidget::OnLayerError); } - size_t SliceViewerWidget::AddLayer(IVolumeSlicer* layer) // Takes ownership + size_t SliceViewerWidget::AddLayer(boost::shared_ptr<IVolumeSlicer> layer) { if (layer == NULL) { @@ -409,7 +394,7 @@ size_t index = layers_.size(); layers_.push_back(layer); styles_.push_back(RenderStyle()); - layersIndex_[layer] = index; + layersIndex_[layer.get()] = index; ResetPendingScene(); @@ -421,7 +406,8 @@ } - void SliceViewerWidget::ReplaceLayer(size_t index, IVolumeSlicer* layer) // Takes ownership + void SliceViewerWidget::ReplaceLayer(size_t index, + boost::shared_ptr<IVolumeSlicer> layer) { if (layer == NULL) { @@ -433,9 +419,8 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - delete layers_[index]; layers_[index] = layer; - layersIndex_[layer] = index; + layersIndex_[layer.get()] = index; ResetPendingScene(); @@ -452,13 +437,13 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - IVolumeSlicer* previousLayer = layers_[index]; + IVolumeSlicer* previousLayer = layers_[index].get(); layersIndex_.erase(layersIndex_.find(previousLayer)); layers_.erase(layers_.begin() + index); changedLayers_.erase(changedLayers_.begin() + index); styles_.erase(styles_.begin() + index); - delete layers_[index]; + layers_[index].reset(); currentScene_->DeleteLayer(index); ResetPendingScene();
--- a/Framework/Deprecated/Widgets/SliceViewerWidget.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Deprecated/Widgets/SliceViewerWidget.h Wed Oct 23 11:04:47 2019 +0200 @@ -24,7 +24,7 @@ #include "WorldSceneWidget.h" #include "../Layers/IVolumeSlicer.h" #include "../../Toolbox/Extent2D.h" -#include "../../Messages/IObserver.h" +#include "../../Messages/ObserverBase.h" #include <map> @@ -32,7 +32,7 @@ { class SliceViewerWidget : public WorldSceneWidget, - public OrthancStone::IObserver, + public OrthancStone::ObserverBase<SliceViewerWidget>, public OrthancStone::IObservable { public: @@ -72,7 +72,7 @@ bool started_; LayersIndex layersIndex_; - std::vector<IVolumeSlicer*> layers_; + std::vector<boost::shared_ptr<IVolumeSlicer> > layers_; std::vector<RenderStyle> styles_; OrthancStone::CoordinateSystem3D plane_; std::auto_ptr<Scene> currentScene_; @@ -100,8 +100,7 @@ void ResetChangedLayers(); public: - SliceViewerWidget(OrthancStone::MessageBroker& broker, - const std::string& name); + SliceViewerWidget(const std::string& name); virtual OrthancStone::Extent2D GetSceneExtent(); @@ -120,11 +119,13 @@ void InvalidateLayer(size_t layer); public: - virtual ~SliceViewerWidget(); + virtual ~SliceViewerWidget() + { + } - size_t AddLayer(IVolumeSlicer* layer); // Takes ownership + size_t AddLayer(boost::shared_ptr<IVolumeSlicer> layer); - void ReplaceLayer(size_t layerIndex, IVolumeSlicer* layer); // Takes ownership + void ReplaceLayer(size_t layerIndex, boost::shared_ptr<IVolumeSlicer> layer); // Takes ownership void RemoveLayer(size_t layerIndex);
--- a/Framework/Loaders/DicomStructureSetLoader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Loaders/DicomStructureSetLoader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -347,7 +347,6 @@ DicomStructureSetLoader::DicomStructureSetLoader(IOracle& oracle, IObservable& oracleObservable) : LoaderStateMachine(oracle, oracleObservable), - IObservable(oracleObservable.GetBroker()), revision_(0), countProcessedInstances_(0), countReferencedInstances_(0),
--- a/Framework/Loaders/LoaderStateMachine.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Loaders/LoaderStateMachine.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -97,7 +97,8 @@ ") < simultaneousDownloads_ (" << simultaneousDownloads_ << ") --> will Schedule command addr " << std::hex << nextCommand << std::dec; - oracle_.Schedule(*this, nextCommand); + boost::shared_ptr<IObserver> observer(GetSharedObserver()); + oracle_.Schedule(observer, nextCommand); pendingCommands_.pop_front(); activeCommands_++; @@ -136,7 +137,6 @@ template <typename T> void LoaderStateMachine::HandleSuccessMessage(const T& message) { - LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage(). Receiver fingerprint = " << GetFingerprint(); if (activeCommands_ <= 0) { LOG(ERROR) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage : activeCommands_ should be > 0 but is: " << activeCommands_; } @@ -159,35 +159,22 @@ LoaderStateMachine::LoaderStateMachine(IOracle& oracle, IObservable& oracleObservable) : - IObserver(oracleObservable.GetBroker()), oracle_(oracle), - oracleObservable_(oracleObservable), active_(false), simultaneousDownloads_(4), activeCommands_(0) { LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::LoaderStateMachine()"; - oracleObservable.RegisterObserverCallback( - new Callable<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage> - (*this, &LoaderStateMachine::HandleSuccessMessage)); - - oracleObservable.RegisterObserverCallback( - new Callable<LoaderStateMachine, GetOrthancImageCommand::SuccessMessage> - (*this, &LoaderStateMachine::HandleSuccessMessage)); - - oracleObservable.RegisterObserverCallback( - new Callable<LoaderStateMachine, GetOrthancWebViewerJpegCommand::SuccessMessage> - (*this, &LoaderStateMachine::HandleSuccessMessage)); - - oracleObservable.RegisterObserverCallback( - new Callable<LoaderStateMachine, OracleCommandExceptionMessage> - (*this, &LoaderStateMachine::HandleExceptionMessage)); + // TODO => Move this out of constructor + Register<OrthancRestApiCommand::SuccessMessage>(oracleObservable, &LoaderStateMachine::HandleSuccessMessage); + Register<GetOrthancImageCommand::SuccessMessage>(oracleObservable, &LoaderStateMachine::HandleSuccessMessage); + Register<GetOrthancWebViewerJpegCommand::SuccessMessage>(oracleObservable, &LoaderStateMachine::HandleSuccessMessage); + Register<OracleCommandExceptionMessage>(oracleObservable, &LoaderStateMachine::HandleExceptionMessage); } LoaderStateMachine::~LoaderStateMachine() { - oracleObservable_.Unregister(this); LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::~LoaderStateMachine()"; Clear(); }
--- a/Framework/Loaders/LoaderStateMachine.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Loaders/LoaderStateMachine.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,7 +22,7 @@ #pragma once #include "../Messages/IObservable.h" -#include "../Messages/IObserver.h" +#include "../Messages/ObserverBase.h" #include "../Oracle/GetOrthancImageCommand.h" #include "../Oracle/GetOrthancWebViewerJpegCommand.h" #include "../Oracle/IOracle.h" @@ -41,7 +41,7 @@ rest once slots become available. It is used, a.o., by the OrtancMultiframeVolumeLoader class. */ - class LoaderStateMachine : public IObserver + class LoaderStateMachine : public ObserverBase<LoaderStateMachine> { protected: class State : public Orthanc::IDynamicObject @@ -95,7 +95,6 @@ typedef std::list<IOracleCommand*> PendingCommands; IOracle& oracle_; - IObservable& oracleObservable_; bool active_; unsigned int simultaneousDownloads_; PendingCommands pendingCommands_;
--- a/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -335,7 +335,6 @@ IOracle& oracle, IObservable& oracleObservable) : LoaderStateMachine(oracle, oracleObservable), - IObservable(oracleObservable.GetBroker()), volume_(volume), pixelDataLoaded_(false) {
--- a/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -292,7 +292,9 @@ } command->SetPayload(new Orthanc::SingleValueObject<unsigned int>(sliceIndex)); - oracle_.Schedule(*this, command.release()); + + boost::shared_ptr<IObserver> observer(GetSharedObserver()); + oracle_.Schedule(observer, command.release()); } else { @@ -421,32 +423,26 @@ OrthancSeriesVolumeProgressiveLoader::OrthancSeriesVolumeProgressiveLoader(const boost::shared_ptr<DicomVolumeImage>& volume, IOracle& oracle, IObservable& oracleObservable) : - IObserver(oracleObservable.GetBroker()), - IObservable(oracleObservable.GetBroker()), oracle_(oracle), - oracleObservable_(oracleObservable), active_(false), simultaneousDownloads_(4), volume_(volume), sorter_(new BasicFetchingItemsSorter::Factory), volumeImageReadyInHighQuality_(false) { - oracleObservable.RegisterObserverCallback( - new Callable<OrthancSeriesVolumeProgressiveLoader, OrthancRestApiCommand::SuccessMessage> - (*this, &OrthancSeriesVolumeProgressiveLoader::LoadGeometry)); + // TODO => Move this out of constructor + Register<OrthancRestApiCommand::SuccessMessage> + (oracleObservable, &OrthancSeriesVolumeProgressiveLoader::LoadGeometry); - oracleObservable.RegisterObserverCallback( - new Callable<OrthancSeriesVolumeProgressiveLoader, GetOrthancImageCommand::SuccessMessage> - (*this, &OrthancSeriesVolumeProgressiveLoader::LoadBestQualitySliceContent)); + Register<GetOrthancImageCommand::SuccessMessage> + (oracleObservable, &OrthancSeriesVolumeProgressiveLoader::LoadBestQualitySliceContent); - oracleObservable.RegisterObserverCallback( - new Callable<OrthancSeriesVolumeProgressiveLoader, GetOrthancWebViewerJpegCommand::SuccessMessage> - (*this, &OrthancSeriesVolumeProgressiveLoader::LoadJpegSliceContent)); + Register<GetOrthancWebViewerJpegCommand::SuccessMessage> + (oracleObservable, &OrthancSeriesVolumeProgressiveLoader::LoadJpegSliceContent); } OrthancSeriesVolumeProgressiveLoader::~OrthancSeriesVolumeProgressiveLoader() { - oracleObservable_.Unregister(this); LOG(TRACE) << "OrthancSeriesVolumeProgressiveLoader::~OrthancSeriesVolumeProgressiveLoader()"; } @@ -485,7 +481,8 @@ command->SetUri("/series/" + seriesId + "/instances-tags"); // LOG(TRACE) << "OrthancSeriesVolumeProgressiveLoader::LoadSeries about to call oracle_.Schedule"; - oracle_.Schedule(*this, command.release()); + boost::shared_ptr<IObserver> observer(GetSharedObserver()); + oracle_.Schedule(observer, command.release()); // LOG(TRACE) << "OrthancSeriesVolumeProgressiveLoader::LoadSeries called oracle_.Schedule"; } }
--- a/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,7 +22,7 @@ #pragma once #include "../Messages/IObservable.h" -#include "../Messages/IObserver.h" +#include "../Messages/ObserverBase.h" #include "../Oracle/GetOrthancImageCommand.h" #include "../Oracle/GetOrthancWebViewerJpegCommand.h" #include "../Oracle/IOracle.h" @@ -42,7 +42,7 @@ is stored in a Dicom series. */ class OrthancSeriesVolumeProgressiveLoader : - public IObserver, + public ObserverBase<OrthancSeriesVolumeProgressiveLoader>, public IObservable, public IVolumeSlicer, public IGeometryProvider @@ -106,7 +106,6 @@ void LoadJpegSliceContent(const GetOrthancWebViewerJpegCommand::SuccessMessage& message); IOracle& oracle_; - IObservable& oracleObservable_; bool active_; unsigned int simultaneousDownloads_; SeriesGeometry seriesGeometry_;
--- a/Framework/Messages/ICallable.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/ICallable.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,20 +22,20 @@ #pragma once #include "IMessage.h" +#include "IObserver.h" #include <Core/Logging.h> #include <boost/noncopyable.hpp> +#include <boost/weak_ptr.hpp> #include <string> -namespace OrthancStone { - - class IObserver; - +namespace OrthancStone +{ // This is referencing an object and member function that can be notified // by an IObservable. The object must derive from IO - // The member functions must be of type "void Function(const IMessage& message)" or reference a derived class of IMessage + // The member functions must be of type "void Method(const IMessage& message)" or reference a derived class of IMessage class ICallable : public boost::noncopyable { public: @@ -47,11 +47,14 @@ virtual const MessageIdentifier& GetMessageIdentifier() = 0; - virtual IObserver* GetObserver() const = 0; + // TODO - Is this needed? + virtual boost::weak_ptr<IObserver> GetObserver() const = 0; }; + + // TODO - Remove this class template <typename TMessage> - class MessageHandler: public ICallable + class MessageHandler : public ICallable { }; @@ -61,47 +64,28 @@ class Callable : public MessageHandler<TMessage> { private: - typedef void (TObserver::* MemberFunction) (const TMessage&); + typedef void (TObserver::* MemberMethod) (const TMessage&); - TObserver& observer_; - MemberFunction function_; - std::string observerFingerprint_; + boost::weak_ptr<IObserver> observer_; + MemberMethod function_; public: - Callable(TObserver& observer, - MemberFunction function) : + Callable(boost::shared_ptr<TObserver> observer, + MemberMethod function) : observer_(observer), - function_(function), - observerFingerprint_(observer.GetFingerprint()) - { - } - - void ApplyInternal(const TMessage& message) + function_(function) { - std::string currentFingerprint(observer_.GetFingerprint()); - if (observerFingerprint_ != currentFingerprint) - { - LOG(TRACE) << "The observer at address " << - std::hex << &observer_ << std::dec << - ") has a different fingerprint than the one recorded at callback " << - "registration time. This means that it is not the same object as " << - "the one recorded, even though their addresses are the same. " << - "Callback will NOT be sent!"; - LOG(TRACE) << " recorded fingerprint = " << observerFingerprint_ << - " current fingerprint = " << currentFingerprint; - } - else - { - LOG(TRACE) << "The recorded fingerprint is " << observerFingerprint_ - << " and the current fingerprint is " << currentFingerprint - << " -- callable will be called."; - (observer_.*function_) (message); - } } virtual void Apply(const IMessage& message) { - ApplyInternal(dynamic_cast<const TMessage&>(message)); + boost::shared_ptr<IObserver> lock(observer_); + if (lock) + { + TObserver& observer = dynamic_cast<TObserver&>(*lock); + const TMessage& typedMessage = dynamic_cast<const TMessage&>(message); + (observer.*function_) (typedMessage); + } } virtual const MessageIdentifier& GetMessageIdentifier() @@ -109,41 +93,9 @@ return TMessage::GetStaticIdentifier(); } - virtual IObserver* GetObserver() const + virtual boost::weak_ptr<IObserver> GetObserver() const { - return &observer_; + return observer_; } }; - -#if 0 /* __cplusplus >= 201103L*/ - -#include <functional> - - template <typename TMessage> - class LambdaCallable : public MessageHandler<TMessage> - { - private: - - IObserver& observer_; - std::function<void (const TMessage&)> lambda_; - - public: - LambdaCallable(IObserver& observer, - std::function<void (const TMessage&)> lambdaFunction) : - observer_(observer), - lambda_(lambdaFunction) - { - } - - virtual void Apply(const IMessage& message) - { - lambda_(dynamic_cast<const TMessage&>(message)); - } - - virtual IObserver* GetObserver() const - { - return &observer_; - } - }; -#endif //__cplusplus >= 201103L }
--- a/Framework/Messages/IMessage.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/IMessage.h Wed Oct 23 11:04:47 2019 +0200 @@ -33,6 +33,12 @@ const char* file_; int line_; + bool IsEqual(const MessageIdentifier& other) const + { + return (line_ == other.line_ && + strcmp(file_, other.file_) == 0); + } + public: MessageIdentifier(const char* file, int line) : @@ -62,6 +68,16 @@ return strcmp(file_, other.file_) < 0; } } + + bool operator== (const MessageIdentifier& other) const + { + return IsEqual(other); + } + + bool operator!= (const MessageIdentifier& other) const + { + return !IsEqual(other); + } };
--- a/Framework/Messages/IMessageEmitter.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/IMessageEmitter.h Wed Oct 23 11:04:47 2019 +0200 @@ -24,6 +24,8 @@ #include "IObserver.h" #include "IMessage.h" +#include <boost/weak_ptr.hpp> + namespace OrthancStone { /** @@ -39,7 +41,7 @@ { } - virtual void EmitMessage(const IObserver& observer, + virtual void EmitMessage(boost::weak_ptr<IObserver>& observer, const IMessage& message) = 0; }; }
--- a/Framework/Messages/IObservable.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/IObservable.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -40,20 +40,10 @@ delete *it2; } } - - // unregister the forwarders but don't delete them (they'll be - // deleted by the observable they are observing as any other - // callable) - for (Forwarders::iterator it = forwarders_.begin(); - it != forwarders_.end(); ++it) - { - IMessageForwarder* fw = *it; - broker_.Unregister(dynamic_cast<IObserver&>(*fw)); - } } - void IObservable::RegisterObserverCallback(ICallable* callable) + void IObservable::RegisterCallable(ICallable* callable) { if (callable == NULL) { @@ -64,30 +54,6 @@ callables_[id].insert(callable); } - void IObservable::Unregister(IObserver *observer) - { - LOG(TRACE) << "IObservable::Unregister for IObserver at addr: " - << std::hex << observer << std::dec; - // delete all callables from this observer - for (Callables::iterator itCallableSet = callables_.begin(); - itCallableSet != callables_.end(); ++itCallableSet) - { - for (std::set<ICallable*>::const_iterator - itCallable = itCallableSet->second.begin(); itCallable != itCallableSet->second.end(); ) - { - if ((*itCallable)->GetObserver() == observer) - { - LOG(TRACE) << " ** IObservable::Unregister : deleting callable: " - << std::hex << (*itCallable) << std::dec; - delete *itCallable; - itCallableSet->second.erase(itCallable++); - } - else - ++itCallable; - } - } - } - void IObservable::EmitMessageInternal(const IObserver* receiver, const IMessage& message) { @@ -102,15 +68,21 @@ { assert(*it != NULL); - const IObserver* observer = (*it)->GetObserver(); - if (broker_.IsActive(*observer)) + boost::shared_ptr<IObserver> observer((*it)->GetObserver().lock()); + + if (observer) { if (receiver == NULL || // Are we broadcasting? - observer == receiver) // Not broadcasting, but this is the receiver + observer.get() == receiver) // Not broadcasting, but this is the receiver { (*it)->Apply(message); } } + else + { + // TODO => Remove "it" from the list of callables => This + // allows to suppress the need for "Unregister()" + } } } } @@ -122,21 +94,16 @@ } - void IObservable::EmitMessage(const IObserver& observer, + void IObservable::EmitMessage(boost::weak_ptr<IObserver>& observer, const IMessage& message) { LOG(TRACE) << "IObservable::EmitMessage observer = " << std::hex << &observer << std::dec; - EmitMessageInternal(&observer, message); - } - - void IObservable::RegisterForwarder(IMessageForwarder* forwarder) - { - if (forwarder == NULL) + + boost::shared_ptr<IObserver> lock(observer.lock()); + if (lock) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + EmitMessageInternal(lock.get(), message); } - - forwarders_.insert(forwarder); } }
--- a/Framework/Messages/IObservable.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/IObservable.h Wed Oct 23 11:04:47 2019 +0200 @@ -24,8 +24,6 @@ #include "../StoneEnumerations.h" #include "ICallable.h" #include "IObserver.h" -#include "MessageBroker.h" -#include "MessageForwarder.h" #include <set> #include <map> @@ -37,39 +35,20 @@ private: typedef std::map<MessageIdentifier, std::set<ICallable*> > Callables; - typedef std::set<IMessageForwarder*> Forwarders; - - MessageBroker& broker_; Callables callables_; - Forwarders forwarders_; void EmitMessageInternal(const IObserver* receiver, const IMessage& message); public: - IObservable(MessageBroker& broker) : - broker_(broker) - { - } - virtual ~IObservable(); - MessageBroker& GetBroker() const - { - return broker_; - } - - // Takes ownsership - void RegisterObserverCallback(ICallable* callable); - - void Unregister(IObserver* observer); + // Takes ownsership of the callable + void RegisterCallable(ICallable* callable); void BroadcastMessage(const IMessage& message); - void EmitMessage(const IObserver& observer, + void EmitMessage(boost::weak_ptr<IObserver>& observer, const IMessage& message); - - // Takes ownsership - void RegisterForwarder(IMessageForwarder* forwarder); }; }
--- a/Framework/Messages/IObserver.cpp Tue Oct 22 17:51:25 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "IObserver.h" - -#include "IMessage.h" -#include "../StoneException.h" - -#include <Core/Logging.h> -#include <Core/Toolbox.h> - -namespace OrthancStone -{ - IObserver::IObserver(MessageBroker& broker) - : broker_(broker) - , fingerprint_() - { - // we store the fingerprint_ as a char array to avoid problems when - // reading it in a deceased object. - // remember this is panic-level code to track zombie object usage - std::string fingerprint = Orthanc::Toolbox::GenerateUuid(); - const char* fingerprintRaw = fingerprint.c_str(); - memcpy(fingerprint_, fingerprintRaw, 37); - broker_.Register(*this); - } - - - IObserver::~IObserver() - { - try - { - LOG(TRACE) << "IObserver(" << std::hex << this << std::dec << ")::~IObserver : fingerprint_ == " << fingerprint_; - const char* deadMarker = "deadbeef-dead-dead-0000-0000deadbeef"; - ORTHANC_ASSERT(strlen(deadMarker) == 36); - memcpy(fingerprint_, deadMarker, 37); - broker_.Unregister(*this); - } - catch (const Orthanc::OrthancException& e) - { - if (e.HasDetails()) - { - LOG(ERROR) << "OrthancException in ~IObserver: " << e.What() << " Details: " << e.GetDetails(); - } - else - { - LOG(ERROR) << "OrthancException in ~IObserver: " << e.What(); - } - } - catch (const std::exception& e) - { - LOG(ERROR) << "std::exception in ~IObserver: " << e.what(); - } - catch (...) - { - LOG(ERROR) << "Unknown exception in ~IObserver"; - } - } - - - bool IObserver::DoesFingerprintLookGood() const - { - for (size_t i = 0; i < 36; ++i) { - bool ok = false; - if (fingerprint_[i] >= 'a' && fingerprint_[i] <= 'f') - ok = true; - if (fingerprint_[i] >= '0' && fingerprint_[i] <= '9') - ok = true; - if (fingerprint_[i] == '-') - ok = true; - if (!ok) - return false; - } - return fingerprint_[36] == 0; - } -}
--- a/Framework/Messages/IObserver.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/IObserver.h Wed Oct 23 11:04:47 2019 +0200 @@ -21,33 +21,19 @@ #pragma once -#include "MessageBroker.h" +#include <boost/noncopyable.hpp> namespace OrthancStone { class IObserver : public boost::noncopyable { - private: - MessageBroker& broker_; - // the following is a UUID that is used to disambiguate different observers - // that may have the same address - char fingerprint_[37]; - public: - IObserver(MessageBroker& broker); - - virtual ~IObserver(); - - const char* GetFingerprint() const + IObserver() { - return fingerprint_; } - bool DoesFingerprintLookGood() const; - - MessageBroker& GetBroker() const + virtual ~IObserver() { - return broker_; } }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Messages/LockingEmitter.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -0,0 +1,40 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "LockingEmitter.h" + +#include <Core/OrthancException.h> + +namespace OrthancStone +{ + void LockingEmitter::EmitMessage(boost::weak_ptr<IObserver>& observer, + const IMessage& message) + { + try + { + boost::unique_lock<boost::shared_mutex> lock(mutex_); + oracleObservable_.EmitMessage(observer, message); + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "Exception while emitting a message: " << e.What(); + } + } +}
--- a/Framework/Messages/LockingEmitter.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Messages/LockingEmitter.h Wed Oct 23 11:04:47 2019 +0200 @@ -26,7 +26,9 @@ #include "IMessageEmitter.h" #include "IObservable.h" -#include <boost/thread.hpp> +#include <Core/Enumerations.h> // For ORTHANC_OVERRIDE + +#include <boost/thread/shared_mutex.hpp> namespace OrthancStone { @@ -43,33 +45,11 @@ { private: boost::shared_mutex mutex_; - MessageBroker broker_; IObservable oracleObservable_; public: - LockingEmitter() : - oracleObservable_(broker_) - { - } - - MessageBroker& GetBroker() - { - return broker_; - } - - virtual void EmitMessage(const IObserver& observer, - const IMessage& message) ORTHANC_OVERRIDE - { - try - { - boost::unique_lock<boost::shared_mutex> lock(mutex_); - oracleObservable_.EmitMessage(observer, message); - } - catch (Orthanc::OrthancException& e) - { - LOG(ERROR) << "Exception while emitting a message: " << e.What(); - } - } + virtual void EmitMessage(boost::weak_ptr<IObserver>& observer, + const IMessage& message) ORTHANC_OVERRIDE; class ReaderLock : public boost::noncopyable @@ -80,8 +60,8 @@ public: ReaderLock(LockingEmitter& that) : - that_(that), - lock_(that.mutex_) + that_(that), + lock_(that.mutex_) { } }; @@ -95,16 +75,11 @@ public: WriterLock(LockingEmitter& that) : - that_(that), - lock_(that.mutex_) + that_(that), + lock_(that.mutex_) { } - MessageBroker& GetBroker() - { - return that_.broker_; - } - IObservable& GetOracleObservable() { return that_.oracleObservable_;
--- a/Framework/Messages/MessageBroker.h Tue Oct 22 17:51:25 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - -#pragma once - -#include "boost/noncopyable.hpp" - -#include <set> - -namespace OrthancStone -{ - class IObserver; - - /* - * This is a central message broker. It keeps track of all observers and knows - * when an observer is deleted. - * This way, it can prevent an observable to send a message to a deleted observer. - */ - class MessageBroker : public boost::noncopyable - { - private: - std::set<const IObserver*> activeObservers_; // the list of observers that are currently alive (that have not been deleted) - - public: - MessageBroker() - { - } - - void Register(const IObserver& observer) - { - activeObservers_.insert(&observer); - } - - void Unregister(const IObserver& observer) - { - activeObservers_.erase(&observer); - } - - bool IsActive(const IObserver& observer) - { - return activeObservers_.find(&observer) != activeObservers_.end(); - } - }; -}
--- a/Framework/Messages/MessageForwarder.cpp Tue Oct 22 17:51:25 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "MessageForwarder.h" - -#include "IObservable.h" - -namespace OrthancStone -{ - - void IMessageForwarder::ForwardMessageInternal(const IMessage& message) - { - emitter_.BroadcastMessage(message); - } - - void IMessageForwarder::RegisterForwarderInEmitter() - { - emitter_.RegisterForwarder(this); - } -}
--- a/Framework/Messages/MessageForwarder.h Tue Oct 22 17:51:25 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include "ICallable.h" -#include "IObserver.h" - -#include <boost/noncopyable.hpp> - -namespace OrthancStone -{ - - class IObservable; - - class IMessageForwarder : public IObserver - { - IObservable& emitter_; - public: - IMessageForwarder(MessageBroker& broker, IObservable& emitter) - : IObserver(broker), - emitter_(emitter) - {} - virtual ~IMessageForwarder() {} - - protected: - void ForwardMessageInternal(const IMessage& message); - void RegisterForwarderInEmitter(); - - }; - - /* When an Observer (B) simply needs to re-emit a message it has received, instead of implementing - * a specific member function to forward the message, it can create a MessageForwarder. - * The MessageForwarder will re-emit the message "in the name of (B)" - * - * Consider the chain where - * A is an observable - * | - * B is an observer of A and observable - * | - * C is an observer of B and knows that B is re-emitting many messages from A - * - * instead of implementing a callback, B will create a MessageForwarder that will emit the messages in his name: - * A.RegisterObserverCallback(new MessageForwarder<A::MessageType>(broker, *this) // where "this" is B - * - * in C: - * B.RegisterObserverCallback(new Callable<C, A:MessageTyper>(*this, &B::MyCallback)) // where "this" is C - */ - template<typename TMessage> - class MessageForwarder : public IMessageForwarder, public Callable<MessageForwarder<TMessage>, TMessage> - { - public: - MessageForwarder(MessageBroker& broker, - IObservable& emitter // the object that will emit the messages to forward - ) - : IMessageForwarder(broker, emitter), - Callable<MessageForwarder<TMessage>, TMessage>(*this, &MessageForwarder::ForwardMessage) - { - RegisterForwarderInEmitter(); - } - -protected: - void ForwardMessage(const TMessage& message) - { - ForwardMessageInternal(message); - } - - }; -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Messages/ObserverBase.h Wed Oct 23 11:04:47 2019 +0200 @@ -0,0 +1,68 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "ICallable.h" +#include "IObserver.h" +#include "IObservable.h" + +#include <Core/OrthancException.h> + +#include <boost/enable_shared_from_this.hpp> + +namespace OrthancStone +{ + template <typename TObserver> + class ObserverBase : + public IObserver, + public boost::enable_shared_from_this<TObserver> + { + public: + boost::shared_ptr<TObserver> GetSharedObserver() + { + try + { + return this->shared_from_this(); + } + catch (boost::bad_weak_ptr&) + { + throw Orthanc::OrthancException( + Orthanc::ErrorCode_InternalError, + "Cannot get a shared pointer to an observer from its constructor, " + "or the observer is not created as a shared pointer"); + } + } + + template <typename TMessage> + ICallable* CreateCallable(void (TObserver::* MemberMethod) (const TMessage&)) + { + return new Callable<TObserver, TMessage>(GetSharedObserver(), MemberMethod); + } + + template <typename TMessage> + void Register(IObservable& observable, + void (TObserver::* MemberMethod) (const TMessage&)) + { + observable.RegisterCallable(CreateCallable(MemberMethod)); + } + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Oracle/CustomOracleCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -0,0 +1,40 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "IOracleRunner.h" + +namespace OrthancStone +{ + class CustomOracleCommand : public IOracleCommand + { + public: + virtual Type GetType() const + { + return Type_Custom; + } + + virtual void Execute(IMessageEmitter& emitter, + boost::weak_ptr<IObserver>& receiver, + IOracleRunner& runner) = 0; + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Oracle/GenericOracleRunner.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -0,0 +1,239 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "GenericOracleRunner.h" + +#include "CustomOracleCommand.h" +#include "GetOrthancImageCommand.h" +#include "GetOrthancWebViewerJpegCommand.h" +#include "HttpCommand.h" +#include "OracleCommandExceptionMessage.h" +#include "OrthancRestApiCommand.h" + +#include <Core/Compression/GzipCompressor.h> +#include <Core/HttpClient.h> +#include <Core/OrthancException.h> +#include <Core/Toolbox.h> + +namespace OrthancStone +{ + static void CopyHttpHeaders(Orthanc::HttpClient& client, + const Orthanc::HttpClient::HttpHeaders& headers) + { + for (Orthanc::HttpClient::HttpHeaders::const_iterator + it = headers.begin(); it != headers.end(); it++ ) + { + client.AddHeader(it->first, it->second); + } + } + + + static void DecodeAnswer(std::string& answer, + const Orthanc::HttpClient::HttpHeaders& headers) + { + Orthanc::HttpCompression contentEncoding = Orthanc::HttpCompression_None; + + for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); + it != headers.end(); ++it) + { + std::string s; + Orthanc::Toolbox::ToLowerCase(s, it->first); + + if (s == "content-encoding") + { + if (it->second == "gzip") + { + contentEncoding = Orthanc::HttpCompression_Gzip; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, + "Unsupported HTTP Content-Encoding: " + it->second); + } + + break; + } + } + + if (contentEncoding == Orthanc::HttpCompression_Gzip) + { + std::string compressed; + answer.swap(compressed); + + Orthanc::GzipCompressor compressor; + compressor.Uncompress(answer, compressed.c_str(), compressed.size()); + + LOG(INFO) << "Uncompressing gzip Encoding: from " << compressed.size() + << " to " << answer.size() << " bytes"; + } + } + + + static void Execute(IMessageEmitter& emitter, + boost::weak_ptr<IObserver>& receiver, + const HttpCommand& command) + { + Orthanc::HttpClient client; + client.SetUrl(command.GetUrl()); + client.SetMethod(command.GetMethod()); + client.SetTimeout(command.GetTimeout()); + + CopyHttpHeaders(client, command.GetHttpHeaders()); + + if (command.HasCredentials()) + { + client.SetCredentials(command.GetUsername().c_str(), command.GetPassword().c_str()); + } + + if (command.GetMethod() == Orthanc::HttpMethod_Post || + command.GetMethod() == Orthanc::HttpMethod_Put) + { + client.SetBody(command.GetBody()); + } + + std::string answer; + Orthanc::HttpClient::HttpHeaders answerHeaders; + client.ApplyAndThrowException(answer, answerHeaders); + + DecodeAnswer(answer, answerHeaders); + + HttpCommand::SuccessMessage message(command, answerHeaders, answer); + emitter.EmitMessage(receiver, message); + } + + + static void Execute(IMessageEmitter& emitter, + const Orthanc::WebServiceParameters& orthanc, + boost::weak_ptr<IObserver>& receiver, + const OrthancRestApiCommand& command) + { + Orthanc::HttpClient client(orthanc, command.GetUri()); + client.SetMethod(command.GetMethod()); + client.SetTimeout(command.GetTimeout()); + + CopyHttpHeaders(client, command.GetHttpHeaders()); + + if (command.GetMethod() == Orthanc::HttpMethod_Post || + command.GetMethod() == Orthanc::HttpMethod_Put) + { + client.SetBody(command.GetBody()); + } + + std::string answer; + Orthanc::HttpClient::HttpHeaders answerHeaders; + client.ApplyAndThrowException(answer, answerHeaders); + + DecodeAnswer(answer, answerHeaders); + + OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); + emitter.EmitMessage(receiver, message); + } + + + static void Execute(IMessageEmitter& emitter, + const Orthanc::WebServiceParameters& orthanc, + boost::weak_ptr<IObserver>& receiver, + const GetOrthancImageCommand& command) + { + Orthanc::HttpClient client(orthanc, command.GetUri()); + client.SetTimeout(command.GetTimeout()); + + CopyHttpHeaders(client, command.GetHttpHeaders()); + + std::string answer; + Orthanc::HttpClient::HttpHeaders answerHeaders; + client.ApplyAndThrowException(answer, answerHeaders); + + DecodeAnswer(answer, answerHeaders); + + command.ProcessHttpAnswer(emitter, receiver, answer, answerHeaders); + } + + + static void Execute(IMessageEmitter& emitter, + const Orthanc::WebServiceParameters& orthanc, + boost::weak_ptr<IObserver>& receiver, + const GetOrthancWebViewerJpegCommand& command) + { + Orthanc::HttpClient client(orthanc, command.GetUri()); + client.SetTimeout(command.GetTimeout()); + + CopyHttpHeaders(client, command.GetHttpHeaders()); + + std::string answer; + Orthanc::HttpClient::HttpHeaders answerHeaders; + client.ApplyAndThrowException(answer, answerHeaders); + + DecodeAnswer(answer, answerHeaders); + + command.ProcessHttpAnswer(emitter, receiver, answer); + } + + + void GenericOracleRunner::Run(boost::weak_ptr<IObserver>& receiver, + IOracleCommand& command) + { + try + { + switch (command.GetType()) + { + case IOracleCommand::Type_Sleep: + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadParameterType, + "Sleep command cannot be executed by the runner"); + break; + + case IOracleCommand::Type_Http: + Execute(emitter_, receiver, dynamic_cast<const HttpCommand&>(command)); + break; + + case IOracleCommand::Type_OrthancRestApi: + Execute(emitter_, orthanc_, receiver, dynamic_cast<const OrthancRestApiCommand&>(command)); + break; + + case IOracleCommand::Type_GetOrthancImage: + Execute(emitter_, orthanc_, receiver, dynamic_cast<const GetOrthancImageCommand&>(command)); + break; + + case IOracleCommand::Type_GetOrthancWebViewerJpeg: + Execute(emitter_, orthanc_, receiver, dynamic_cast<const GetOrthancWebViewerJpegCommand&>(command)); + break; + + case IOracleCommand::Type_Custom: + dynamic_cast<CustomOracleCommand&>(command).Execute(emitter_, receiver, *this); + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "Exception within the oracle: " << e.What(); + emitter_.EmitMessage(receiver, OracleCommandExceptionMessage(command, e)); + } + catch (...) + { + LOG(ERROR) << "Threaded exception within the oracle"; + emitter_.EmitMessage(receiver, OracleCommandExceptionMessage + (command, Orthanc::ErrorCode_InternalError)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Oracle/GenericOracleRunner.h Wed Oct 23 11:04:47 2019 +0200 @@ -0,0 +1,49 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "../Messages/IMessageEmitter.h" +#include "IOracleRunner.h" + +#include <Core/Enumerations.h> // For ORTHANC_OVERRIDE +#include <Core/WebServiceParameters.h> + +namespace OrthancStone +{ + class GenericOracleRunner : public IOracleRunner + { + private: + IMessageEmitter& emitter_; + const Orthanc::WebServiceParameters& orthanc_; + + public: + GenericOracleRunner(IMessageEmitter& emitter, + const Orthanc::WebServiceParameters& orthanc) : + emitter_(emitter), + orthanc_(orthanc) + { + } + + virtual void Run(boost::weak_ptr<IObserver>& receiver, + IOracleCommand& command) ORTHANC_OVERRIDE; + }; +}
--- a/Framework/Oracle/GetOrthancImageCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/GetOrthancImageCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -83,7 +83,7 @@ } void GetOrthancImageCommand::ProcessHttpAnswer(IMessageEmitter& emitter, - const IObserver& receiver, + boost::weak_ptr<IObserver>& receiver, const std::string& answer, const HttpHeaders& answerHeaders) const {
--- a/Framework/Oracle/GetOrthancImageCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/GetOrthancImageCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -112,7 +112,7 @@ } void ProcessHttpAnswer(IMessageEmitter& emitter, - const IObserver& receiver, + boost::weak_ptr<IObserver>& receiver, const std::string& answer, const HttpHeaders& answerHeaders) const; };
--- a/Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -77,7 +77,7 @@ void GetOrthancWebViewerJpegCommand::ProcessHttpAnswer(IMessageEmitter& emitter, - const IObserver& receiver, + boost::weak_ptr<IObserver>& receiver, const std::string& answer) const { // This code comes from older "OrthancSlicesLoader::ParseSliceImageJpeg()"
--- a/Framework/Oracle/GetOrthancWebViewerJpegCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/GetOrthancWebViewerJpegCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -129,7 +129,7 @@ std::string GetUri() const; void ProcessHttpAnswer(IMessageEmitter& emitter, - const IObserver& receiver, + boost::weak_ptr<IObserver>& receiver, const std::string& answer) const; }; }
--- a/Framework/Oracle/HttpCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/HttpCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -76,4 +76,30 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } + + + const std::string& HttpCommand::GetUsername() const + { + if (HasCredentials()) + { + return username_; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + } + + + const std::string& HttpCommand::GetPassword() const + { + if (HasCredentials()) + { + return password_; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + } }
--- a/Framework/Oracle/HttpCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/HttpCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -69,6 +69,8 @@ std::string body_; HttpHeaders headers_; unsigned int timeout_; + std::string username_; + std::string password_; public: HttpCommand(); @@ -137,5 +139,27 @@ { return timeout_; } + + void SetCredentials(const std::string& username, + const std::string& password) + { + username_ = username; + password_ = password; + } + + void ClearCredentials() + { + username_.clear(); + password_.clear(); + } + + bool HasCredentials() const + { + return !username_.empty(); + } + + const std::string& GetUsername() const; + + const std::string& GetPassword() const; }; }
--- a/Framework/Oracle/IOracle.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/IOracle.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,7 +22,9 @@ #pragma once #include "../Messages/IObserver.h" -#include "IOracleCommand.h" +#include "IOracleRunner.h" + +#include <boost/shared_ptr.hpp> namespace OrthancStone { @@ -33,7 +35,7 @@ { } - virtual void Schedule(const IObserver& receiver, + virtual void Schedule(boost::shared_ptr<IObserver>& receiver, IOracleCommand* command) = 0; // Takes ownership }; }
--- a/Framework/Oracle/IOracleCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/IOracleCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -34,7 +34,8 @@ Type_Sleep, Type_OrthancRestApi, Type_GetOrthancImage, - Type_GetOrthancWebViewerJpeg + Type_GetOrthancWebViewerJpeg, + Type_Custom }; virtual ~IOracleCommand()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Oracle/IOracleRunner.h Wed Oct 23 11:04:47 2019 +0200 @@ -0,0 +1,40 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "IOracleCommand.h" + +#include <boost/weak_ptr.hpp> + +namespace OrthancStone +{ + class IOracleRunner : public boost::noncopyable + { + public: + virtual ~IOracleRunner() + { + } + + virtual void Run(boost::weak_ptr<IObserver>& receiver, + IOracleCommand& command) = 0; + }; +}
--- a/Framework/Oracle/ThreadedOracle.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/ThreadedOracle.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -21,29 +21,21 @@ #include "ThreadedOracle.h" -#include "GetOrthancImageCommand.h" -#include "GetOrthancWebViewerJpegCommand.h" -#include "HttpCommand.h" -#include "OrthancRestApiCommand.h" #include "SleepOracleCommand.h" -#include "OracleCommandExceptionMessage.h" -#include <Core/Compression/GzipCompressor.h> -#include <Core/HttpClient.h> +#include <Core/Logging.h> #include <Core/OrthancException.h> -#include <Core/Toolbox.h> - namespace OrthancStone { class ThreadedOracle::Item : public Orthanc::IDynamicObject { private: - const IObserver& receiver_; + boost::weak_ptr<IObserver> receiver_; std::auto_ptr<IOracleCommand> command_; public: - Item(const IObserver& receiver, + Item(boost::weak_ptr<IObserver> receiver, IOracleCommand* command) : receiver_(receiver), command_(command) @@ -54,7 +46,7 @@ } } - const IObserver& GetReceiver() const + boost::weak_ptr<IObserver>& GetReceiver() { return receiver_; } @@ -73,12 +65,12 @@ class Item { private: - const IObserver& receiver_; + boost::weak_ptr<IObserver> receiver_; std::auto_ptr<SleepOracleCommand> command_; boost::posix_time::ptime expiration_; public: - Item(const IObserver& receiver, + Item(boost::weak_ptr<IObserver>& receiver, SleepOracleCommand* command) : receiver_(receiver), command_(command) @@ -123,7 +115,7 @@ } } - void Add(const IObserver& receiver, + void Add(boost::weak_ptr<IObserver>& receiver, SleepOracleCommand* command) // Takes ownership { boost::mutex::scoped_lock lock(mutex_); @@ -160,154 +152,6 @@ }; - static void CopyHttpHeaders(Orthanc::HttpClient& client, - const Orthanc::HttpClient::HttpHeaders& headers) - { - for (Orthanc::HttpClient::HttpHeaders::const_iterator - it = headers.begin(); it != headers.end(); it++ ) - { - client.AddHeader(it->first, it->second); - } - } - - - static void DecodeAnswer(std::string& answer, - const Orthanc::HttpClient::HttpHeaders& headers) - { - Orthanc::HttpCompression contentEncoding = Orthanc::HttpCompression_None; - - for (Orthanc::HttpClient::HttpHeaders::const_iterator it = headers.begin(); - it != headers.end(); ++it) - { - std::string s; - Orthanc::Toolbox::ToLowerCase(s, it->first); - - if (s == "content-encoding") - { - if (it->second == "gzip") - { - contentEncoding = Orthanc::HttpCompression_Gzip; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, - "Unsupported HTTP Content-Encoding: " + it->second); - } - - break; - } - } - - if (contentEncoding == Orthanc::HttpCompression_Gzip) - { - std::string compressed; - answer.swap(compressed); - - Orthanc::GzipCompressor compressor; - compressor.Uncompress(answer, compressed.c_str(), compressed.size()); - - LOG(INFO) << "Uncompressing gzip Encoding: from " << compressed.size() - << " to " << answer.size() << " bytes"; - } - } - - - static void Execute(IMessageEmitter& emitter, - const IObserver& receiver, - const HttpCommand& command) - { - Orthanc::HttpClient client; - client.SetUrl(command.GetUrl()); - client.SetMethod(command.GetMethod()); - client.SetTimeout(command.GetTimeout()); - - CopyHttpHeaders(client, command.GetHttpHeaders()); - - if (command.GetMethod() == Orthanc::HttpMethod_Post || - command.GetMethod() == Orthanc::HttpMethod_Put) - { - client.SetBody(command.GetBody()); - } - - std::string answer; - Orthanc::HttpClient::HttpHeaders answerHeaders; - client.ApplyAndThrowException(answer, answerHeaders); - - DecodeAnswer(answer, answerHeaders); - - HttpCommand::SuccessMessage message(command, answerHeaders, answer); - emitter.EmitMessage(receiver, message); - } - - - static void Execute(IMessageEmitter& emitter, - const Orthanc::WebServiceParameters& orthanc, - const IObserver& receiver, - const OrthancRestApiCommand& command) - { - Orthanc::HttpClient client(orthanc, command.GetUri()); - client.SetMethod(command.GetMethod()); - client.SetTimeout(command.GetTimeout()); - - CopyHttpHeaders(client, command.GetHttpHeaders()); - - if (command.GetMethod() == Orthanc::HttpMethod_Post || - command.GetMethod() == Orthanc::HttpMethod_Put) - { - client.SetBody(command.GetBody()); - } - - std::string answer; - Orthanc::HttpClient::HttpHeaders answerHeaders; - client.ApplyAndThrowException(answer, answerHeaders); - - DecodeAnswer(answer, answerHeaders); - - OrthancRestApiCommand::SuccessMessage message(command, answerHeaders, answer); - emitter.EmitMessage(receiver, message); - } - - - static void Execute(IMessageEmitter& emitter, - const Orthanc::WebServiceParameters& orthanc, - const IObserver& receiver, - const GetOrthancImageCommand& command) - { - Orthanc::HttpClient client(orthanc, command.GetUri()); - client.SetTimeout(command.GetTimeout()); - - CopyHttpHeaders(client, command.GetHttpHeaders()); - - std::string answer; - Orthanc::HttpClient::HttpHeaders answerHeaders; - client.ApplyAndThrowException(answer, answerHeaders); - - DecodeAnswer(answer, answerHeaders); - - command.ProcessHttpAnswer(emitter, receiver, answer, answerHeaders); - } - - - static void Execute(IMessageEmitter& emitter, - const Orthanc::WebServiceParameters& orthanc, - const IObserver& receiver, - const GetOrthancWebViewerJpegCommand& command) - { - Orthanc::HttpClient client(orthanc, command.GetUri()); - client.SetTimeout(command.GetTimeout()); - - CopyHttpHeaders(client, command.GetHttpHeaders()); - - std::string answer; - Orthanc::HttpClient::HttpHeaders answerHeaders; - client.ApplyAndThrowException(answer, answerHeaders); - - DecodeAnswer(answer, answerHeaders); - - command.ProcessHttpAnswer(emitter, receiver, answer); - } - - void ThreadedOracle::Step() { std::auto_ptr<Orthanc::IDynamicObject> object(queue_.Dequeue(100)); @@ -316,60 +160,23 @@ { Item& item = dynamic_cast<Item&>(*object); - try + if (item.GetCommand().GetType() == IOracleCommand::Type_Sleep) { - switch (item.GetCommand().GetType()) + SleepOracleCommand& command = dynamic_cast<SleepOracleCommand&>(item.GetCommand()); + + std::auto_ptr<SleepOracleCommand> copy(new SleepOracleCommand(command.GetDelay())); + + if (command.HasPayload()) { - case IOracleCommand::Type_Sleep: - { - SleepOracleCommand& command = dynamic_cast<SleepOracleCommand&>(item.GetCommand()); - - std::auto_ptr<SleepOracleCommand> copy(new SleepOracleCommand(command.GetDelay())); - - if (command.HasPayload()) - { - copy->SetPayload(command.ReleasePayload()); - } - - sleepingCommands_->Add(item.GetReceiver(), copy.release()); - - break; - } - - case IOracleCommand::Type_Http: - Execute(emitter_, item.GetReceiver(), - dynamic_cast<const HttpCommand&>(item.GetCommand())); - break; - - case IOracleCommand::Type_OrthancRestApi: - Execute(emitter_, orthanc_, item.GetReceiver(), - dynamic_cast<const OrthancRestApiCommand&>(item.GetCommand())); - break; - - case IOracleCommand::Type_GetOrthancImage: - Execute(emitter_, orthanc_, item.GetReceiver(), - dynamic_cast<const GetOrthancImageCommand&>(item.GetCommand())); - break; - - case IOracleCommand::Type_GetOrthancWebViewerJpeg: - Execute(emitter_, orthanc_, item.GetReceiver(), - dynamic_cast<const GetOrthancWebViewerJpegCommand&>(item.GetCommand())); - break; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + copy->SetPayload(command.ReleasePayload()); } - } - catch (Orthanc::OrthancException& e) - { - LOG(ERROR) << "Exception within the oracle: " << e.What(); - emitter_.EmitMessage(item.GetReceiver(), OracleCommandExceptionMessage(item.GetCommand(), e)); + + sleepingCommands_->Add(item.GetReceiver(), copy.release()); } - catch (...) + else { - LOG(ERROR) << "Threaded exception within the oracle"; - emitter_.EmitMessage(item.GetReceiver(), OracleCommandExceptionMessage - (item.GetCommand(), Orthanc::ErrorCode_InternalError)); + GenericOracleRunner runner(emitter_, orthanc_); + runner.Run(item.GetReceiver(), item.GetCommand()); } } } @@ -563,7 +370,7 @@ } - void ThreadedOracle::Schedule(const IObserver& receiver, + void ThreadedOracle::Schedule(boost::shared_ptr<IObserver>& receiver, IOracleCommand* command) { queue_.Enqueue(new Item(receiver, command));
--- a/Framework/Oracle/ThreadedOracle.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/ThreadedOracle.h Wed Oct 23 11:04:47 2019 +0200 @@ -29,10 +29,9 @@ # error This file can only compiled for native targets #endif -#include "../Messages/IMessageEmitter.h" #include "IOracle.h" +#include "GenericOracleRunner.h" -#include <Core/WebServiceParameters.h> #include <Core/MultiThreading/SharedMessageQueue.h> @@ -74,7 +73,6 @@ virtual ~ThreadedOracle(); - // The reference is not stored. void SetOrthancParameters(const Orthanc::WebServiceParameters& orthanc); void SetThreadsCount(unsigned int count); @@ -88,7 +86,7 @@ StopInternal(); } - virtual void Schedule(const IObserver& receiver, - IOracleCommand* command); + virtual void Schedule(boost::shared_ptr<IObserver>& receiver, + IOracleCommand* command) ORTHANC_OVERRIDE; }; }
--- a/Framework/Oracle/WebAssemblyOracle.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/WebAssemblyOracle.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -695,7 +695,7 @@ - void WebAssemblyOracle::Schedule(const IObserver& receiver, + void WebAssemblyOracle::Schedule(boost::shared_ptr<IObserver>& receiver, IOracleCommand* command) { LOG(TRACE) << "WebAssemblyOracle::Schedule : receiver = "
--- a/Framework/Oracle/WebAssemblyOracle.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Oracle/WebAssemblyOracle.h Wed Oct 23 11:04:47 2019 +0200 @@ -76,7 +76,7 @@ orthancRoot_ = root; } - virtual void Schedule(const IObserver& receiver, - IOracleCommand* command); + virtual void Schedule(boost::shared_ptr<IObserver>& receiver, + IOracleCommand* command) ORTHANC_OVERRIDE; }; }
--- a/Framework/Radiography/RadiographyAlphaLayer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyAlphaLayer.h Wed Oct 23 11:04:47 2019 +0200 @@ -38,8 +38,8 @@ float foreground_; public: - RadiographyAlphaLayer(MessageBroker& broker, const RadiographyScene& scene) : - RadiographyLayer(broker, scene), + RadiographyAlphaLayer(const RadiographyScene& scene) : + RadiographyLayer(scene), useWindowing_(true), foreground_(0) {
--- a/Framework/Radiography/RadiographyDicomLayer.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyDicomLayer.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -47,7 +47,8 @@ } - RadiographyDicomLayer::RadiographyDicomLayer(MessageBroker& broker, const RadiographyScene& scene) : RadiographyLayer(broker, scene) + RadiographyDicomLayer::RadiographyDicomLayer(const RadiographyScene& scene) : + RadiographyLayer(scene) { }
--- a/Framework/Radiography/RadiographyDicomLayer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyDicomLayer.h Wed Oct 23 11:04:47 2019 +0200 @@ -42,7 +42,7 @@ void ApplyConverter(); public: - RadiographyDicomLayer(MessageBroker& broker, const RadiographyScene& scene); + RadiographyDicomLayer(const RadiographyScene& scene); void SetInstance(const std::string& instanceId, unsigned int frame) {
--- a/Framework/Radiography/RadiographyLayer.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyLayer.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -119,8 +119,7 @@ } - RadiographyLayer::RadiographyLayer(MessageBroker& broker, const RadiographyScene& scene) : - IObservable(broker), + RadiographyLayer::RadiographyLayer(const RadiographyScene& scene) : index_(0), hasSize_(false), width_(0),
--- a/Framework/Radiography/RadiographyLayer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyLayer.h Wed Oct 23 11:04:47 2019 +0200 @@ -248,7 +248,7 @@ double zoom); public: - RadiographyLayer(MessageBroker& broker, const RadiographyScene& scene); + RadiographyLayer(const RadiographyScene& scene); virtual ~RadiographyLayer() {
--- a/Framework/Radiography/RadiographyMaskLayer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyMaskLayer.h Wed Oct 23 11:04:47 2019 +0200 @@ -40,9 +40,9 @@ mutable std::auto_ptr<Orthanc::ImageAccessor> mask_; public: - RadiographyMaskLayer(MessageBroker& broker, const RadiographyScene& scene, const RadiographyDicomLayer& dicomLayer, + RadiographyMaskLayer(const RadiographyScene& scene, const RadiographyDicomLayer& dicomLayer, float foreground) : - RadiographyLayer(broker, scene), + RadiographyLayer(scene), dicomLayer_(dicomLayer), invalidated_(true), foreground_(foreground)
--- a/Framework/Radiography/RadiographyScene.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyScene.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -142,7 +142,7 @@ BroadcastMessage(GeometryChangedMessage(*this, *layer)); BroadcastMessage(ContentChangedMessage(*this, *layer)); - layer->RegisterObserverCallback(new Callable<RadiographyScene, RadiographyLayer::LayerEditedMessage>(*this, &RadiographyScene::OnLayerEdited)); + Register<RadiographyLayer::LayerEditedMessage>(*layer, &RadiographyScene::OnLayerEdited); return *layer; } @@ -162,9 +162,7 @@ BroadcastMessage(RadiographyScene::LayerEditedMessage(*this, message.GetOrigin())); } - RadiographyScene::RadiographyScene(MessageBroker& broker) : - IObserver(broker), - IObservable(broker), + RadiographyScene::RadiographyScene() : countLayers_(0), hasWindowing_(false), windowingCenter_(0), // Dummy initialization @@ -284,7 +282,7 @@ const std::string& utf8, RadiographyLayer::Geometry* geometry) { - std::auto_ptr<RadiographyTextLayer> alpha(new RadiographyTextLayer(IObservable::GetBroker(), *this)); + std::auto_ptr<RadiographyTextLayer> alpha(new RadiographyTextLayer(*this)); alpha->LoadText(font, utf8); if (geometry != NULL) { @@ -328,7 +326,7 @@ float foreground, RadiographyLayer::Geometry* geometry) { - std::auto_ptr<RadiographyMaskLayer> mask(new RadiographyMaskLayer(IObservable::GetBroker(), *this, dicomLayer, foreground)); + std::auto_ptr<RadiographyMaskLayer> mask(new RadiographyMaskLayer(*this, dicomLayer, foreground)); mask->SetCorners(corners); if (geometry != NULL) { @@ -341,7 +339,7 @@ RadiographyLayer& RadiographyScene::LoadAlphaBitmap(Orthanc::ImageAccessor* bitmap, RadiographyLayer::Geometry *geometry) { - std::auto_ptr<RadiographyAlphaLayer> alpha(new RadiographyAlphaLayer(IObservable::GetBroker(), *this)); + std::auto_ptr<RadiographyAlphaLayer> alpha(new RadiographyAlphaLayer(*this)); alpha->SetAlpha(bitmap); if (geometry != NULL) { @@ -358,7 +356,7 @@ RadiographyPhotometricDisplayMode preferredPhotometricDisplayMode, RadiographyLayer::Geometry* geometry) { - RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer(IObservable::GetBroker(), *this))); + RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer(*this))); layer.SetInstance(instance, frame); @@ -380,7 +378,7 @@ bool httpCompression, RadiographyLayer::Geometry* geometry) { - RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer(IObservable::GetBroker(), *this))); + RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer( *this))); layer.SetInstance(instance, frame); if (geometry != NULL) @@ -395,7 +393,7 @@ orthanc.GetBinaryAsync( uri, headers, new Callable<RadiographyScene, Deprecated::OrthancApiClient::BinaryResponseReadyMessage> - (*this, &RadiographyScene::OnTagsReceived), NULL, + (GetSharedObserver(), &RadiographyScene::OnTagsReceived), NULL, new Orthanc::SingleValueObject<size_t>(layer.GetIndex())); } @@ -414,7 +412,7 @@ orthanc.GetBinaryAsync( uri, headers, new Callable<RadiographyScene, Deprecated::OrthancApiClient::BinaryResponseReadyMessage> - (*this, &RadiographyScene::OnFrameReceived), NULL, + (GetSharedObserver(), &RadiographyScene::OnFrameReceived), NULL, new Orthanc::SingleValueObject<size_t>(layer.GetIndex())); } @@ -424,7 +422,7 @@ RadiographyLayer& RadiographyScene::LoadDicomWebFrame(Deprecated::IWebService& web) { - RadiographyLayer& layer = RegisterLayer(new RadiographyDicomLayer(IObservable::GetBroker(), *this)); + RadiographyLayer& layer = RegisterLayer(new RadiographyDicomLayer(*this)); return layer; @@ -752,7 +750,7 @@ orthanc.PostJsonAsyncExpectJson( "/tools/create-dicom", createDicomRequestContent, new Callable<RadiographyScene, Deprecated::OrthancApiClient::JsonResponseReadyMessage> - (*this, &RadiographyScene::OnDicomExported), + (GetSharedObserver(), &RadiographyScene::OnDicomExported), NULL, NULL); }
--- a/Framework/Radiography/RadiographyScene.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyScene.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,6 +22,7 @@ #pragma once #include "RadiographyLayer.h" +#include "../Messages/ObserverBase.h" #include "../Deprecated/Toolbox/DicomFrameConverter.h" #include "../Deprecated/Toolbox/OrthancApiClient.h" #include "../StoneEnumerations.h" @@ -33,8 +34,8 @@ class RadiographyDicomLayer; class RadiographyScene : - public IObserver, - public IObservable + public ObserverBase<RadiographyScene>, + public IObservable { public: class GeometryChangedMessage : public OriginMessage<RadiographyScene> @@ -159,7 +160,7 @@ virtual void OnLayerEdited(const RadiographyLayer::LayerEditedMessage& message); public: - RadiographyScene(MessageBroker& broker); + RadiographyScene(); virtual ~RadiographyScene();
--- a/Framework/Radiography/RadiographySceneReader.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographySceneReader.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -50,7 +50,7 @@ RadiographyDicomLayer* RadiographySceneReader::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry) { - return dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomFrame(orthancApiClient_, instanceId, frame, false, geometry))); + return dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomFrame(*orthancApiClient_, instanceId, frame, false, geometry))); } void RadiographySceneBuilder::Read(const Json::Value& input) @@ -161,7 +161,7 @@ if (jsonLayer["type"].asString() == "dicom") { ReadLayerGeometry(geometry, jsonLayer); - dicomLayer = dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomFrame(orthancApiClient_, jsonLayer["instanceId"].asString(), jsonLayer["frame"].asUInt(), false, &geometry))); + dicomLayer = dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomFrame(*orthancApiClient_, jsonLayer["instanceId"].asString(), jsonLayer["frame"].asUInt(), false, &geometry))); } else if (jsonLayer["type"].asString() == "mask") {
--- a/Framework/Radiography/RadiographySceneReader.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographySceneReader.h Wed Oct 23 11:04:47 2019 +0200 @@ -75,10 +75,12 @@ class RadiographySceneReader : public RadiographySceneBuilder { - Deprecated::OrthancApiClient& orthancApiClient_; + private: + boost::shared_ptr<Deprecated::OrthancApiClient> orthancApiClient_; public: - RadiographySceneReader(RadiographyScene& scene, Deprecated::OrthancApiClient& orthancApiClient) : + RadiographySceneReader(RadiographyScene& scene, + boost::shared_ptr<Deprecated::OrthancApiClient> orthancApiClient) : RadiographySceneBuilder(scene), orthancApiClient_(orthancApiClient) {
--- a/Framework/Radiography/RadiographyTextLayer.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyTextLayer.h Wed Oct 23 11:04:47 2019 +0200 @@ -34,8 +34,8 @@ std::string fontName_; public: - RadiographyTextLayer(MessageBroker& broker, const RadiographyScene& scene) : - RadiographyAlphaLayer(broker, scene) + RadiographyTextLayer(const RadiographyScene& scene) : + RadiographyAlphaLayer(scene) { }
--- a/Framework/Radiography/RadiographyWidget.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyWidget.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -181,11 +181,9 @@ } - RadiographyWidget::RadiographyWidget(MessageBroker& broker, - boost::shared_ptr<RadiographyScene> scene, + RadiographyWidget::RadiographyWidget(boost::shared_ptr<RadiographyScene> scene, const std::string& name) : WorldSceneWidget(name), - IObserver(broker), invert_(false), interpolation_(ImageInterpolation_Nearest), hasSelection_(false), @@ -281,20 +279,10 @@ void RadiographyWidget::SetScene(boost::shared_ptr<RadiographyScene> scene) { - if (scene_ != NULL) - { - scene_->Unregister(this); - } - scene_ = scene; - scene_->RegisterObserverCallback( - new Callable<RadiographyWidget, RadiographyScene::GeometryChangedMessage> - (*this, &RadiographyWidget::OnGeometryChanged)); - - scene_->RegisterObserverCallback( - new Callable<RadiographyWidget, RadiographyScene::ContentChangedMessage> - (*this, &RadiographyWidget::OnContentChanged)); + Register<RadiographyScene::GeometryChangedMessage>(*scene_, &RadiographyWidget::OnGeometryChanged); + Register<RadiographyScene::ContentChangedMessage>(*scene_, &RadiographyWidget::OnContentChanged); NotifyContentChanged();
--- a/Framework/Radiography/RadiographyWidget.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Radiography/RadiographyWidget.h Wed Oct 23 11:04:47 2019 +0200 @@ -22,6 +22,7 @@ #pragma once #include "../Deprecated/Widgets/WorldSceneWidget.h" +#include "../Messages/ObserverBase.h" #include "RadiographyScene.h" @@ -31,7 +32,7 @@ class RadiographyWidget : public Deprecated::WorldSceneWidget, - public IObserver + public ObserverBase<RadiographyWidget> { private: boost::shared_ptr<RadiographyScene> scene_; @@ -60,8 +61,7 @@ bool IsInvertedInternal() const; public: - RadiographyWidget(MessageBroker& broker, - boost::shared_ptr<RadiographyScene> scene, // TODO: check how we can avoid boost::shared_ptr here since we don't want them in the public API (app is keeping a boost::shared_ptr to this right now) + RadiographyWidget(boost::shared_ptr<RadiographyScene> scene, // TODO: check how we can avoid boost::shared_ptr here since we don't want them in the public API (app is keeping a boost::shared_ptr to this right now) const std::string& name); RadiographyScene& GetScene() const
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -42,8 +42,8 @@ // the params in the LayerHolder ctor specify the number of polyline and text // layers AngleMeasureTool::AngleMeasureTool( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) - : MeasureTool(broker, controllerW) + boost::weak_ptr<ViewportController> controllerW) + : MeasureTool(controllerW) #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 , layerHolder_(boost::make_shared<LayerHolder>(controllerW,1,5)) #else @@ -189,8 +189,9 @@ boost::weak_ptr<ViewportController> controllerW, const PointerEvent & e); */ + boost::shared_ptr<EditAngleMeasureTracker> editAngleMeasureTracker( - new EditAngleMeasureTracker(shared_from_this(), GetBroker(), GetController(), e)); + new EditAngleMeasureTracker(shared_from_this(), GetController(), e)); return editAngleMeasureTracker; }
--- a/Framework/Scene2DViewport/AngleMeasureTool.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.h Wed Oct 23 11:04:47 2019 +0200 @@ -37,10 +37,10 @@ namespace OrthancStone { - class AngleMeasureTool : public MeasureTool, public boost::enable_shared_from_this<AngleMeasureTool> + class AngleMeasureTool : public MeasureTool { public: - AngleMeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW); + AngleMeasureTool(boost::weak_ptr<ViewportController> controllerW); ~AngleMeasureTool();
--- a/Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,12 +26,11 @@ namespace OrthancStone { CreateAngleMeasureCommand::CreateAngleMeasureCommand( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, ScenePoint2D point) : CreateMeasureCommand(controllerW) , measureTool_( - boost::make_shared<AngleMeasureTool>(boost::ref(broker), controllerW)) + boost::make_shared<AngleMeasureTool>(controllerW)) { GetController()->AddMeasureTool(measureTool_); measureTool_->SetSide1End(point);
--- a/Framework/Scene2DViewport/CreateAngleMeasureCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -28,7 +28,6 @@ public: /** Ctor sets end of side 1*/ CreateAngleMeasureCommand( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, ScenePoint2D point);
--- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,7 +26,6 @@ namespace OrthancStone { CreateAngleMeasureTracker::CreateAngleMeasureTracker( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e) : CreateMeasureTracker(controllerW) @@ -34,7 +33,6 @@ { command_.reset( new CreateAngleMeasureCommand( - broker, controllerW, e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform()))); }
--- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.h Wed Oct 23 11:04:47 2019 +0200 @@ -38,7 +38,6 @@ must be supplied, too */ CreateAngleMeasureTracker( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e);
--- a/Framework/Scene2DViewport/CreateLineMeasureCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,12 +26,11 @@ namespace OrthancStone { CreateLineMeasureCommand::CreateLineMeasureCommand( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, ScenePoint2D point) : CreateMeasureCommand(controllerW) , measureTool_( - boost::make_shared<LineMeasureTool>(boost::ref(broker), controllerW)) + boost::make_shared<LineMeasureTool>(controllerW)) { GetController()->AddMeasureTool(measureTool_); measureTool_->Set(point, point);
--- a/Framework/Scene2DViewport/CreateLineMeasureCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -27,7 +27,6 @@ { public: CreateLineMeasureCommand( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, ScenePoint2D point);
--- a/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,14 +26,12 @@ namespace OrthancStone { CreateLineMeasureTracker::CreateLineMeasureTracker( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e) : CreateMeasureTracker(controllerW) { command_.reset( new CreateLineMeasureCommand( - broker, controllerW, e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform()))); }
--- a/Framework/Scene2DViewport/CreateLineMeasureTracker.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.h Wed Oct 23 11:04:47 2019 +0200 @@ -38,7 +38,6 @@ must be supplied, too */ CreateLineMeasureTracker( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e);
--- a/Framework/Scene2DViewport/EditAngleMeasureCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditAngleMeasureCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -23,8 +23,7 @@ namespace OrthancStone { EditAngleMeasureCommand::EditAngleMeasureCommand( - boost::shared_ptr<AngleMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW) : EditMeasureCommand(measureTool, controllerW) , measureTool_(measureTool) @@ -33,21 +32,21 @@ void EditAngleMeasureCommand::SetCenter(ScenePoint2D scenePos) { - measureTool_->SetCenter(scenePos); + dynamic_cast<AngleMeasureTool&>(*measureTool_).SetCenter(scenePos); mementoModified_ = measureTool_->GetMemento(); } void EditAngleMeasureCommand::SetSide1End(ScenePoint2D scenePos) { - measureTool_->SetSide1End(scenePos); + dynamic_cast<AngleMeasureTool&>(*measureTool_).SetSide1End(scenePos); mementoModified_ = measureTool_->GetMemento(); } void EditAngleMeasureCommand::SetSide2End(ScenePoint2D scenePos) { - measureTool_->SetSide2End(scenePos); + dynamic_cast<AngleMeasureTool&>(*measureTool_).SetSide2End(scenePos); mementoModified_ = measureTool_->GetMemento(); } }
--- a/Framework/Scene2DViewport/EditAngleMeasureCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditAngleMeasureCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -28,8 +28,7 @@ public: /** Ctor sets end of side 1*/ EditAngleMeasureCommand( - boost::shared_ptr<AngleMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW); /** This method sets center*/ @@ -46,6 +45,6 @@ { return measureTool_; } - boost::shared_ptr<AngleMeasureTool> measureTool_; + boost::shared_ptr<MeasureTool> measureTool_; }; }
--- a/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,8 +26,7 @@ namespace OrthancStone { EditAngleMeasureTracker::EditAngleMeasureTracker( - boost::shared_ptr<AngleMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e) : EditMeasureTracker(controllerW, e) @@ -35,9 +34,9 @@ ScenePoint2D scenePos = e.GetMainPosition().Apply( GetScene().GetCanvasToSceneTransform()); - modifiedZone_ = measureTool->AngleHitTest(scenePos); + modifiedZone_ = dynamic_cast<AngleMeasureTool&>(*measureTool).AngleHitTest(scenePos); - command_.reset(new EditAngleMeasureCommand(measureTool, broker, controllerW)); + command_.reset(new EditAngleMeasureCommand(measureTool, controllerW)); } EditAngleMeasureTracker::~EditAngleMeasureTracker()
--- a/Framework/Scene2DViewport/EditAngleMeasureTracker.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.h Wed Oct 23 11:04:47 2019 +0200 @@ -37,8 +37,7 @@ must be supplied, too */ EditAngleMeasureTracker( - boost::shared_ptr<AngleMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e);
--- a/Framework/Scene2DViewport/EditLineMeasureCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditLineMeasureCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -23,8 +23,7 @@ namespace OrthancStone { EditLineMeasureCommand::EditLineMeasureCommand( - boost::shared_ptr<LineMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW) : EditMeasureCommand(measureTool, controllerW) , measureTool_(measureTool) @@ -34,14 +33,14 @@ void EditLineMeasureCommand::SetStart(ScenePoint2D scenePos) { - measureTool_->SetStart(scenePos); + dynamic_cast<LineMeasureTool&>(*measureTool_).SetStart(scenePos); mementoModified_ = measureTool_->GetMemento(); } void EditLineMeasureCommand::SetEnd(ScenePoint2D scenePos) { - measureTool_->SetEnd(scenePos); + dynamic_cast<LineMeasureTool&>(*measureTool_).SetEnd(scenePos); mementoModified_ = measureTool_->GetMemento(); } }
--- a/Framework/Scene2DViewport/EditLineMeasureCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditLineMeasureCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -27,8 +27,7 @@ { public: EditLineMeasureCommand( - boost::shared_ptr<LineMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW); void SetStart(ScenePoint2D scenePos); @@ -39,7 +38,6 @@ { return measureTool_; } - boost::shared_ptr<LineMeasureTool> measureTool_; + boost::shared_ptr<MeasureTool> measureTool_; }; } -
--- a/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -27,8 +27,7 @@ namespace OrthancStone { EditLineMeasureTracker::EditLineMeasureTracker( - boost::shared_ptr<LineMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e) : EditMeasureTracker(controllerW, e) @@ -36,13 +35,9 @@ ScenePoint2D scenePos = e.GetMainPosition().Apply( GetScene().GetCanvasToSceneTransform()); - modifiedZone_ = measureTool->LineHitTest(scenePos); + modifiedZone_ = dynamic_cast<LineMeasureTool&>(*measureTool).LineHitTest(scenePos); - command_.reset( - new EditLineMeasureCommand( - measureTool, - broker, - controllerW)); + command_.reset(new EditLineMeasureCommand(measureTool, controllerW)); } EditLineMeasureTracker::~EditLineMeasureTracker()
--- a/Framework/Scene2DViewport/EditLineMeasureTracker.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/EditLineMeasureTracker.h Wed Oct 23 11:04:47 2019 +0200 @@ -37,8 +37,7 @@ must be supplied, too */ EditLineMeasureTracker( - boost::shared_ptr<LineMeasureTool> measureTool, - MessageBroker& broker, + boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e);
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -32,8 +32,8 @@ { LineMeasureTool::LineMeasureTool( - MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) - : MeasureTool(broker, controllerW) + boost::weak_ptr<ViewportController> controllerW) + : MeasureTool(controllerW) #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5)) #else @@ -148,7 +148,7 @@ const PointerEvent & e); */ boost::shared_ptr<EditLineMeasureTracker> editLineMeasureTracker( - new EditLineMeasureTracker(shared_from_this(), GetBroker(), GetController(), e)); + new EditLineMeasureTracker(shared_from_this(), GetController(), e)); return editLineMeasureTracker; }
--- a/Framework/Scene2DViewport/LineMeasureTool.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.h Wed Oct 23 11:04:47 2019 +0200 @@ -35,10 +35,10 @@ namespace OrthancStone { - class LineMeasureTool : public MeasureTool, public boost::enable_shared_from_this<LineMeasureTool> + class LineMeasureTool : public MeasureTool { public: - LineMeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW); + LineMeasureTool(boost::weak_ptr<ViewportController> controllerW); ~LineMeasureTool();
--- a/Framework/Scene2DViewport/MeasureTool.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTool.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -28,14 +28,6 @@ namespace OrthancStone { - MeasureTool::~MeasureTool() - { - // if the controller is dead, let's not bother. - boost::shared_ptr<ViewportController> controller = controllerW_.lock(); - if (controller) - controller->Unregister(this); - } - void MeasureTool::Enable() { enabled_ = true; @@ -79,15 +71,13 @@ #endif } - MeasureTool::MeasureTool(MessageBroker& broker, + MeasureTool::MeasureTool( boost::weak_ptr<ViewportController> controllerW) - : IObserver(broker) - , controllerW_(controllerW) + : controllerW_(controllerW) , enabled_(true) { - GetController()->RegisterObserverCallback( - new Callable<MeasureTool, ViewportController::SceneTransformChanged> - (*this, &MeasureTool::OnSceneTransformChanged)); + // TODO => Move this out of constructor + Register<ViewportController::SceneTransformChanged>(*GetController(), &MeasureTool::OnSceneTransformChanged); }
--- a/Framework/Scene2DViewport/MeasureTool.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTool.h Wed Oct 23 11:04:47 2019 +0200 @@ -20,6 +20,7 @@ #pragma once +#include "../Messages/ObserverBase.h" #include "../Scene2D/PolylineSceneLayer.h" #include "../Scene2D/Scene2D.h" #include "../Scene2D/ScenePoint2D.h" @@ -27,7 +28,6 @@ #include "../Scene2DViewport/PredeclaredTypes.h" #include "../Scene2DViewport/ViewportController.h" -#include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <vector> @@ -38,10 +38,12 @@ class IFlexiblePointerTracker; class MeasureToolMemento; - class MeasureTool : public IObserver + class MeasureTool : public ObserverBase<MeasureTool> { public: - virtual ~MeasureTool(); + virtual ~MeasureTool() + { + } /** Enabled tools are rendered in the scene. @@ -111,7 +113,7 @@ virtual std::string GetDescription() = 0; protected: - MeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW); + MeasureTool(boost::weak_ptr<ViewportController> controllerW); /** The measuring tool may exist in a standalone fashion, without any available
--- a/Framework/Scene2DViewport/ViewportController.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -30,10 +30,8 @@ namespace OrthancStone { ViewportController::ViewportController(boost::weak_ptr<UndoStack> undoStackW, - MessageBroker& broker, IViewport& viewport) - : IObservable(broker) - , undoStackW_(undoStackW) + : undoStackW_(undoStackW) , canvasToSceneFactor_(0.0) , viewport_(viewport) {
--- a/Framework/Scene2DViewport/ViewportController.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.h Wed Oct 23 11:04:47 2019 +0200 @@ -81,7 +81,6 @@ SceneTransformChanged, ViewportController); ViewportController(boost::weak_ptr<UndoStack> undoStackW, - MessageBroker& broker, IViewport& viewport);
--- a/Framework/Toolbox/GenericToolbox.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Toolbox/GenericToolbox.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -29,7 +29,7 @@ { bool GetRgbaValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, uint8_t& alpha, const char* text) { - boost::regex pattern(R"bgo(\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*)bgo"); + boost::regex pattern("\\s*rgb\\s*\\(\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*\\)\\s*"); boost::cmatch what; @@ -68,7 +68,7 @@ } bool GetRgbValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, const char* text) { - boost::regex pattern(R"bgo(\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*)bgo"); + boost::regex pattern("\\s*rgb\\s*\\(\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*\\)\\s*"); boost::cmatch what;
--- a/Framework/Toolbox/GenericToolbox.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Framework/Toolbox/GenericToolbox.h Wed Oct 23 11:04:47 2019 +0200 @@ -116,7 +116,7 @@ if (*p == '.') { double f = 0.0; - int n = 1; + size_t n = 1; ++p; while (*p >= '0' && *p <= '9' && n < FRAC_FACTORS_LEN) {
--- a/Platforms/Generic/DelayedCallCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/DelayedCallCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -26,13 +26,11 @@ namespace Deprecated { - DelayedCallCommand::DelayedCallCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback, // takes ownership + DelayedCallCommand::DelayedCallCommand(OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback, // takes ownership unsigned int timeoutInMs, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context ) : - IObservable(broker), callback_(callback), payload_(payload), context_(context),
--- a/Platforms/Generic/DelayedCallCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/DelayedCallCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -42,8 +42,7 @@ unsigned int timeoutInMs_; public: - DelayedCallCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback, // takes ownership + DelayedCallCommand(OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback, // takes ownership unsigned int timeoutInMs, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context
--- a/Platforms/Generic/OracleDelayedCallExecutor.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/OracleDelayedCallExecutor.h Wed Oct 23 11:04:47 2019 +0200 @@ -36,10 +36,8 @@ OrthancStone::NativeStoneApplicationContext& context_; public: - OracleDelayedCallExecutor(OrthancStone::MessageBroker& broker, - Oracle& oracle, + OracleDelayedCallExecutor(Oracle& oracle, OrthancStone::NativeStoneApplicationContext& context) : - IDelayedCallExecutor(broker), oracle_(oracle), context_(context) { @@ -48,7 +46,7 @@ virtual void Schedule(OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback, unsigned int timeoutInMs = 1000) { - oracle_.Submit(new DelayedCallCommand(broker_, callback, timeoutInMs, NULL, context_)); + oracle_.Submit(new DelayedCallCommand(callback, timeoutInMs, NULL, context_)); } }; }
--- a/Platforms/Generic/OracleWebService.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/OracleWebService.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -35,13 +35,11 @@ OrthancStone::NativeStoneApplicationContext& context_; public: - WebServiceCachedGetCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServiceCachedGetCommand(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedMessage, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context ) : - IObservable(broker), successCallback_(successCallback), payload_(payload), cachedMessage_(cachedMessage), @@ -75,7 +73,7 @@ Orthanc::IDynamicObject* payload, // takes ownership OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback) { - oracle_.Submit(new WebServiceCachedGetCommand(GetBroker(), successCallback, cachedMessage, payload, context_)); + oracle_.Submit(new WebServiceCachedGetCommand(successCallback, cachedMessage, payload, context_)); }
--- a/Platforms/Generic/OracleWebService.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/OracleWebService.h Wed Oct 23 11:04:47 2019 +0200 @@ -43,11 +43,9 @@ class WebServiceCachedGetCommand; public: - OracleWebService(OrthancStone::MessageBroker& broker, - Oracle& oracle, + OracleWebService(Oracle& oracle, const Orthanc::WebServiceParameters& parameters, OrthancStone::NativeStoneApplicationContext& context) : - BaseWebService(broker), oracle_(oracle), context_(context), parameters_(parameters) @@ -62,7 +60,7 @@ OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL, // takes ownership unsigned int timeoutInSeconds = 60) { - oracle_.Submit(new WebServicePostCommand(GetBroker(), successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, body, payload, context_)); + oracle_.Submit(new WebServicePostCommand(successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, body, payload, context_)); } virtual void DeleteAsync(const std::string& uri, @@ -72,7 +70,7 @@ OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL, unsigned int timeoutInSeconds = 60) { - oracle_.Submit(new WebServiceDeleteCommand(GetBroker(), successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, payload, context_)); + oracle_.Submit(new WebServiceDeleteCommand(successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, payload, context_)); } protected: @@ -83,7 +81,7 @@ OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,// takes ownership unsigned int timeoutInSeconds = 60) { - oracle_.Submit(new WebServiceGetCommand(GetBroker(), successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, payload, context_)); + oracle_.Submit(new WebServiceGetCommand(successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, payload, context_)); } virtual void NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedHttpMessage,
--- a/Platforms/Generic/WebServiceCommandBase.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServiceCommandBase.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -25,8 +25,7 @@ namespace Deprecated { - WebServiceCommandBase::WebServiceCommandBase(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, + WebServiceCommandBase::WebServiceCommandBase(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, const Orthanc::WebServiceParameters& parameters, const std::string& url, @@ -34,7 +33,6 @@ unsigned int timeoutInSeconds, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context) : - IObservable(broker), successCallback_(successCallback), failureCallback_(failureCallback), parameters_(parameters),
--- a/Platforms/Generic/WebServiceCommandBase.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServiceCommandBase.h Wed Oct 23 11:04:47 2019 +0200 @@ -51,8 +51,7 @@ unsigned int timeoutInSeconds_; public: - WebServiceCommandBase(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServiceCommandBase(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url,
--- a/Platforms/Generic/WebServiceDeleteCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServiceDeleteCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -25,8 +25,7 @@ namespace Deprecated { - WebServiceDeleteCommand::WebServiceDeleteCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServiceDeleteCommand::WebServiceDeleteCommand(OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url, @@ -34,7 +33,7 @@ unsigned int timeoutInSeconds, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context) : - WebServiceCommandBase(broker, successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context) + WebServiceCommandBase(successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context) { }
--- a/Platforms/Generic/WebServiceDeleteCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServiceDeleteCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -28,8 +28,7 @@ class WebServiceDeleteCommand : public WebServiceCommandBase { public: - WebServiceDeleteCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServiceDeleteCommand(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url,
--- a/Platforms/Generic/WebServiceGetCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServiceGetCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -25,9 +25,7 @@ namespace Deprecated { - - WebServiceGetCommand::WebServiceGetCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServiceGetCommand::WebServiceGetCommand(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url, @@ -35,7 +33,7 @@ unsigned int timeoutInSeconds, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context) : - WebServiceCommandBase(broker, successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context) + WebServiceCommandBase(successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context) { }
--- a/Platforms/Generic/WebServiceGetCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServiceGetCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -28,8 +28,7 @@ class WebServiceGetCommand : public WebServiceCommandBase { public: - WebServiceGetCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServiceGetCommand(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url,
--- a/Platforms/Generic/WebServicePostCommand.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServicePostCommand.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -25,8 +25,7 @@ namespace Deprecated { - WebServicePostCommand::WebServicePostCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServicePostCommand::WebServicePostCommand(OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url, @@ -35,7 +34,7 @@ const std::string& body, Orthanc::IDynamicObject* payload /* takes ownership */, OrthancStone::NativeStoneApplicationContext& context) : - WebServiceCommandBase(broker, successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context), + WebServiceCommandBase(successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context), body_(body) { }
--- a/Platforms/Generic/WebServicePostCommand.h Tue Oct 22 17:51:25 2019 +0200 +++ b/Platforms/Generic/WebServicePostCommand.h Wed Oct 23 11:04:47 2019 +0200 @@ -31,8 +31,7 @@ std::string body_; public: - WebServicePostCommand(OrthancStone::MessageBroker& broker, - OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership + WebServicePostCommand(OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback, // takes ownership const Orthanc::WebServiceParameters& parameters, const std::string& url,
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Tue Oct 22 17:51:25 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Wed Oct 23 11:04:47 2019 +0200 @@ -401,8 +401,10 @@ if (ENABLE_THREADS) list(APPEND ORTHANC_STONE_SOURCES + ${ORTHANC_STONE_ROOT}/Framework/Messages/LockingEmitter.cpp ${ORTHANC_STONE_ROOT}/Framework/Messages/LockingEmitter.h ${ORTHANC_STONE_ROOT}/Framework/Oracle/ThreadedOracle.cpp + ${ORTHANC_STONE_ROOT}/Framework/Oracle/GenericOracleRunner.cpp ) endif() @@ -452,10 +454,7 @@ ${ORTHANC_STONE_ROOT}/Framework/Messages/ICallable.h ${ORTHANC_STONE_ROOT}/Framework/Messages/IMessage.h ${ORTHANC_STONE_ROOT}/Framework/Messages/IObservable.cpp - ${ORTHANC_STONE_ROOT}/Framework/Messages/IObserver.cpp ${ORTHANC_STONE_ROOT}/Framework/Messages/IObserver.h - ${ORTHANC_STONE_ROOT}/Framework/Messages/MessageBroker.h - ${ORTHANC_STONE_ROOT}/Framework/Messages/MessageForwarder.cpp ${ORTHANC_STONE_ROOT}/Framework/Oracle/GetOrthancImageCommand.cpp ${ORTHANC_STONE_ROOT}/Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp ${ORTHANC_STONE_ROOT}/Framework/Oracle/OracleCommandWithPayload.cpp
--- a/UnitTestsSources/GenericToolboxTests.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/UnitTestsSources/GenericToolboxTests.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -3762,7 +3762,7 @@ for (double b = DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) { char txt[1024]; - sprintf_s(txt, "%.17f", b); + snprintf(txt, sizeof(txt) - 1, "%.17f", b); double r = 0.0; bool ok = StringToDouble(r, txt); @@ -3802,7 +3802,7 @@ for (double b = -1.0*DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) { char txt[1024]; - sprintf_s(txt, "%.17f", b); + snprintf(txt, sizeof(txt) - 1, "%.17f", b); double r = 0.0; bool ok = StringToDouble(r, txt); @@ -3843,9 +3843,9 @@ int64_t bi = static_cast<int64_t>(b); char txt[1024]; #if (defined __clang__) || (defined __GNUC__) || ( (defined _MSC_VER) && (_MSC_VER > 1800) ) - sprintf_s(txt, "%lld", bi); + snprintf(txt, sizeof(txt) - 1, "%ld", bi); #elif (defined _MSC_VER) - sprintf_s(txt, "%I64d", bi); + snprintf(txt, sizeof(txt) - 1, "%I64d", bi); #else #error Please adjust for your platform #endif
--- a/UnitTestsSources/TestMessageBroker.cpp Tue Oct 22 17:51:25 2019 +0200 +++ b/UnitTestsSources/TestMessageBroker.cpp Wed Oct 23 11:04:47 2019 +0200 @@ -21,10 +21,8 @@ #include "gtest/gtest.h" -#include "../Framework/Messages/MessageBroker.h" -#include "../Framework/Messages/IObservable.h" -#include "../Framework/Messages/IObserver.h" -#include "../Framework/Messages/MessageForwarder.h" +#include "Framework/Messages/IObservable.h" +#include "Framework/Messages/ObserverBase.h" int testCounter = 0; @@ -47,51 +45,26 @@ { } }; - - MyObservable(MessageBroker& broker) : - IObservable(broker) - { - } }; - class MyObserver : public IObserver + class MyObserver : public ObserverBase<MyObserver> { public: - MyObserver(MessageBroker& broker) - : IObserver(broker) - {} - void HandleCompletedMessage(const MyObservable::MyCustomMessage& message) { testCounter += message.payload_; } - - }; - - - class MyIntermediate : public IObserver, public IObservable - { - IObservable& observedObject_; - public: - MyIntermediate(MessageBroker& broker, IObservable& observedObject) - : IObserver(broker), - IObservable(broker), - observedObject_(observedObject) - { - observedObject_.RegisterObserverCallback(new MessageForwarder<MyObservable::MyCustomMessage>(broker, *this)); - } }; } TEST(MessageBroker, TestPermanentConnectionSimpleUseCase) { - MessageBroker broker; - MyObservable observable(broker); - MyObserver observer(broker); + MyObservable observable; + boost::shared_ptr<MyObserver> observer(new MyObserver); // create a permanent connection between an observable and an observer - observable.RegisterObserverCallback(new Callable<MyObserver, MyObservable::MyCustomMessage>(observer, &MyObserver::HandleCompletedMessage)); + observer->Register<MyObservable::MyCustomMessage>(observable, &MyObserver::HandleCompletedMessage); testCounter = 0; observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); @@ -103,155 +76,29 @@ ASSERT_EQ(20, testCounter); // Unregister the observer; make sure it's not called anymore - observable.Unregister(&observer); + observer.reset(); testCounter = 0; observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); ASSERT_EQ(0, testCounter); } -TEST(MessageBroker, TestMessageForwarderSimpleUseCase) -{ - MessageBroker broker; - MyObservable observable(broker); - MyIntermediate intermediate(broker, observable); - MyObserver observer(broker); - - // let the observer observers the intermediate that is actually forwarding the messages from the observable - intermediate.RegisterObserverCallback(new Callable<MyObserver, MyObservable::MyCustomMessage>(observer, &MyObserver::HandleCompletedMessage)); - - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); - ASSERT_EQ(12, testCounter); - - // the connection is permanent; if we emit the same message again, the observer will be notified again - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); - ASSERT_EQ(20, testCounter); -} - TEST(MessageBroker, TestPermanentConnectionDeleteObserver) { - MessageBroker broker; - MyObservable observable(broker); - MyObserver* observer = new MyObserver(broker); + MyObservable observable; + boost::shared_ptr<MyObserver> observer(new MyObserver); // create a permanent connection between an observable and an observer - observable.RegisterObserverCallback(new Callable<MyObserver, MyObservable::MyCustomMessage>(*observer, &MyObserver::HandleCompletedMessage)); + observer->Register<MyObservable::MyCustomMessage>(observable, &MyObserver::HandleCompletedMessage); testCounter = 0; observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); ASSERT_EQ(12, testCounter); // delete the observer and check that the callback is not called anymore - delete observer; + observer.reset(); // the connection is permanent; if we emit the same message again, the observer will be notified again testCounter = 0; observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); ASSERT_EQ(0, testCounter); } - -TEST(MessageBroker, TestMessageForwarderDeleteIntermediate) -{ - MessageBroker broker; - MyObservable observable(broker); - MyIntermediate* intermediate = new MyIntermediate(broker, observable); - MyObserver observer(broker); - - // let the observer observers the intermediate that is actually forwarding the messages from the observable - intermediate->RegisterObserverCallback(new Callable<MyObserver, MyObservable::MyCustomMessage>(observer, &MyObserver::HandleCompletedMessage)); - - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); - ASSERT_EQ(12, testCounter); - - delete intermediate; - - observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); - ASSERT_EQ(12, testCounter); -} - -TEST(MessageBroker, TestCustomMessage) -{ - MessageBroker broker; - MyObservable observable(broker); - MyIntermediate intermediate(broker, observable); - MyObserver observer(broker); - - // let the observer observers the intermediate that is actually forwarding the messages from the observable - intermediate.RegisterObserverCallback(new Callable<MyObserver, MyObservable::MyCustomMessage>(observer, &MyObserver::HandleCompletedMessage)); - - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); - ASSERT_EQ(12, testCounter); - - // the connection is permanent; if we emit the same message again, the observer will be notified again - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); - ASSERT_EQ(20, testCounter); -} - - -#if 0 /* __cplusplus >= 201103L*/ - -TEST(MessageBroker, TestLambdaSimpleUseCase) -{ - MessageBroker broker; - MyObservable observable(broker); - MyObserver* observer = new MyObserver(broker); - - // create a permanent connection between an observable and an observer - observable.RegisterObserverCallback(new LambdaCallable<MyObservable::MyCustomMessage>(*observer, [&](const MyObservable::MyCustomMessage& message) {testCounter += 2 * message.payload_;})); - - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); - ASSERT_EQ(24, testCounter); - - // delete the observer and check that the callback is not called anymore - delete observer; - - // the connection is permanent; if we emit the same message again, the observer will be notified again - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); - ASSERT_EQ(0, testCounter); -} - -namespace { - class MyObserverWithLambda : public IObserver { - private: - int multiplier_; // this is a private variable we want to access in a lambda - - public: - MyObserverWithLambda(MessageBroker& broker, int multiplier, MyObservable& observable) - : IObserver(broker), - multiplier_(multiplier) - { - // register a callable to a lambda that access private members - observable.RegisterObserverCallback(new LambdaCallable<MyObservable::MyCustomMessage>(*this, [this](const MyObservable::MyCustomMessage& message) { - testCounter += multiplier_ * message.payload_; - })); - - } - }; -} - -TEST(MessageBroker, TestLambdaCaptureThisAndAccessPrivateMembers) -{ - MessageBroker broker; - MyObservable observable(broker); - MyObserverWithLambda* observer = new MyObserverWithLambda(broker, 3, observable); - - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(12)); - ASSERT_EQ(36, testCounter); - - // delete the observer and check that the callback is not called anymore - delete observer; - - // the connection is permanent; if we emit the same message again, the observer will be notified again - testCounter = 0; - observable.BroadcastMessage(MyObservable::MyCustomMessage(20)); - ASSERT_EQ(0, testCounter); -} - -#endif // C++ 11