changeset 1314:9b126de2cde2 broker

Since the observer system now uses shared_ptr and many registrations are done in the constructors, and since we cannot called shared_from_this() in the constructors, it is mandatory to split construction from registration. This has been done by making many ctors protected and replacing them by factory methods that directly return shared_ptrs + added PostConstructor method when base classes perform shared_from_this() calls too.
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 16 Mar 2020 11:19:50 +0100
parents f30905f5d246
children 1a08b779be64
files Framework/Deprecated/Loaders/DicomStructureSetLoader.cpp Framework/Deprecated/Loaders/DicomStructureSetLoader.h Framework/Deprecated/Loaders/LoaderCache.cpp Framework/Deprecated/Loaders/LoaderStateMachine.cpp Framework/Deprecated/Loaders/LoaderStateMachine.h Framework/Deprecated/Loaders/OrthancMultiframeVolumeLoader.cpp Framework/Deprecated/Loaders/OrthancMultiframeVolumeLoader.h Framework/Deprecated/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Framework/Deprecated/Loaders/OrthancSeriesVolumeProgressiveLoader.h Framework/Scene2DViewport/AngleMeasureTool.cpp Framework/Scene2DViewport/AngleMeasureTool.h Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp Framework/Scene2DViewport/CreateLineMeasureCommand.cpp Framework/Scene2DViewport/LineMeasureTool.cpp Framework/Scene2DViewport/LineMeasureTool.h Framework/Scene2DViewport/MeasureTool.cpp Framework/Scene2DViewport/MeasureTool.h
diffstat 17 files changed, 114 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Deprecated/Loaders/DicomStructureSetLoader.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/DicomStructureSetLoader.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -357,6 +357,16 @@
   }
    
     
+  boost::shared_ptr<Deprecated::DicomStructureSetLoader> DicomStructureSetLoader::Create(OrthancStone::ILoadersContext& loadersContext)
+  {
+    boost::shared_ptr<DicomStructureSetLoader> obj(
+      new DicomStructureSetLoader(
+        loadersContext));
+    obj->LoaderStateMachine::PostConstructor();
+    return obj;
+
+  }
+
   void DicomStructureSetLoader::SetStructureDisplayState(size_t structureIndex, bool display)
   {
     structureVisibility_.at(structureIndex) = display;
--- a/Framework/Deprecated/Loaders/DicomStructureSetLoader.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/DicomStructureSetLoader.h	Mon Mar 16 11:19:50 2020 +0100
@@ -69,11 +69,15 @@
     */
     std::vector<bool>                  structureVisibility_;
 
+  protected:
+    DicomStructureSetLoader(OrthancStone::ILoadersContext& loadersContext);
+
   public:
     ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, StructuresReady, DicomStructureSetLoader);
 
-    DicomStructureSetLoader(OrthancStone::ILoadersContext& loadersContext);
-    
+    static boost::shared_ptr<DicomStructureSetLoader> Create(
+      OrthancStone::ILoadersContext& loadersContext);
+
     OrthancStone::DicomStructureSet* GetContent()
     {
       return content_.get();
--- a/Framework/Deprecated/Loaders/LoaderCache.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/LoaderCache.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -83,7 +83,7 @@
         boost::shared_ptr<OrthancStone::DicomVolumeImage> volumeImage(new OrthancStone::DicomVolumeImage);
         boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> loader;
       
-        loader.reset(new OrthancSeriesVolumeProgressiveLoader(loadersContext_, volumeImage));
+        loader = OrthancSeriesVolumeProgressiveLoader::Create(loadersContext_, volumeImage);
         loader->LoadSeries(seriesUuid);
         seriesVolumeProgressiveLoaders_[seriesUuid] = loader;
       }
@@ -144,7 +144,7 @@
         boost::shared_ptr<OrthancStone::DicomVolumeImage> volumeImage(new OrthancStone::DicomVolumeImage);
         boost::shared_ptr<OrthancMultiframeVolumeLoader> loader;
         {
-          loader.reset(new OrthancMultiframeVolumeLoader(loadersContext_, volumeImage));
+          loader = OrthancMultiframeVolumeLoader::Create(loadersContext_, volumeImage);
           loader->LoadInstance(instanceUuid);
         }
         multiframeVolumeLoaders_[instanceUuid] = loader;
