# HG changeset patch # User Benjamin Golinvaux # Date 1590479529 -7200 # Node ID 49f31fa332b3468b68b08e194476cc1c5d8875b6 # Parent 758fb6958c204753ed843aaa2b55eb137ff067ff# Parent 4e233e3ea53b216e732316385d68434e074b25a6 Merge from default. diff -r 758fb6958c20 -r 49f31fa332b3 Deprecated/Applications/Generic/GuiAdapter.cpp --- 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 diff -r 758fb6958c20 -r 49f31fa332b3 Deprecated/Applications/Generic/GuiAdapter.h --- 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; }; } diff -r 758fb6958c20 -r 49f31fa332b3 Framework/Loaders/GenericLoadersContext.cpp --- 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(); diff -r 758fb6958c20 -r 49f31fa332b3 Framework/Loaders/LoaderCache.cpp --- 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& stringList) + std::string LoaderCache::BuildDicomStructureSetLoaderKey( + const std::string& instanceUuid, + const std::string& uniqueKey) { - if (stringList.size() == 0) - { - return ""; - } - else - { - std::vector 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 - LoaderCache::GetDicomStructureSetLoader( + + boost::shared_ptr LoaderCache::GetDicomStructureSetLoader( std::string inInstanceUuid, - const std::vector& initiallyVisibleStructures) + const std::vector& 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()) diff -r 758fb6958c20 -r 49f31fa332b3 Framework/Loaders/LoaderCache.h --- 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 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 GetDicomStructureSetLoader( std::string instanceUuid, - const std::vector& initiallyVisibleStructures); + const std::vector& initiallyVisibleStructures, + const std::string& uniqueKey = ""); + + std::string BuildDicomStructureSetLoaderKey( + const std::string& instanceUuid, + const std::string& uniqueKey = ""); void ClearCache(); diff -r 758fb6958c20 -r 49f31fa332b3 Framework/Oracle/ThreadedOracle.cpp --- 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++) diff -r 758fb6958c20 -r 49f31fa332b3 Framework/Volumes/VolumeSceneLayerSource.cpp --- 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 @@ -40,16 +41,20 @@ void VolumeSceneLayerSource::ClearLayer() { - scene_.DeleteLayer(layerDepth_); + { + std::unique_ptr lock(viewport_->Lock()); + ViewportController& controller = lock->GetController(); + Scene2D& scene = controller.GetScene(); + scene.DeleteLayer(layerDepth_); + } lastPlane_.reset(NULL); } - VolumeSceneLayerSource::VolumeSceneLayerSource( - Scene2D& scene, + boost::shared_ptr viewport, int layerDepth, const boost::shared_ptr& 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(new NullLayer); - scene_.SetLayer(layerDepth_,nullLayer.release()); + { + std::unique_ptr 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(new NullLayer); + scene.SetLayer(layerDepth_,nullLayer.release()); + } } VolumeSceneLayerSource::~VolumeSceneLayerSource() @@ -104,6 +115,10 @@ void VolumeSceneLayerSource::Update(const CoordinateSystem3D& plane) { + std::unique_ptr lock(viewport_->Lock()); + ViewportController& controller = lock->GetController(); + Scene2D& scene = controller.GetScene(); + assert(slicer_.get() != NULL); std::unique_ptr 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()); } } } diff -r 758fb6958c20 -r 49f31fa332b3 Framework/Volumes/VolumeSceneLayerSource.h --- 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 viewport_; int layerDepth_; boost::shared_ptr slicer_; std::unique_ptr configurator_; @@ -50,7 +51,7 @@ void ClearLayer(); public: - VolumeSceneLayerSource(Scene2D& scene, + VolumeSceneLayerSource(boost::shared_ptr viewport, int layerDepth, const boost::shared_ptr& slicer); diff -r 758fb6958c20 -r 49f31fa332b3 Samples/Common/RtViewerView.cpp --- 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 diff -r 758fb6958c20 -r 49f31fa332b3 Samples/Sdl/RtViewer/RtViewerSdl.cpp --- 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 sdlEvents; + std::map 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::const_iterator it = userEventsMap.begin(); it != userEventsMap.end(); ++it) + sdlEvents.push_back(it->second); + + // now process the events + for (std::vector::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 view = GetViewFromWindowId( - views, event.window.windowID); + views, sdlEvent.window.windowID); boost::shared_ptr sdlViewport = boost::dynamic_pointer_cast(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 view = GetViewFromWindowId( - views, event.window.windowID); + views, sdlEvent.window.windowID); boost::shared_ptr sdlViewport = boost::dynamic_pointer_cast(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 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 view = GetViewFromWindowId( - views, event.window.windowID); + views, sdlEvent.window.windowID); std::auto_ptr 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 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 = boost::dynamic_pointer_cast(views[i]->GetViewport()); - if (sdlViewport->IsRefreshEvent(event)) + if (sdlViewport->IsRefreshEvent(sdlEvent)) + { sdlViewport->Paint(); + } } } }