changeset 1440:49f31fa332b3 loader-injection-feature

Merge from default.
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 26 May 2020 09:52:09 +0200
parents 758fb6958c20 (current diff) 4e233e3ea53b (diff)
children 60e30d73e2aa
files
diffstat 10 files changed, 127 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/Deprecated/Applications/Generic/GuiAdapter.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Deprecated/Applications/Generic/GuiAdapter.cpp	Tue May 26 09:52:09 2020 +0200
@@ -56,6 +56,8 @@
     return os;
   }
 
+  int GuiAdapter::s_instanceCount = 0;
+
 #if ORTHANC_ENABLE_WASM == 1
   void GuiAdapter::Run(GuiAdapterRunFunc /*func*/, void* /*cookie*/)
   {
@@ -984,7 +986,7 @@
         while (SDL_PollEvent(&sdlEvent) != 0)
         {
           if ( (sdlEvent.type >= SDL_USEREVENT) && 
-               (sdlEvent.type <= SDL_USEREVENT) )
+               (sdlEvent.type < SDL_LASTEVENT) )
           {
             // we don't want to have multiple events with the same event.type
             userEventsMap[sdlEvent.type] = sdlEvent;
@@ -1132,9 +1134,8 @@
         
           OnSdlGenericEvent(sdlEvent);
         }
+        SDL_Delay(1);
       }
-
-      SDL_Delay(1);
     }
   }
 #endif
--- a/Deprecated/Applications/Generic/GuiAdapter.h	Tue May 19 07:39:03 2020 +0200
+++ b/Deprecated/Applications/Generic/GuiAdapter.h	Tue May 26 09:52:09 2020 +0200
@@ -249,9 +249,13 @@
   public:
     GuiAdapter()
     {
-      static int instanceCount = 0;
-      ORTHANC_ASSERT(instanceCount == 0);
-      instanceCount = 1;
+      ORTHANC_ASSERT(s_instanceCount == 0);
+      s_instanceCount = 1;
+    }
+
+    ~GuiAdapter()
+    {
+      s_instanceCount -= 1;
     }
 
     /**
@@ -371,5 +375,7 @@
     deals with this)
     */
     void ViewportsUpdateSize();
+
+    static int s_instanceCount;
   };
 }
--- a/Framework/Loaders/GenericLoadersContext.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Framework/Loaders/GenericLoadersContext.cpp	Tue May 26 09:52:09 2020 +0200
@@ -108,7 +108,7 @@
 
   GenericLoadersContext::~GenericLoadersContext()
   {
-    LOG(WARNING) << "scheduled commands: " << scheduler_->GetTotalScheduled()
+    LOG(INFO) << "scheduled commands: " << scheduler_->GetTotalScheduled()
                  << ", processed commands: " << scheduler_->GetTotalProcessed();
     scheduler_.reset();
     //LOG(INFO) << "counter: " << scheduler_.use_count();
--- a/Framework/Loaders/LoaderCache.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Framework/Loaders/LoaderCache.cpp	Tue May 26 09:52:09 2020 +0200
@@ -164,44 +164,24 @@
     }
   }
   
-  /**
-  This method allows to convert a list of string into a string by 
-  sorting the strings then joining them
-  */
-  static std::string SortAndJoin(const std::vector<std::string>& stringList)
+  std::string LoaderCache::BuildDicomStructureSetLoaderKey(
+    const std::string& instanceUuid,
+    const std::string& uniqueKey)
   {
-    if (stringList.size() == 0)
-    {
-      return "";
-    } 
-    else
-    {
-      std::vector<std::string> sortedStringList = stringList;
-      std::sort(sortedStringList.begin(), sortedStringList.end());
-      std::stringstream s;
-      s << sortedStringList[0];
-      for (size_t i = 1; i < sortedStringList.size(); ++i)
-      {
-        s << "-" << sortedStringList[i];
-      }
-      return s.str();
-    }
+    return instanceUuid + "_" + uniqueKey;
   }
