changeset 1064:af4b9cba905f broker

simplify how observers are regsitered, and how callables are created
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 15 Oct 2019 13:46:01 +0200
parents 3e8f59cefec6
children 9d42f89b8c3c
files Framework/Loaders/LoaderStateMachine.cpp Framework/Loaders/LoaderStateMachine.h Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h Framework/Messages/ICallable.h Framework/Messages/IObservable.cpp Framework/Messages/IObservable.h Framework/Messages/IObserver.h Framework/Messages/ObserverBase.h Framework/Scene2DViewport/MeasureTool.cpp Framework/Scene2DViewport/MeasureTool.h
diffstat 11 files changed, 99 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Loaders/LoaderStateMachine.cpp	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Loaders/LoaderStateMachine.cpp	Tue Oct 15 13:46:01 2019 +0200
@@ -159,33 +159,27 @@
   LoaderStateMachine::LoaderStateMachine(IOracle& oracle,
                                          IObservable& oracleObservable) :
     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>
-      (shared_from_this(), &LoaderStateMachine::HandleSuccessMessage));
+    oracleObservable.RegisterObserver<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage>
+      (*this, &LoaderStateMachine::HandleSuccessMessage);
 
-    oracleObservable.RegisterObserverCallback(
-      new Callable<LoaderStateMachine, GetOrthancImageCommand::SuccessMessage>
-      (shared_from_this(), &LoaderStateMachine::HandleSuccessMessage));
+    oracleObservable.RegisterObserver<LoaderStateMachine, GetOrthancImageCommand::SuccessMessage>
+      (*this, &LoaderStateMachine::HandleSuccessMessage);
 
-    oracleObservable.RegisterObserverCallback(
-      new Callable<LoaderStateMachine, GetOrthancWebViewerJpegCommand::SuccessMessage>
-      (shared_from_this(), &LoaderStateMachine::HandleSuccessMessage));
+    oracleObservable.RegisterObserver<LoaderStateMachine, GetOrthancWebViewerJpegCommand::SuccessMessage>
+      (*this, &LoaderStateMachine::HandleSuccessMessage);
 
-    oracleObservable.RegisterObserverCallback(
-      new Callable<LoaderStateMachine, OracleCommandExceptionMessage>
-      (shared_from_this(), &LoaderStateMachine::HandleExceptionMessage));
+    oracleObservable.RegisterObserver<LoaderStateMachine, OracleCommandExceptionMessage>
+      (*this, &LoaderStateMachine::HandleExceptionMessage);
   }
 
   LoaderStateMachine::~LoaderStateMachine()
   {
-    oracleObservable_.Unregister(this);
     LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::~LoaderStateMachine()";
     Clear();
   }
--- a/Framework/Loaders/LoaderStateMachine.h	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Loaders/LoaderStateMachine.h	Tue Oct 15 13:46:01 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"
@@ -95,7 +95,6 @@
     typedef std::list<IOracleCommand*>  PendingCommands;
 
     IOracle&         oracle_;
-    IObservable&     oracleObservable_;
     bool             active_;
     unsigned int     simultaneousDownloads_;
     PendingCommands  pendingCommands_;
--- a/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp	Tue Oct 15 13:46:01 2019 +0200
@@ -422,29 +422,24 @@
                                                                              IOracle& oracle,
                                                                              IObservable& oracleObservable) :
     oracle_(oracle),
-    oracleObservable_(oracleObservable),
     active_(false),
     simultaneousDownloads_(4),
     volume_(volume),
     sorter_(new BasicFetchingItemsSorter::Factory),
     volumeImageReadyInHighQuality_(false)
   {
-    oracleObservable.RegisterObserverCallback(
-      new Callable<OrthancSeriesVolumeProgressiveLoader, OrthancRestApiCommand::SuccessMessage>
-      (shared_from_this(), &OrthancSeriesVolumeProgressiveLoader::LoadGeometry));
-
-    oracleObservable.RegisterObserverCallback(
-      new Callable<OrthancSeriesVolumeProgressiveLoader, GetOrthancImageCommand::SuccessMessage>
-      (shared_from_this(), &OrthancSeriesVolumeProgressiveLoader::LoadBestQualitySliceContent));
-
-    oracleObservable.RegisterObserverCallback(
-      new Callable<OrthancSeriesVolumeProgressiveLoader, GetOrthancWebViewerJpegCommand::SuccessMessage>
-      (shared_from_this(), &OrthancSeriesVolumeProgressiveLoader::LoadJpegSliceContent));
+    oracleObservable.RegisterObserver<OrthancSeriesVolumeProgressiveLoader, OrthancRestApiCommand::SuccessMessage>
+      (*this, &OrthancSeriesVolumeProgressiveLoader::LoadGeometry);
+  
+    oracleObservable.RegisterObserver<OrthancSeriesVolumeProgressiveLoader, GetOrthancImageCommand::SuccessMessage>
+      (*this, &OrthancSeriesVolumeProgressiveLoader::LoadBestQualitySliceContent);
+    
+    oracleObservable.RegisterObserver<OrthancSeriesVolumeProgressiveLoader, GetOrthancWebViewerJpegCommand::SuccessMessage>
+      (*this, &OrthancSeriesVolumeProgressiveLoader::LoadJpegSliceContent);
   }
 
   OrthancSeriesVolumeProgressiveLoader::~OrthancSeriesVolumeProgressiveLoader()
   {
-    oracleObservable_.Unregister(this);
     LOG(TRACE) << "OrthancSeriesVolumeProgressiveLoader::~OrthancSeriesVolumeProgressiveLoader()";
   }
 