@@ -241,7 +241,7 @@
 
         boost::shared_ptr<DicomStructureSetLoader> loader;
         {
-          loader.reset(new DicomStructureSetLoader(loadersContext_));
+          loader = DicomStructureSetLoader::Create(loadersContext_);
           loader->LoadInstance(inInstanceUuid, initiallyVisibleStructures);
         }
         dicomStructureSetLoaders_[entryKey] = loader;
--- a/Framework/Deprecated/Loaders/LoaderStateMachine.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/LoaderStateMachine.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -174,12 +174,16 @@
     LOG(TRACE) 
       << "LoaderStateMachine(" << std::hex << this 
       << std::dec << ")::LoaderStateMachine()";
+  }
 
-    std::unique_ptr<ILoadersContext::ILock> lock(loadersContext_.Lock());
+  void LoaderStateMachine::PostConstructor()
+  {
+    std::unique_ptr<OrthancStone::ILoadersContext::ILock>
+      lock(loadersContext_.Lock());
 
     OrthancStone::IObservable& observable = lock->GetOracleObservable();
 
-    // TODO => Move this out of constructor WHY?
+    // TODO => Move this out of constructor
     Register<OrthancStone::OrthancRestApiCommand::SuccessMessage>(
       observable, &LoaderStateMachine::HandleSuccessMessage);
     Register<OrthancStone::GetOrthancImageCommand::SuccessMessage>(
--- a/Framework/Deprecated/Loaders/LoaderStateMachine.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/LoaderStateMachine.h	Mon Mar 16 11:19:50 2020 +0100
@@ -45,10 +45,16 @@
      simultaneousDownloads_ of them at the same time, then will schedule the 
      rest once slots become available. It is used, a.o., by the 
      OrtancMultiframeVolumeLoader class.
+
+     To use it, you need to create commands that derive from State.
+
+     You need to initialize them with the object that must be called when 
+     an answer is received. 
   */
+
   class LoaderStateMachine : public OrthancStone::ObserverBase<LoaderStateMachine>
   {
-  protected:
+  public:
     class State : public Orthanc::IDynamicObject
     {
     private:
@@ -105,9 +111,12 @@
     PendingCommands                 pendingCommands_;
     unsigned int                    activeCommands_;
 
+
   public:
     LoaderStateMachine(OrthancStone::ILoadersContext& loadersContext);
 
+    void PostConstructor();
+
     virtual ~LoaderStateMachine();
 
     bool IsActive() const
--- a/Framework/Deprecated/Loaders/OrthancMultiframeVolumeLoader.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/OrthancMultiframeVolumeLoader.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -526,12 +526,27 @@
     }
   }
 
+
+  boost::shared_ptr<OrthancMultiframeVolumeLoader>
+    OrthancMultiframeVolumeLoader::Create(
+      OrthancStone::ILoadersContext& loadersContext, 
+      boost::shared_ptr<OrthancStone::DicomVolumeImage> volume, 
+      float outliersHalfRejectionRate /*= 0.0005*/)
+  {
+    boost::shared_ptr<OrthancMultiframeVolumeLoader> obj(
+      new OrthancMultiframeVolumeLoader(
+        loadersContext,
+        volume,
+        outliersHalfRejectionRate));
+    obj->LoaderStateMachine::PostConstructor();
+    return obj;
+  }
+
   OrthancMultiframeVolumeLoader::~OrthancMultiframeVolumeLoader()
   {
     LOG(TRACE) << "OrthancMultiframeVolumeLoader::~OrthancMultiframeVolumeLoader()";
   }
-
-
+  
   void OrthancMultiframeVolumeLoader::GetDistributionMinMax
   (float& minValue, float& maxValue) const
   {
--- a/Framework/Deprecated/Loaders/OrthancMultiframeVolumeLoader.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/OrthancMultiframeVolumeLoader.h	Mon Mar 16 11:19:50 2020 +0100
@@ -93,12 +93,18 @@
     bool HasGeometry() const;
     const OrthancStone::VolumeImageGeometry& GetImageGeometry() const;
 
-  public:
+  protected:
     OrthancMultiframeVolumeLoader(
       OrthancStone::ILoadersContext& loadersContext,
       boost::shared_ptr<OrthancStone::DicomVolumeImage> volume,
+      float outliersHalfRejectionRate);
+  public:
+
+    static boost::shared_ptr<OrthancMultiframeVolumeLoader> Create(
+      OrthancStone::ILoadersContext& loadersContext,
+      boost::shared_ptr<OrthancStone::DicomVolumeImage> volume,
       float outliersHalfRejectionRate = 0.0005);
-    
+
     virtual ~OrthancMultiframeVolumeLoader();
 
     bool IsPixelDataLoaded() const
--- a/Framework/Deprecated/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -446,22 +446,34 @@
     , sorter_(new OrthancStone::BasicFetchingItemsSorter::Factory)
     , volumeImageReadyInHighQuality_(false)
   {
+  }
+
+  boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> 
+    OrthancSeriesVolumeProgressiveLoader::Create(
+      OrthancStone::ILoadersContext& loadersContext,
+      const boost::shared_ptr<OrthancStone::DicomVolumeImage>& volume)
+  {
     std::auto_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext.Lock());
 
-    // TODO => Move this out of constructor WHY?
-    Register<OrthancStone::OrthancRestApiCommand::SuccessMessage>(
-      lock->GetOracleObservable(), 
+    boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> obj(
+        new OrthancSeriesVolumeProgressiveLoader(loadersContext,volume));
+
+    obj->Register<OrthancStone::OrthancRestApiCommand::SuccessMessage>(
+      lock->GetOracleObservable(),
       &OrthancSeriesVolumeProgressiveLoader::LoadGeometry);
 
-    Register<OrthancStone::GetOrthancImageCommand::SuccessMessage>(
+    obj->Register<OrthancStone::GetOrthancImageCommand::SuccessMessage>(
       lock->GetOracleObservable(),
       &OrthancSeriesVolumeProgressiveLoader::LoadBestQualitySliceContent);
 
-    Register<OrthancStone::GetOrthancWebViewerJpegCommand::SuccessMessage>(
+    obj->Register<OrthancStone::GetOrthancWebViewerJpegCommand::SuccessMessage>(
       lock->GetOracleObservable(),
       &OrthancSeriesVolumeProgressiveLoader::LoadJpegSliceContent);
+
+    return obj;
   }
 
+
   OrthancSeriesVolumeProgressiveLoader::~OrthancSeriesVolumeProgressiveLoader()
   {
     LOG(TRACE) << "OrthancSeriesVolumeProgressiveLoader::~OrthancSeriesVolumeProgressiveLoader()";
--- a/Framework/Deprecated/Loaders/OrthancSeriesVolumeProgressiveLoader.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Deprecated/Loaders/OrthancSeriesVolumeProgressiveLoader.h	Mon Mar 16 11:19:50 2020 +0100
@@ -123,10 +123,15 @@
     std::vector<unsigned int>                     slicesQuality_;
     bool                                          volumeImageReadyInHighQuality_;
 
+
+    OrthancSeriesVolumeProgressiveLoader(
+      OrthancStone::ILoadersContext& loadersContext,
+      const boost::shared_ptr<OrthancStone::DicomVolumeImage>& volume);
+  
   public:
     ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, VolumeImageReadyInHighQuality, OrthancSeriesVolumeProgressiveLoader);
 
-    OrthancSeriesVolumeProgressiveLoader(
+    static boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> Create(
       OrthancStone::ILoadersContext& context,
       const boost::shared_ptr<OrthancStone::DicomVolumeImage>& volume);
 
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -51,7 +51,14 @@
 #endif
     , angleHighlightArea_(AngleHighlightArea_None)
   {
-    RefreshScene();
+  }
+
+  boost::shared_ptr<AngleMeasureTool> AngleMeasureTool::Create(IViewport& viewport)
+  {
+    boost::shared_ptr<AngleMeasureTool> obj(new AngleMeasureTool(viewport));
+    obj->MeasureTool::PostConstructor();
+    obj->RefreshScene();
+    return obj;
   }
 
   AngleMeasureTool::~AngleMeasureTool()
--- a/Framework/Scene2DViewport/AngleMeasureTool.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/AngleMeasureTool.h	Mon Mar 16 11:19:50 2020 +0100
@@ -40,7 +40,7 @@
   class AngleMeasureTool : public MeasureTool
   {
   public:
-    AngleMeasureTool(IViewport& viewport);
+    static boost::shared_ptr<AngleMeasureTool> Create(IViewport& viewport);
 
     ~AngleMeasureTool();
 
@@ -70,6 +70,8 @@
     AngleHighlightArea AngleHitTest(ScenePoint2D p) const;
 
   private:
+    AngleMeasureTool(IViewport& viewport);
+
     virtual void        RefreshScene() ORTHANC_OVERRIDE;
     void                RemoveFromScene();
     void                SetAngleHighlightArea(AngleHighlightArea area);
--- a/Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/CreateAngleMeasureCommand.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -29,8 +29,7 @@
     IViewport& viewport,
     ScenePoint2D           point)
     : CreateMeasureCommand(viewport)
-    , measureTool_(
-      boost::shared_ptr<AngleMeasureTool>(new AngleMeasureTool(viewport)))
+    , measureTool_(AngleMeasureTool::Create(viewport))
   {
     
     std::unique_ptr<IViewport::ILock> lock(viewport_.Lock());
--- a/Framework/Scene2DViewport/CreateLineMeasureCommand.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/CreateLineMeasureCommand.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -29,8 +29,7 @@
     IViewport& viewport,
     ScenePoint2D           point)
     : CreateMeasureCommand(viewport)
-    , measureTool_(
-      boost::shared_ptr<LineMeasureTool>(new LineMeasureTool(viewport)))
+    , measureTool_(LineMeasureTool::Create(viewport))
   {
     
     std::unique_ptr<IViewport::ILock> lock(viewport_.Lock());
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/LineMeasureTool.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -44,6 +44,14 @@
 
   }
 
+  boost::shared_ptr<LineMeasureTool> LineMeasureTool::Create(IViewport& viewport)
+  {
+    boost::shared_ptr<LineMeasureTool> obj(new LineMeasureTool(viewport));
+    obj->MeasureTool::PostConstructor();
+    obj->RefreshScene();
+    return obj;
+  }
+
   LineMeasureTool::~LineMeasureTool()
   {
     // this measuring tool is a RABI for the corresponding visual layers
--- a/Framework/Scene2DViewport/LineMeasureTool.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/LineMeasureTool.h	Mon Mar 16 11:19:50 2020 +0100
@@ -38,7 +38,7 @@
   class LineMeasureTool : public MeasureTool
   {
   public:
-    LineMeasureTool(IViewport& viewport);
+    static boost::shared_ptr<LineMeasureTool> Create(IViewport& viewport);
 
     ~LineMeasureTool();
 
@@ -67,6 +67,8 @@
     LineHighlightArea LineHitTest(ScenePoint2D p);
 
   private:
+    LineMeasureTool(IViewport& viewport);
+
     virtual void        RefreshScene() ORTHANC_OVERRIDE;
     void                RemoveFromScene();
     void                SetLineHighlightArea(LineHighlightArea area);
--- a/Framework/Scene2DViewport/MeasureTool.cpp	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/MeasureTool.cpp	Mon Mar 16 11:19:50 2020 +0100
@@ -52,10 +52,14 @@
     : viewport_(viewport)
     , enabled_(true)
   {
+
+  }
+
+  void MeasureTool::PostConstructor()
+  {
     std::unique_ptr<IViewport::ILock> lock(viewport_.Lock());
     ViewportController& controller = lock->GetController();
 
-    // TODO => Move this out of constructor
     Register<ViewportController::SceneTransformChanged>(
       controller, 
       &MeasureTool::OnSceneTransformChanged);
--- a/Framework/Scene2DViewport/MeasureTool.h	Mon Mar 16 11:12:39 2020 +0100
+++ b/Framework/Scene2DViewport/MeasureTool.h	Mon Mar 16 11:19:50 2020 +0100
@@ -115,6 +115,8 @@
   protected:
     MeasureTool(IViewport& viewport);
 
+    void PostConstructor();
+
     /**
     The measuring tool may exist in a standalone fashion, without any available
     scene (because the controller is dead or dying). This call allows to check