-  
-  boost::shared_ptr<DicomStructureSetLoader> 
-    LoaderCache::GetDicomStructureSetLoader(
+
+  boost::shared_ptr<DicomStructureSetLoader> LoaderCache::GetDicomStructureSetLoader(
       std::string inInstanceUuid, 
-      const std::vector<std::string>& initiallyVisibleStructures)
+      const std::vector<std::string>& initiallyVisibleStructures,
+      const std::string& uniqueKey)
   {
     try
     {
       // normalize keys a little
       NormalizeUuid(inInstanceUuid);
 
-      std::string initiallyVisibleStructuresKey = 
-        SortAndJoin(initiallyVisibleStructures);
-
-      std::string entryKey = inInstanceUuid + "_" + initiallyVisibleStructuresKey;
+      std::string entryKey = BuildDicomStructureSetLoaderKey(inInstanceUuid, uniqueKey);
 
       // find in cache
       if (dicomStructureSetLoaders_.find(entryKey) == dicomStructureSetLoaders_.end())
--- a/Framework/Loaders/LoaderCache.h	Tue May 19 07:39:03 2020 +0200
+++ b/Framework/Loaders/LoaderCache.h	Tue May 26 09:52:09 2020 +0200
@@ -60,10 +60,24 @@
     boost::shared_ptr<OrthancMultiframeVolumeLoader>
       GetMultiframeVolumeLoader(std::string instanceUuid);
 
+    /**
+    The DicomStructureSetLoader instances are stored in a map and indexed
+    by a key built from instanceUuid and uniqueKey.
+
+    If instanceUuid and uniqueKey correspond to an already existing loader, it is returned.
+
+    Please note that initiallyVisibleStructures is only used if the call results in the creation
+    of a new loader. In that case, the value is passed to the constructor.
+    */
     boost::shared_ptr<DicomStructureSetLoader>
       GetDicomStructureSetLoader(
         std::string instanceUuid,
-        const std::vector<std::string>& initiallyVisibleStructures);
+        const std::vector<std::string>& initiallyVisibleStructures,
+        const std::string& uniqueKey = "");
+
+    std::string BuildDicomStructureSetLoaderKey(
+        const std::string& instanceUuid,
+        const std::string& uniqueKey = "");
 
     void ClearCache();
 
--- a/Framework/Oracle/ThreadedOracle.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Framework/Oracle/ThreadedOracle.cpp	Tue May 26 09:52:09 2020 +0200
@@ -396,7 +396,7 @@
     }
     else
     {
-      LOG(WARNING) << "Starting oracle with " << workers_.size() << " worker threads";
+      LOG(INFO) << "Starting oracle with " << workers_.size() << " worker threads";
       state_ = State_Running;
 
       for (unsigned int i = 0; i < workers_.size(); i++)
--- a/Framework/Volumes/VolumeSceneLayerSource.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Framework/Volumes/VolumeSceneLayerSource.cpp	Tue May 26 09:52:09 2020 +0200
@@ -22,6 +22,7 @@
 #include "VolumeSceneLayerSource.h"
 
 #include "../Scene2D/NullLayer.h"
+#include "../Viewport/IViewport.h"
 #include "../StoneException.h"
 
 #include <Core/OrthancException.h>
@@ -40,16 +41,20 @@
 
   void VolumeSceneLayerSource::ClearLayer()
   {
-    scene_.DeleteLayer(layerDepth_);
+    {
+      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      ViewportController& controller = lock->GetController();
+      Scene2D& scene = controller.GetScene();
+      scene.DeleteLayer(layerDepth_);
+    }
     lastPlane_.reset(NULL);
   }
 
-
   VolumeSceneLayerSource::VolumeSceneLayerSource(
-    Scene2D& scene,
+    boost::shared_ptr<OrthancStone::IViewport>  viewport,
     int layerDepth,
     const boost::shared_ptr<IVolumeSlicer>& slicer)
-    : scene_(scene)
+    : viewport_(viewport)
     , layerDepth_(layerDepth)
     , slicer_(slicer)
   {
@@ -57,11 +62,17 @@
     {
       throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
     }
-    ORTHANC_ASSERT(!scene_.HasLayer(layerDepth_));
 
-    // we need to book the scene layer depth by adding a dummy layer
-    std::unique_ptr<NullLayer> nullLayer(new NullLayer);
-    scene_.SetLayer(layerDepth_,nullLayer.release());
+    {
+      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      ViewportController& controller = lock->GetController();
+      Scene2D& scene = controller.GetScene();
+      ORTHANC_ASSERT(!scene.HasLayer(layerDepth_));
+
+      // we need to book the scene layer depth by adding a dummy layer
+      std::unique_ptr<NullLayer> nullLayer(new NullLayer);
+      scene.SetLayer(layerDepth_,nullLayer.release());
+    }
   }
 
   VolumeSceneLayerSource::~VolumeSceneLayerSource()
@@ -104,6 +115,10 @@
 
   void VolumeSceneLayerSource::Update(const CoordinateSystem3D& plane)
   {
+    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    ViewportController& controller = lock->GetController();
+    Scene2D& scene = controller.GetScene();
+
     assert(slicer_.get() != NULL);
     std::unique_ptr<IVolumeSlicer::IExtractedSlice> slice(slicer_->ExtractSlice(plane));
 
@@ -126,9 +141,9 @@
 
       if (configurator_.get() != NULL &&
           configurator_->GetRevision() != lastConfiguratorRevision_ &&
-          scene_.HasLayer(layerDepth_))
+          scene.HasLayer(layerDepth_))
       {
-        configurator_->ApplyStyle(scene_.GetLayer(layerDepth_));
+        configurator_->ApplyStyle(scene.GetLayer(layerDepth_));
       }
     }
     else