--- a/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h	Tue Oct 15 13:46:01 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"
@@ -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 15 12:22:44 2019 +0200
+++ b/Framework/Messages/ICallable.h	Tue Oct 15 13:46:01 2019 +0200
@@ -35,7 +35,7 @@
 {
   // 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:
@@ -64,14 +64,14 @@
   class Callable : public MessageHandler<TMessage>
   {
   private:
-    typedef void (TObserver::* MemberFunction) (const TMessage&);
+    typedef void (TObserver::* MemberMethod) (const TMessage&);
 
     boost::weak_ptr<IObserver>  observer_;
-    MemberFunction              function_;
+    MemberMethod                function_;
 
   public:
     Callable(boost::shared_ptr<TObserver> observer,
-             MemberFunction function) :
+             MemberMethod function) :
       observer_(observer),
       function_(function)
     {
--- a/Framework/Messages/IObservable.cpp	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Messages/IObservable.cpp	Tue Oct 15 13:46:01 2019 +0200
@@ -118,6 +118,11 @@
             (*it)->Apply(message);
           }
         }
+        else
+        {
+          // TODO => Remove "it" from the list of callables => This
+          // allows to suppress the need for "Unregister()"
+        }
       }
     }
   }
--- a/Framework/Messages/IObservable.h	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Messages/IObservable.h	Tue Oct 15 13:46:01 2019 +0200
@@ -44,12 +44,12 @@
     void EmitMessageInternal(const IObserver* receiver,
                              const IMessage& message);
 
+    // Takes ownsership of the callable
+    void RegisterObserverCallback(ICallable* callable);
+
   public:
     virtual ~IObservable();
 
-    // Takes ownsership
-    void RegisterObserverCallback(ICallable* callable);
-
     // TODO - Remove this?
     void Unregister(IObserver* observer);
 
@@ -60,5 +60,13 @@
 
     // Takes ownsership
     void RegisterForwarder(IMessageForwarder* forwarder);
+
+    template<typename TObserver,
+             typename TMessage>
+    void RegisterObserver(TObserver& observer,
+                          void (TObserver::* MemberMethod) (const TMessage&))
+    {
+      RegisterObserverCallback(new Callable<TObserver, TMessage>(observer.GetSharedObserver(), MemberMethod));
+    }
   };
 }
--- a/Framework/Messages/IObserver.h	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Messages/IObserver.h	Tue Oct 15 13:46:01 2019 +0200
@@ -22,7 +22,6 @@
 #pragma once
 
 #include <boost/noncopyable.hpp>
-#include <boost/enable_shared_from_this.hpp>
 
 namespace OrthancStone 
 {
@@ -37,11 +36,4 @@
     {
     }
   };
-
-  template <typename T>
-  class ObserverBase : 
-    public IObserver,
-    public boost::enable_shared_from_this<T>    
-  {
-  };
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Messages/ObserverBase.h	Tue Oct 15 13:46:01 2019 +0200
@@ -0,0 +1,58 @@
+/**
+ * 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 <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 a constructor");
+      }
+    }
+
+    template <typename TMessage>
+    ICallable* CreateCallable(void (TObserver::* MemberMethod) (const TMessage&))
+    {
+      return new Callable<TObserver, TMessage>(GetSharedObserver(), MemberMethod);
+    }
+  };
+}
--- a/Framework/Scene2DViewport/MeasureTool.cpp	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureTool.cpp	Tue Oct 15 13:46:01 2019 +0200
@@ -84,9 +84,8 @@
     : controllerW_(controllerW)
     , enabled_(true)
   {
-    GetController()->RegisterObserverCallback(
-      new Callable<MeasureTool, ViewportController::SceneTransformChanged>
-      (shared_from_this(), &MeasureTool::OnSceneTransformChanged));
+    GetController()->RegisterObserver<MeasureTool, ViewportController::SceneTransformChanged>
+      (*this, &MeasureTool::OnSceneTransformChanged);
   }
 
 
--- a/Framework/Scene2DViewport/MeasureTool.h	Tue Oct 15 12:22:44 2019 +0200
+++ b/Framework/Scene2DViewport/MeasureTool.h	Tue Oct 15 13:46:01 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>