changeset 381:19bd222283ae

uncoupling LayerReadyMessage from the creation of the renderer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 06 Nov 2018 15:36:06 +0100
parents ba5ad93f935a
children dd4c7e82b4be
files Framework/Layers/DicomStructureSetRendererFactory.cpp Framework/Layers/DicomStructureSetRendererFactory.h Framework/Layers/ILayerSource.h Framework/Layers/LayerSourceBase.cpp Framework/Layers/LayerSourceBase.h Framework/Layers/OrthancFrameLayerSource.cpp Framework/Layers/OrthancFrameLayerSource.h Framework/SmartLoader.cpp Framework/Widgets/LayerWidget.cpp Framework/dev.h
diffstat 10 files changed, 151 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Layers/DicomStructureSetRendererFactory.cpp	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/DicomStructureSetRendererFactory.cpp	Tue Nov 06 15:36:06 2018 +0100
@@ -126,11 +126,33 @@
   };
 
 
+  class DicomStructureSetRendererFactory::RendererFactory : public LayerReadyMessage::IRendererFactory
+  {
+  private:
+    DicomStructureSet&         structureSet_;
+    const CoordinateSystem3D&  slice_;
+
+  public:
+    RendererFactory(DicomStructureSet& structureSet,
+                    const CoordinateSystem3D&  slice) :
+      structureSet_(structureSet),
+      slice_(slice)
+    {
+    }
+
+    virtual ILayerRenderer* CreateRenderer() const
+    {
+      return new Renderer(structureSet_, slice_);
+    }
+  };
+  
+
   void DicomStructureSetRendererFactory::ScheduleLayerCreation(const CoordinateSystem3D& viewportSlice)
   {
     if (loader_.HasStructureSet())
     {
-      NotifyLayerReady(new Renderer(loader_.GetStructureSet(), viewportSlice), viewportSlice);
+      RendererFactory factory(loader_.GetStructureSet(), viewportSlice);
+      NotifyLayerReady(factory, viewportSlice);
     }
   }
 }