@@ -153,7 +168,7 @@
           configurator_->ApplyStyle(*layer);
         }
 
-        scene_.SetLayer(layerDepth_, layer.release());
+        scene.SetLayer(layerDepth_, layer.release());
       }
     }
   }
--- a/Framework/Volumes/VolumeSceneLayerSource.h	Tue May 19 07:39:03 2020 +0200
+++ b/Framework/Volumes/VolumeSceneLayerSource.h	Tue May 26 09:52:09 2020 +0200
@@ -28,6 +28,7 @@
 
 namespace OrthancStone
 {
+  class IViewport;
   /**
      This class applies one "volume slicer" to a "3D volume", in order
      to create one "2D scene layer" that will be set onto the "2D
@@ -38,7 +39,7 @@
   class VolumeSceneLayerSource : public boost::noncopyable
   {
   private:
-    Scene2D&                                  scene_;
+    boost::shared_ptr<OrthancStone::IViewport>  viewport_;
     int                                       layerDepth_;
     boost::shared_ptr<IVolumeSlicer>          slicer_;
     std::unique_ptr<ILayerStyleConfigurator>  configurator_;
@@ -50,7 +51,7 @@
     void ClearLayer();
 
   public:
-    VolumeSceneLayerSource(Scene2D& scene,
+    VolumeSceneLayerSource(boost::shared_ptr<OrthancStone::IViewport>  viewport,
                            int layerDepth,
                            const boost::shared_ptr<IVolumeSlicer>& slicer);
 
--- a/Samples/Common/RtViewerView.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Samples/Common/RtViewerView.cpp	Tue May 26 09:52:09 2020 +0200
@@ -312,7 +312,7 @@
     Scene2D& scene = controller.GetScene();
     int depth = scene.GetMaxDepth() + 1;
 
-    ctVolumeLayerSource_.reset(new OrthancStone::VolumeSceneLayerSource(scene, depth, volume));
+    ctVolumeLayerSource_.reset(new OrthancStone::VolumeSceneLayerSource(viewport_, depth, volume));
 
     if (style != NULL)
     {
@@ -328,7 +328,7 @@
     Scene2D& scene = controller.GetScene();
     int depth = scene.GetMaxDepth() + 1;
 
-    doseVolumeLayerSource_.reset(new OrthancStone::VolumeSceneLayerSource(scene, depth, volume));
+    doseVolumeLayerSource_.reset(new OrthancStone::VolumeSceneLayerSource(viewport_, depth, volume));
 
     if (style != NULL)
     {
@@ -343,6 +343,6 @@
     Scene2D& scene = controller.GetScene();
     int depth = scene.GetMaxDepth() + 1;
 
-    structLayerSource_.reset(new OrthancStone::VolumeSceneLayerSource(scene, depth, volume));
+    structLayerSource_.reset(new OrthancStone::VolumeSceneLayerSource(viewport_, depth, volume));
   }
 }
\ No newline at end of file
--- a/Samples/Sdl/RtViewer/RtViewerSdl.cpp	Tue May 19 07:39:03 2020 +0200
+++ b/Samples/Sdl/RtViewer/RtViewerSdl.cpp	Tue May 26 09:52:09 2020 +0200
@@ -259,44 +259,70 @@
       bool stop = false;
       while (!stop)
       {
-        bool paint = false;
-        SDL_Event event;
-        while (SDL_PollEvent(&event))
+        std::vector<SDL_Event> sdlEvents;
+        std::map<Uint32,SDL_Event> userEventsMap;
+        SDL_Event sdlEvent;
+
+        // FIRST: collect all pending events
+        while (SDL_PollEvent(&sdlEvent) != 0)
         {
-          if (event.type == SDL_QUIT)
+          if ( (sdlEvent.type >= SDL_USEREVENT) && 
+               (sdlEvent.type < SDL_LASTEVENT) )
+          {
+            // we don't want to have multiple refresh events ,
+            // and since every refresh event is a user event with a special type,
+            // we use a map
+            userEventsMap[sdlEvent.type] = sdlEvent;
+          }
+          else
+          {
+            sdlEvents.push_back(sdlEvent);
+          }
+        }
+
+        // SECOND: add all user events to sdlEvents
+        for (std::map<Uint32,SDL_Event>::const_iterator it = userEventsMap.begin(); it != userEventsMap.end(); ++it)
+          sdlEvents.push_back(it->second);
+
+        // now process the events
+        for (std::vector<SDL_Event>::const_iterator it = sdlEvents.begin(); it != sdlEvents.end(); ++it)
+        {
+          const SDL_Event& sdlEvent = *it;
+
+          if (sdlEvent.type == SDL_QUIT)
           {
             stop = true;
             break;
           }
-          else if (event.type == SDL_WINDOWEVENT &&
-                   (event.window.event == SDL_WINDOWEVENT_RESIZED ||
-                    event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED))
+          else if (sdlEvent.type == SDL_WINDOWEVENT &&
+                   (sdlEvent.window.event == SDL_WINDOWEVENT_RESIZED ||
+                    sdlEvent.window.event == SDL_WINDOWEVENT_SIZE_CHANGED))
           {
             boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
-              views, event.window.windowID);
+              views, sdlEvent.window.windowID);
 
             boost::shared_ptr<SdlViewport> sdlViewport =
               boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport());
 
-            sdlViewport->UpdateSize(event.window.data1, event.window.data2);
+            sdlViewport->UpdateSize(sdlEvent.window.data1, sdlEvent.window.data2);
           }
-          else if (event.type == SDL_WINDOWEVENT &&
-                   (event.window.event == SDL_WINDOWEVENT_SHOWN ||
-                    event.window.event == SDL_WINDOWEVENT_EXPOSED))
+          else if (sdlEvent.type == SDL_WINDOWEVENT &&
+                   (sdlEvent.window.event == SDL_WINDOWEVENT_SHOWN ||
+                    sdlEvent.window.event == SDL_WINDOWEVENT_EXPOSED))
           {
             boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
-              views, event.window.windowID);
+              views, sdlEvent.window.windowID);
             boost::shared_ptr<SdlViewport> sdlViewport =
               boost::dynamic_pointer_cast<SdlViewport>(view->GetViewport());
             sdlViewport->Paint();
           }
-          else if (event.type == SDL_KEYDOWN &&
-                   event.key.repeat == 0 /* Ignore key bounce */)
+          else if (sdlEvent.type == SDL_KEYDOWN &&
+                   sdlEvent.key.repeat == 0 /* Ignore key bounce */)
           {
             boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
-              views, event.window.windowID);
+              views, sdlEvent.window.windowID);
 
