changeset 322:a902a07769d4 am-2

wip: preload slice
author am@osimis.io
date Mon, 15 Oct 2018 22:43:02 +0200
parents 56b2e47d3c0c
children dbfe2e9e5020
files Framework/SmartLoader.cpp Framework/SmartLoader.h Framework/Toolbox/Slice.h Platforms/Wasm/WasmPlatformApplicationAdapter.cpp
diffstat 4 files changed, 80 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/SmartLoader.cpp	Fri Oct 12 14:53:38 2018 +0200
+++ b/Framework/SmartLoader.cpp	Mon Oct 15 22:43:02 2018 +0200
@@ -31,8 +31,9 @@
 {
     enum CachedSliceStatus
     {
-      CachedSliceStatus_Loading,
-      CachedSliceStatus_Loaded
+      CachedSliceStatus_ScheduledToLoad,
+      CachedSliceStatus_GeometryLoaded,
+      CachedSliceStatus_ImageLoaded
     };
 
   class SmartLoader::CachedSlice : public LayerSourceBase
@@ -103,10 +104,11 @@
     // in both cases, we must be carefull about objects lifecycle !!!
 
     std::auto_ptr<ILayerSource> layerSource;
+    std::string sliceKeyId = instanceId + ":" + std::to_string(frame);
 
-    if (cachedSlices_.find(instanceId) != cachedSlices_.end() && cachedSlices_[instanceId]->status_ == CachedSliceStatus_Loaded)
+    if (cachedSlices_.find(sliceKeyId) != cachedSlices_.end()) // && cachedSlices_[sliceKeyId]->status_ == CachedSliceStatus_Loaded)
     {
-      layerSource.reset(cachedSlices_[instanceId]->Clone());
+      layerSource.reset(cachedSlices_[sliceKeyId]->Clone());
     }
     else
     {
@@ -140,36 +142,56 @@
 
   }
 
+  void SmartLoader::PreloadSlice(const std::string instanceId, unsigned int frame)
+  {
+    // TODO: check if it is already in the cache
 
-  void SmartLoader::LoadStudyList()
-  {
-    //    orthancApiClient_.ScheduleGetJsonRequest("/studies");
+    // create the slice in the cache with "empty" data
+    boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_));
+    cachedSlice->slice_.reset(new Slice(instanceId, frame));
+    cachedSlice->status_ = CachedSliceStatus_ScheduledToLoad;
+    std::string sliceKeyId = instanceId + ":" + std::to_string(frame);
+
+    cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice);
+
+    std::auto_ptr<ILayerSource> layerSource(new OrthancFrameLayerSource(IObserver::broker_, orthancApiClient_));
+
+    dynamic_cast<OrthancFrameLayerSource*>(layerSource.get())->SetImageQuality(imageQuality_);
+    layerSource->RegisterObserverCallback(new Callable<SmartLoader, ILayerSource::GeometryReadyMessage>(*this, &SmartLoader::OnLayerGeometryReady));
+    layerSource->RegisterObserverCallback(new Callable<SmartLoader, ILayerSource::ImageReadyMessage>(*this, &SmartLoader::OnImageReady));
+    layerSource->RegisterObserverCallback(new Callable<SmartLoader, ILayerSource::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady));
+    dynamic_cast<OrthancFrameLayerSource*>(layerSource.get())->LoadFrame(instanceId, frame);
+
+    // keep a ref to the LayerSource until the slice is fully loaded and saved to cache
+    preloadingInstances_[sliceKeyId] = boost::shared_ptr<ILayerSource>(layerSource.release());
   }
 
-  void PreloadStudy(const std::string studyId)
-  {
-    /* TODO */
-  }
 
-  void PreloadSeries(const std::string seriesId)
-  {
-    /* TODO */
-  }
+//  void PreloadStudy(const std::string studyId)
+//  {
+//    /* TODO */
+//  }
+
+//  void PreloadSeries(const std::string seriesId)
+//  {
+//    /* TODO */
+//  }
 
 
   void SmartLoader::OnLayerGeometryReady(const ILayerSource::GeometryReadyMessage& message)
   {
     OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_);
-    // save the slice
+
+    // save/replace the slice in cache
     const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount()
-    std::string instanceId = slice.GetOrthancInstanceId();
+    std::string sliceKeyId = slice.GetOrthancInstanceId() + ":" + std::to_string(slice.GetFrame());
 
-    CachedSlice* cachedSlice = new CachedSlice(IObserver::broker_);
+    boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_));
     cachedSlice->slice_.reset(slice.Clone());
     cachedSlice->effectiveQuality_ = source.GetImageQuality();