--- a/Framework/Layers/DicomStructureSetRendererFactory.h	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/DicomStructureSetRendererFactory.h	Tue Nov 06 15:36:06 2018 +0100
@@ -32,6 +32,7 @@
   {
   private:
     class Renderer;
+    class RendererFactory;
 
     virtual void NotifyGeometryReady(const IVolumeLoader& loader)
     {
--- a/Framework/Layers/ILayerSource.h	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/ILayerSource.h	Tue Nov 06 15:36:06 2018 +0100
@@ -59,29 +59,34 @@
 
     class LayerReadyMessage : public OriginMessage<MessageType_LayerSource_LayerReady, ILayerSource>
     {
+    public:
+      class IRendererFactory : public boost::noncopyable
+      {
+      public:
+        virtual ~IRendererFactory()
+        {
+        }
+
+        virtual ILayerRenderer* CreateRenderer() const = 0;
+      };
+    
     private:
-      std::auto_ptr<ILayerRenderer>  renderer_;
-      const CoordinateSystem3D&      slice_;
+      const IRendererFactory&    factory_;
+      const CoordinateSystem3D&  slice_;
 
     public:
       LayerReadyMessage(ILayerSource& origin,
-                        ILayerRenderer* renderer,  // Takes ownership => TODO Remove this!
+                        const IRendererFactory& rendererFactory,
                         const CoordinateSystem3D& slice) :
         OriginMessage(origin),
-        renderer_(renderer),
+        factory_(rendererFactory),
         slice_(slice)
       {
       }
 
-      // TODO - Remove this function
-      std::auto_ptr<ILayerRenderer>& GetRendererRaw()
+      ILayerRenderer* CreateRenderer() const
       {
-        return renderer_;
-      }
-
-      const ILayerRenderer& GetRenderer() const
-      {
-        return *renderer_;
+        return factory_.CreateRenderer();
       }
 
       const CoordinateSystem3D& GetSlice() const
--- a/Framework/Layers/LayerSourceBase.cpp	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/LayerSourceBase.cpp	Tue Nov 06 15:36:06 2018 +0100
@@ -45,10 +45,10 @@
     EmitMessage(ILayerSource::SliceChangedMessage(*this, slice));
   }
 
-  void LayerSourceBase::NotifyLayerReady(ILayerRenderer* layer,
+  void LayerSourceBase::NotifyLayerReady(const LayerReadyMessage::IRendererFactory& factory,
                                          const CoordinateSystem3D& slice)
   {
-    EmitMessage(ILayerSource::LayerReadyMessage(*this, layer, slice));
+    EmitMessage(ILayerSource::LayerReadyMessage(*this, factory, slice));
   }
 
   void LayerSourceBase::NotifyLayerError(const CoordinateSystem3D& slice)
--- a/Framework/Layers/LayerSourceBase.h	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/LayerSourceBase.h	Tue Nov 06 15:36:06 2018 +0100
@@ -39,7 +39,7 @@
 
     void NotifySliceChange(const Slice& slice);
 
-    void NotifyLayerReady(ILayerRenderer* layer,
+    void NotifyLayerReady(const LayerReadyMessage::IRendererFactory& factory,
                           const CoordinateSystem3D& slice);
 
     void NotifyLayerError(const CoordinateSystem3D& slice);
--- a/Framework/Layers/OrthancFrameLayerSource.cpp	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/OrthancFrameLayerSource.cpp	Tue Nov 06 15:36:06 2018 +0100
@@ -49,18 +49,35 @@
     LayerSourceBase::NotifyGeometryError();
   }
 
+
+  class OrthancFrameLayerSource::RendererFactory : public LayerReadyMessage::IRendererFactory
+  {
+  private:
+    const OrthancSlicesLoader::SliceImageReadyMessage&  message_;
+
+  public:
+    RendererFactory(const OrthancSlicesLoader::SliceImageReadyMessage& message) :
+      message_(message)
+    {
+    }
+
+    virtual ILayerRenderer* CreateRenderer() const
+    {
+      bool isFull = (message_.GetEffectiveQuality() == SliceImageQuality_FullPng ||
+                     message_.GetEffectiveQuality() == SliceImageQuality_FullPam);
+
+      return FrameRenderer::CreateRenderer(message_.GetImage(), message_.GetSlice(), isFull);
+    }
+  };
+
   void OrthancFrameLayerSource::OnSliceImageReady(const OrthancSlicesLoader::SliceImageReadyMessage& message)
   {
     // first notify that the image is ready (targeted to, i.e: an image cache)
     LayerSourceBase::NotifyImageReady(message.GetImage(), message.GetEffectiveQuality(), message.GetSlice());
 
     // then notify that the layer is ready for render
-    bool isFull = (message.GetEffectiveQuality() == SliceImageQuality_FullPng ||
-                   message.GetEffectiveQuality() == SliceImageQuality_FullPam);
-
-    LayerSourceBase::NotifyLayerReady(FrameRenderer::CreateRenderer(message.GetImage(), message.GetSlice(), isFull),
-                                      message.GetSlice().GetGeometry());
-
+    RendererFactory factory(message);
+    LayerSourceBase::NotifyLayerReady(factory, message.GetSlice().GetGeometry());
   }
 
   void OrthancFrameLayerSource::OnSliceImageError(const OrthancSlicesLoader::SliceImageErrorMessage& message)
--- a/Framework/Layers/OrthancFrameLayerSource.h	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Layers/OrthancFrameLayerSource.h	Tue Nov 06 15:36:06 2018 +0100
@@ -37,6 +37,8 @@
     //private OrthancSlicesLoader::ISliceLoaderObserver
   {
   private:
+    class RendererFactory;
+    
     OrthancSlicesLoader  loader_;
     SliceImageQuality    quality_;
 
--- a/Framework/SmartLoader.cpp	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/SmartLoader.cpp	Tue Nov 06 15:36:06 2018 +0100
@@ -40,6 +40,26 @@
   class SmartLoader::CachedSlice : public LayerSourceBase
   {
   public:
+    class RendererFactory : public LayerReadyMessage::IRendererFactory
+    {
+    private:
+      const CachedSlice&  that_;
+
+    public:
+      RendererFactory(const CachedSlice& that) :
+        that_(that)
+      {
+      }
+
+      virtual ILayerRenderer* CreateRenderer() const
+      {
+        bool isFull = (that_.effectiveQuality_ == SliceImageQuality_FullPng ||
+                       that_.effectiveQuality_ == SliceImageQuality_FullPam);
+
+        return FrameRenderer::CreateRenderer(*that_.image_, *that_.slice_, isFull);
+      }
+    };
+    
     unsigned int                    sliceIndex_;
     std::auto_ptr<Slice>            slice_;
     boost::shared_ptr<Orthanc::ImageAccessor>   image_;
@@ -73,10 +93,9 @@
       if (status_ == CachedSliceStatus_ImageLoaded)
       {
         LOG(WARNING) << "ScheduleLayerCreation for CachedSlice (image is loaded): " << slice_->GetOrthancInstanceId();
-        bool isFull = (effectiveQuality_ == SliceImageQuality_FullPng ||
-                       effectiveQuality_ == SliceImageQuality_FullPam);
-        LayerSourceBase::NotifyLayerReady(FrameRenderer::CreateRenderer(*image_, *slice_, isFull),
-                                          slice_->GetGeometry());
+
+        RendererFactory factory(*this);
+        LayerSourceBase::NotifyLayerReady(factory, slice_->GetGeometry());
       }
       else
       {
--- a/Framework/Widgets/LayerWidget.cpp	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/Widgets/LayerWidget.cpp	Tue Nov 06 15:36:06 2018 +0100
@@ -589,16 +589,7 @@
     if (LookupLayer(index, message.GetOrigin()))
     {
       LOG(INFO) << "Renderer ready for layer " << index;
-
-      // TODO -- REMOVE THIS UGLY STUFF
-      ILayerSource::LayerReadyMessage& ugly = const_cast<ILayerSource::LayerReadyMessage&>(message);
-      
-      if (ugly.GetRendererRaw().get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      
-      UpdateLayer(index, ugly.GetRendererRaw().release(), message.GetSlice());
+      UpdateLayer(index, message.CreateRenderer(), message.GetSlice());
     }
     
     EmitMessage(LayerWidget::ContentChangedMessage(*this));
--- a/Framework/dev.h	Tue Nov 06 14:59:20 2018 +0100
+++ b/Framework/dev.h	Tue Nov 06 15:36:06 2018 +0100
@@ -499,6 +499,30 @@
       private ISlicedVolume::IObserver
   {
   private:
+    class RendererFactory : public LayerReadyMessage::IRendererFactory
+    {
+    private:
+      const Orthanc::ImageAccessor&  frame_;
+      const Slice&                   slice_;
+      bool                           isFullQuality_;
+
+    public:
+      RendererFactory(const Orthanc::ImageAccessor& frame,
+                      const Slice& slice,
+                      bool isFullQuality) :
+        frame_(frame),
+        slice_(slice),
+        isFullQuality_(isFullQuality)
+      {
+      }
+
+      virtual ILayerRenderer* CreateRenderer() const
+      {
+        return FrameRenderer::CreateRenderer(frame_, slice_, isFullQuality_);
+      }
+    };
+
+
     OrthancVolumeImage&                 volume_;
     std::auto_ptr<VolumeImageGeometry>  axialGeometry_;
     std::auto_ptr<VolumeImageGeometry>  coronalGeometry_;
@@ -657,8 +681,9 @@
           }
 
           std::auto_ptr<Slice> slice(geometry.GetSlice(closest));
-          LayerSourceBase::NotifyLayerReady(
-            FrameRenderer::CreateRenderer(*frame, *slice, isFullQuality),
+
+          RendererFactory factory(*frame, *slice, isFullQuality);
+          LayerSourceBase::NotifyLayerReady(factory,
             //new SliceOutlineRenderer(slice),
             slice->GetGeometry());
           return;
@@ -840,6 +865,35 @@
   class SliceLocationSource : public LayerSourceBase
   {
   private:
+    class RendererFactory : public LayerReadyMessage::IRendererFactory
+    {
+    private:
+      double                     x1_;
+      double                     y1_;
+      double                     x2_;
+      double                     y2_;
+      const CoordinateSystem3D&  slice_;
+
+    public:
+      RendererFactory(double x1,
+                      double y1,
+                      double x2,
+                      double y2,
+                      const CoordinateSystem3D& slice) :
+        x1_(x1),
+        y1_(y1),
+        x2_(x2),
+        y2_(y2),
+        slice_(slice)
+      {
+      }
+
+      virtual ILayerRenderer* CreateRenderer() const
+      {
+        return new LineLayerRenderer(x1_, y1_, x2_, y2_, slice_);
+      }
+    };
+
     LayerWidget&  otherPlane_;
 
   public:
@@ -885,7 +939,8 @@
                                                  extent.GetX1(), extent.GetY1(),
                                                  extent.GetX2(), extent.GetY2()))
         {
-          NotifyLayerReady(new LineLayerRenderer(x1, y1, x2, y2, slice), reference.GetGeometry());
+          RendererFactory factory(x1, y1, x2, y2, slice);
+          NotifyLayerReady(factory, reference.GetGeometry());
         }
         else
         {