-            switch (event.key.keysym.sym)
+            switch (sdlEvent.key.keysym.sym)
             {
             case SDLK_f:
             {
@@ -322,21 +348,21 @@
               break;
             }
           }
-          else if (event.type == SDL_MOUSEBUTTONDOWN ||
-                   event.type == SDL_MOUSEMOTION ||
-                   event.type == SDL_MOUSEBUTTONUP)
+          else if (sdlEvent.type == SDL_MOUSEBUTTONDOWN ||
+                   sdlEvent.type == SDL_MOUSEMOTION ||
+                   sdlEvent.type == SDL_MOUSEBUTTONUP)
           {
             boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
-              views, event.window.windowID);
+              views, sdlEvent.window.windowID);
 
             std::auto_ptr<OrthancStone::IViewport::ILock> lock(view->GetViewport()->Lock());
             if (lock->HasCompositor())
             {
               OrthancStone::PointerEvent p;
               OrthancStoneHelpers::GetPointerEvent(p, lock->GetCompositor(),
-                                                   event, keyboardState, scancodeCount);
+                                                   sdlEvent, keyboardState, scancodeCount);
 
-              switch (event.type)
+              switch (sdlEvent.type)
               {
               case SDL_MOUSEBUTTONDOWN:
                 lock->GetController().HandleMousePress(interactor, p,
@@ -362,15 +388,15 @@
               }
             }
           }
-          else if (event.type == SDL_MOUSEWHEEL)
+          else if (sdlEvent.type == SDL_MOUSEWHEEL)
           {
             boost::shared_ptr<RtViewerView> view = GetViewFromWindowId(
-              views, event.window.windowID);
+              views, sdlEvent.window.windowID);
 
             int delta = 0;
-            if (event.wheel.y < 0)
+            if (sdlEvent.wheel.y < 0)
               delta = -1;
-            if (event.wheel.y > 0)
+            if (sdlEvent.wheel.y > 0)
               delta = 1;
 
             view->Scroll(delta);
@@ -381,8 +407,10 @@
             {
               boost::shared_ptr<SdlViewport> sdlViewport =
                 boost::dynamic_pointer_cast<SdlViewport>(views[i]->GetViewport());
-              if (sdlViewport->IsRefreshEvent(event))
+              if (sdlViewport->IsRefreshEvent(sdlEvent))
+              {
                 sdlViewport->Paint();
+              }
             }
           }
         }