-    cachedSlice->status_ = CachedSliceStatus_Loading;
+    cachedSlice->status_ = CachedSliceStatus_GeometryLoaded;
 
-    cachedSlices_[instanceId] = boost::shared_ptr<CachedSlice>(cachedSlice);
+    cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice);
 
     // re-emit original Layer message to observers
     EmitMessage(message);
@@ -179,17 +201,17 @@
   {
     OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_);
 
-    // save the slice
+    // save/replace the slice in cache
     const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ?
-    std::string instanceId = slice.GetOrthancInstanceId();
+    std::string sliceKeyId = slice.GetOrthancInstanceId() + ":" + std::to_string(slice.GetFrame());
 
     boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_));
     cachedSlice->image_ = message.image_;
     cachedSlice->effectiveQuality_ = message.imageQuality_;
     cachedSlice->slice_.reset(message.slice_.Clone());
-    cachedSlice->status_ = CachedSliceStatus_Loaded;
+    cachedSlice->status_ = CachedSliceStatus_ImageLoaded;
 
-    cachedSlices_[instanceId] = cachedSlice;
+    cachedSlices_[sliceKeyId] = cachedSlice;
 
     // re-emit original Layer message to observers
     EmitMessage(message);
@@ -197,6 +219,16 @@
 
   void SmartLoader::OnLayerReady(const ILayerSource::LayerReadyMessage& message)
   {
+    OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_);
+    const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ?
+    std::string sliceKeyId = slice.GetOrthancInstanceId() + ":" + std::to_string(slice.GetFrame());
+
+    // remove the slice from the preloading slices now that it has been fully loaded and it is referenced in the cache
+    if (preloadingInstances_.find(sliceKeyId) != preloadingInstances_.end())
+    {
+      preloadingInstances_.erase(sliceKeyId);
+    }
+
     // re-emit original Layer message to observers
     EmitMessage(message);
   }
--- a/Framework/SmartLoader.h	Fri Oct 12 14:53:38 2018 +0200
+++ b/Framework/SmartLoader.h	Mon Oct 15 22:43:02 2018 +0200
@@ -38,17 +38,18 @@
     typedef std::map<std::string, boost::shared_ptr<SmartLoader::CachedSlice>> CachedSlices;
     CachedSlices cachedSlices_;
 
+    typedef std::map<std::string, boost::shared_ptr<ILayerSource>> PreloadingInstances;
+    PreloadingInstances preloadingInstances_;
+
     SliceImageQuality     imageQuality_;
     OrthancApiClient&     orthancApiClient_;
 
-    int studyListRequest_;
-
   public:
     SmartLoader(MessageBroker& broker, OrthancApiClient& orthancApiClient);  // TODO: add maxPreloadStorageSizeInBytes
 
-    void PreloadStudy(const std::string studyId);
-    void PreloadSeries(const std::string seriesId);
-    void LoadStudyList();
+//    void PreloadStudy(const std::string studyId);
+//    void PreloadSeries(const std::string seriesId);
+    void PreloadSlice(const std::string instanceId, unsigned int frame);
 
     void SetImageQuality(SliceImageQuality imageQuality) { imageQuality_ = imageQuality; }
 
--- a/Framework/Toolbox/Slice.h	Fri Oct 12 14:53:38 2018 +0200
+++ b/Framework/Toolbox/Slice.h	Mon Oct 15 22:43:02 2018 +0200
@@ -61,6 +61,16 @@
   public:
     Slice() :
       type_(Type_Invalid)
+    {
+    }
+
+
+    // this constructor is used to reference, i.e, a slice that is being loaded
+    Slice(const std::string& orthancInstanceId,
+          unsigned int frame) :
+      type_(Type_Invalid),
+      orthancInstanceId_(orthancInstanceId),
+      frame_(frame)
     {        
     }
 
--- a/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp	Fri Oct 12 14:53:38 2018 +0200
+++ b/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp	Mon Oct 15 22:43:02 2018 +0200
@@ -38,9 +38,14 @@
 
     void WasmPlatformApplicationAdapter::NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage)
     {
-      printf("NotifyStatusUpdateFromCppToWeb (TODO)\n");
-      UpdateStoneApplicationStatusFromCpp(statusUpdateMessage.c_str());
-      printf("NotifyStatusUpdateFromCppToWeb (DONE)\n");
+      try
+      {
+        UpdateStoneApplicationStatusFromCpp(statusUpdateMessage.c_str());
+      }
+      catch (...)
+      {
+        printf("Error while handling message to web\n");
+      }
     }
 
 }
\ No newline at end of file