Mercurial > hg > orthanc-stone
changeset 2314:891aff56bbee refactoring
removed class GenericLoadersContext
line wrap: on
line diff
--- a/Applications/Samples/Common/RtViewerApp.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/Applications/Samples/Common/RtViewerApp.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -80,8 +80,9 @@ } } - RtViewerApp::RtViewerApp() : + RtViewerApp::RtViewerApp(StoneApplication::Context& context) : // Create the volumes that will be filled later on + context_(context), ctVolume_(boost::make_shared<DicomVolumeImage>()), doseVolume_(boost::make_shared<DicomVolumeImage>()), undoStack_(new UndoStack), @@ -89,9 +90,9 @@ { } - boost::shared_ptr<RtViewerApp> RtViewerApp::Create() + boost::shared_ptr<RtViewerApp> RtViewerApp::Create(StoneApplication::Context& context) { - boost::shared_ptr<RtViewerApp> thisOne(new RtViewerApp()); + boost::shared_ptr<RtViewerApp> thisOne(new RtViewerApp(context)); return thisOne; } @@ -128,7 +129,7 @@ // "true" means use progressive quality (jpeg 50 --> jpeg 90 --> 16-bit raw) // "false" means only using hi quality // TODO: add flag for quality - ctLoader_ = OrthancSeriesVolumeProgressiveLoader::Create(*loadersContext_, ctVolume_, true); + ctLoader_ = OrthancSeriesVolumeProgressiveLoader::Create(context_, ctVolume_, true); // better priority for CT vs dose and struct ctLoader_->SetSchedulingPriority(-100); @@ -137,8 +138,8 @@ // we need to store the CT loader to ask from geometry details later on when geometry is loaded geometryProvider_ = ctLoader_; - doseLoader_ = OrthancMultiframeVolumeLoader::Create(*loadersContext_, doseVolume_); - rtstructLoader_ = DicomStructureSetLoader::Create(*loadersContext_); + doseLoader_ = OrthancMultiframeVolumeLoader::Create(context_, doseVolume_); + rtstructLoader_ = DicomStructureSetLoader::Create(context_); } /**
--- a/Applications/Samples/Common/RtViewerApp.h Wed Sep 30 11:50:48 2026 +0200 +++ b/Applications/Samples/Common/RtViewerApp.h Wed Sep 30 13:56:32 2026 +0200 @@ -23,7 +23,6 @@ #pragma once #include "../../../OrthancStone/Sources/Loaders/DicomStructureSetLoader.h" -#include "../../../OrthancStone/Sources/Loaders/ILoadersContext.h" #include "../../../OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.h" #include "../../../OrthancStone/Sources/Loaders/OrthancSeriesVolumeProgressiveLoader.h" #include "../../../OrthancStone/Sources/Messages/IMessageEmitter.h" @@ -31,6 +30,7 @@ #include "../../../OrthancStone/Sources/Messages/ObserverBase.h" #include "../../../OrthancStone/Sources/Oracle/OracleCommandExceptionMessage.h" #include "../../../OrthancStone/Sources/Scene2DViewport/ViewportController.h" +#include "../../../OrthancStone/Sources/StoneApplication.h" #include "../../../OrthancStone/Sources/Viewport/DefaultViewportInteractor.h" #include "../../../OrthancStone/Sources/Viewport/IViewport.h" #include "../../../OrthancStone/Sources/Volumes/DicomVolumeImage.h" @@ -72,11 +72,10 @@ #if ORTHANC_ENABLE_SDL public: - void RunSdl(int argc, char* argv[]); + void RunSdl(); void SdlRunLoop(const std::vector<boost::shared_ptr<RtViewerView> >& views, DefaultViewportInteractor& interactor); private: - void ProcessOptions(int argc, char* argv[]); void HandleApplicationEvent(const SDL_Event& event); #elif ORTHANC_ENABLE_WASM public: @@ -96,12 +95,12 @@ VolumeImageGeometry GetMainGeometry(); - static boost::shared_ptr<RtViewerApp> Create(); + static boost::shared_ptr<RtViewerApp> Create(StoneApplication::Context& context); void CreateView(const std::string& canvasId, VolumeProjection projection); protected: - RtViewerApp(); + RtViewerApp(StoneApplication::Context& context); private: void CreateLoaders(); @@ -146,8 +145,7 @@ boost::shared_ptr<OrthancMultiframeVolumeLoader> doseLoader_; boost::shared_ptr<DicomStructureSetLoader> rtstructLoader_; - /** encapsulates resources shared by loaders */ - boost::shared_ptr<ILoadersContext> loadersContext_; + StoneApplication::Context& context_; /** another interface to the ctLoader object (that also implements the IVolumeSlicer interface), that serves as the
--- a/Applications/Samples/Sdl/RtViewer/RtViewerSdl.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/Applications/Samples/Sdl/RtViewer/RtViewerSdl.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -21,12 +21,12 @@ #include "../../Common/RtViewerApp.h" #include "../../Common/RtViewerView.h" +#include "../../Common/SampleHelpers.h" #include "../SdlHelpers.h" #include <EmbeddedResources.h> // Stone of Orthanc includes -#include "../../../../OrthancStone/Sources/Loaders/GenericLoadersContext.h" #include "../../../../OrthancStone/Sources/OpenGL/OpenGLIncludes.h" #include "../../../../OrthancStone/Sources/Platforms/Sdl/SdlOpenGLContext.h" #include "../../../../OrthancStone/Sources/StoneApplication.h" @@ -95,7 +95,8 @@ // only used in WASM at the moment } - void RtViewerApp::ProcessOptions(int argc, char* argv[]) + static void ProcessOptions(std::map<std::string, std::string>& arguments, + int argc, char* argv[]) { namespace po = boost::program_options; po::options_description desc("Usage"); @@ -135,54 +136,12 @@ std::string key = it->first; const po::variable_value& value = it->second; const std::string& strValue = value.as<std::string>(); - SetArgument(key, strValue); + arguments[key] = strValue; } } - void RtViewerApp::RunSdl(int argc, char* argv[]) + void RtViewerApp::RunSdl() { - ProcessOptions(argc, argv); - - /** - Url of the Orthanc instance - Typically, in a native application (Qt, SDL), it will be an absolute URL like "http://localhost:8042". In - wasm on the browser, it could be an absolute URL, provided you do not have cross-origin problems, or a relative - URL. In our wasm samples, it is set to "..", because we set up either a reverse proxy or an Orthanc ServeFolders - plugin that serves the main web application from an URL like "http://localhost:8042/stone-rtviewer" (with ".." - leading to the main Orthanc root URL) - */ - std::string orthancUrl = arguments_["orthanc"]; - - StoneApplication::Configuration configuration; - - { - Orthanc::WebServiceParameters p; - if (HasArgument("orthanc")) - { - p.SetUrl(orthancUrl); - } - if (HasArgument("user")) - { - ORTHANC_ASSERT(HasArgument("password")); - p.SetCredentials(GetArgument("user"), GetArgument("password")); - } - else - { - ORTHANC_ASSERT(!HasArgument("password")); - } - configuration.SetRemoteOrthancParameters(p); - } - - OrthancStone::StoneApplication::Initialize(configuration); - - /** - Create the shared loaders context - */ - loadersContext_.reset(new GenericLoadersContext(1, 4, 1)); - - // we are in SDL --> downcast to concrete type - boost::shared_ptr<GenericLoadersContext> loadersContext = boost::dynamic_pointer_cast<GenericLoadersContext>(loadersContext_); - CreateLoaders(); /** @@ -453,6 +412,30 @@ } } + + +static std::string GetArgument(const std::map<std::string, std::string>& arguments, + const std::string& key) +{ + std::map<std::string, std::string>::const_iterator found = arguments.find(key); + if (found == arguments.end()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return found->second; + } +} + + +static bool HasArgument(const std::map<std::string, std::string>& arguments, + const std::string& key) +{ + return (arguments.find(key) != arguments.end()); +} + + boost::weak_ptr<OrthancStone::RtViewerApp> g_app; /** @@ -469,9 +452,51 @@ try { - boost::shared_ptr<OrthancStone::RtViewerApp> app = OrthancStone::RtViewerApp::Create(); + std::map<std::string, std::string> arguments; + OrthancStone::ProcessOptions(arguments, argc, argv); + + /** + Url of the Orthanc instance + Typically, in a native application (Qt, SDL), it will be an absolute URL like "http://localhost:8042". In + wasm on the browser, it could be an absolute URL, provided you do not have cross-origin problems, or a relative + URL. In our wasm samples, it is set to "..", because we set up either a reverse proxy or an Orthanc ServeFolders + plugin that serves the main web application from an URL like "http://localhost:8042/stone-rtviewer" (with ".." + leading to the main Orthanc root URL) + */ + std::string orthancUrl = arguments["orthanc"]; + + OrthancStone::StoneApplication::Configuration configuration; + + { + Orthanc::WebServiceParameters p; + if (HasArgument(arguments, "orthanc")) + { + p.SetUrl(orthancUrl); + } + if (HasArgument(arguments, "user")) + { + ORTHANC_ASSERT(HasArgument(arguments, "password")); + p.SetCredentials(GetArgument(arguments, "user"), GetArgument(arguments, "password")); + } + else + { + ORTHANC_ASSERT(!HasArgument(arguments, "password")); + } + configuration.SetRemoteOrthancParameters(p); + } + + OrthancStone::StoneApplication::Initialize(configuration); + + boost::shared_ptr<OrthancStone::RtViewerApp> app = OrthancStone::RtViewerApp::Create( + OrthancStone::StoneApplication::GetInstance()); + + for (std::map<std::string, std::string>::const_iterator it = arguments.begin(); it != arguments.end(); ++it) + { + app->SetArgument(it->first, it->second); + } + g_app = app; - app->RunSdl(argc,argv); + app->RunSdl(); } catch (Orthanc::OrthancException& e) {
--- a/Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -29,7 +29,6 @@ #include "../SdlHelpers.h" #include "../../Common/SampleHelpers.h" -#include "../../../../OrthancStone/Sources/Loaders/GenericLoadersContext.h" #include "../../../../OrthancStone/Sources/Platforms/Sdl/SdlViewport.h" #include "../../../../OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.h" #include "../../../../OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.h" @@ -426,8 +425,6 @@ OrthancStone::SdlCairoViewport::Create("Stone of Orthanc", 800, 600); #endif - OrthancStone::GenericLoadersContext context(1, 4, 1); - { { std::string font;
--- a/Applications/Samples/WebAssembly/RtViewer/RtViewerWasm.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/Applications/Samples/WebAssembly/RtViewer/RtViewerWasm.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -21,10 +21,8 @@ #include "../../Common/RtViewerApp.h" #include "../../Common/RtViewerView.h" -#include "../../Common/SampleHelpers.h" // Stone of Orthanc includes -#include "../../../../OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyLoadersContext.h" #include "../../../../OrthancStone/Sources/Platforms/WebAssembly/WebGLViewport.h" #include "../../../../OrthancStone/Sources/StoneApplication.h" #include "../../../../OrthancStone/Sources/StoneException.h" @@ -157,12 +155,6 @@ OrthancStone::StoneApplication::Initialize(configuration); - loadersContext_.reset(new WebAssemblyLoadersContext(1, 4, 1)); - - // we are in WASM --> downcast to concrete type - boost::shared_ptr<WebAssemblyLoadersContext> loadersContext = - boost::dynamic_pointer_cast<WebAssemblyLoadersContext>(loadersContext_); - CreateLoaders(); CreateView("RtViewer_Axial", VolumeProjection_Axial); @@ -199,8 +191,11 @@ LOG(INFO) << "Endianness: " << Orthanc::EnumerationToString(Orthanc::Toolbox::DetectEndianness()); - g_app = OrthancStone::RtViewerApp::Create(); - + OrthancStone::StoneApplication::Configuration configuration; + OrthancStone::StoneApplication::Initialize(configuration); + + g_app = OrthancStone::RtViewerApp::Create(OrthancStone::StoneApplication::GetInstance()); + DISPATCH_JAVASCRIPT_EVENT("WasmModuleInitialized"); } EXTERN_CATCH_EXCEPTIONS;
--- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Wed Sep 30 13:56:32 2026 +0200 @@ -219,7 +219,6 @@ if (NOT ORTHANC_SANDBOXED AND ENABLE_THREADS AND ENABLE_WEB_CLIENT) list(APPEND ORTHANC_STONE_SOURCES - ${ORTHANC_STONE_ROOT}/Loaders/GenericLoadersContext.cpp ${ORTHANC_STONE_ROOT}/Platforms/Native/GenericOracleRunner.cpp ${ORTHANC_STONE_ROOT}/Platforms/Native/ThreadedOracle.cpp ${ORTHANC_STONE_ROOT}/Platforms/Native/NativeEnvironment.cpp
--- a/OrthancStone/Sources/Loaders/DicomStructureSetLoader.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/DicomStructureSetLoader.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -69,7 +69,7 @@ protected: explicit RestInstanceLookupHandler(DicomStructureSetLoader& loader) : - LoaderStateMachine(loader.loadersContext_), + LoaderStateMachine(loader.context_), loader_(loader) { } @@ -378,24 +378,21 @@ }; - DicomStructureSetLoader::DicomStructureSetLoader( - ILoadersContext& loadersContext) - : LoaderStateMachine(loadersContext) - , loadersContext_(loadersContext) - , revision_(0) - , countProcessedInstances_(0) - , countReferencedInstances_(0) - , structuresReady_(false) + DicomStructureSetLoader::DicomStructureSetLoader(StoneApplication::Context& context) : + LoaderStateMachine(context), + context_(context), + revision_(0), + countProcessedInstances_(0), + countReferencedInstances_(0), + structuresReady_(false) { // the default handler to retrieve slice geometry is RestInstanceLookupHandler instanceLookupHandler_ = RestInstanceLookupHandler::Create(*this); } - boost::shared_ptr<DicomStructureSetLoader> DicomStructureSetLoader::Create(ILoadersContext& loadersContext) + boost::shared_ptr<DicomStructureSetLoader> DicomStructureSetLoader::Create(StoneApplication::Context& context) { - boost::shared_ptr<DicomStructureSetLoader> obj( - new DicomStructureSetLoader( - loadersContext)); + boost::shared_ptr<DicomStructureSetLoader> obj(new DicomStructureSetLoader(context)); obj->LoaderStateMachine::PostConstructor(); return obj; }
--- a/OrthancStone/Sources/Loaders/DicomStructureSetLoader.h Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/DicomStructureSetLoader.h Wed Sep 30 13:56:32 2026 +0200 @@ -63,7 +63,7 @@ class RestInstanceLookupHandler; static boost::shared_ptr<DicomStructureSetLoader> Create( - ILoadersContext& loadersContext); + StoneApplication::Context& context); void SetInstanceLookupHandler(boost::shared_ptr<IInstanceLookupHandler> instanceLookupHandler) { @@ -109,7 +109,7 @@ // Only state of LoaderStateMachine class LoadStructure; // 1st state - ILoadersContext& loadersContext_; + StoneApplication::Context& context_; std::unique_ptr<DicomStructureSet> content_; uint64_t revision_; std::string instanceId_; @@ -143,6 +143,6 @@ void RetrieveReferencedSlices(const std::set<std::string>& nonEmptyInstances); protected: - explicit DicomStructureSetLoader(ILoadersContext& loadersContext); + explicit DicomStructureSetLoader(StoneApplication::Context& context); }; }
--- a/OrthancStone/Sources/Loaders/GenericLoadersContext.cpp Wed Sep 30 11:50:48 2026 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2023 Osimis S.A., Belgium - * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Lesser 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/>. - **/ - - -#include "GenericLoadersContext.h" - -#include "../Platforms/Native/ThreadedOracle.h" -#include "../StoneApplication.h" - -#include <boost/thread.hpp> - - -namespace OrthancStone -{ - class GenericLoadersContext::Locker : public ILoadersContext::ILock - { - private: - GenericLoadersContext& that_; - boost::recursive_mutex::scoped_lock lock_; - - public: - explicit Locker(GenericLoadersContext& that) : - that_(that), - lock_(that.mutex_) - { - if (!that_.scheduler_) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - - virtual ILoadersContext& GetContext() const ORTHANC_OVERRIDE - { - return that_; - }; - - virtual void AddLoader(boost::shared_ptr<IObserver> loader) ORTHANC_OVERRIDE - { - that_.loaders_.push_back(loader); - } - - virtual IObservable& GetOracleObservable() const ORTHANC_OVERRIDE - { - return StoneApplication::GetInstance().GetOracleObservable(); - } - - virtual void Schedule(boost::shared_ptr<IObserver> receiver, - int priority, - IOracleCommand* command /* Takes ownership */) ORTHANC_OVERRIDE - { - that_.scheduler_->Schedule(receiver, priority, command); - }; - - virtual void CancelRequests(boost::shared_ptr<IObserver> receiver) ORTHANC_OVERRIDE - { - that_.scheduler_->CancelRequests(receiver); - } - - virtual void CancelAllRequests() ORTHANC_OVERRIDE - { - that_.scheduler_->CancelAllRequests(); - } - - virtual void GetStatistics(uint64_t& scheduledCommands, - uint64_t& processedCommands) ORTHANC_OVERRIDE - { - scheduledCommands = that_.scheduler_->GetTotalScheduled(); - processedCommands = that_.scheduler_->GetTotalProcessed(); - } - }; - - - GenericLoadersContext::GenericLoadersContext(unsigned int maxHighPriority, - unsigned int maxStandardPriority, - unsigned int maxLowPriority) - { - scheduler_ = OracleScheduler::Create(StoneApplication::GetInstance(), maxHighPriority, maxStandardPriority, maxLowPriority); - - if (!scheduler_) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - - - GenericLoadersContext::~GenericLoadersContext() - { - LOG(INFO) << "scheduled commands: " << scheduler_->GetTotalScheduled() - << ", processed commands: " << scheduler_->GetTotalProcessed(); - scheduler_.reset(); - //LOG(INFO) << "counter: " << scheduler_.use_count(); - } - - - void GenericLoadersContext::WaitUntilComplete() - { - for (;;) - { - { - boost::recursive_mutex::scoped_lock lock(mutex_); - if (scheduler_ && - scheduler_->GetTotalScheduled() == scheduler_->GetTotalProcessed()) - { - return; - } - } - - boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - } - } - - ILoadersContext::ILock* GenericLoadersContext::Lock() - { - return new Locker(*this); - } -}
--- a/OrthancStone/Sources/Loaders/GenericLoadersContext.h Wed Sep 30 11:50:48 2026 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2023 Osimis S.A., Belgium - * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Lesser 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/>. - **/ - -#pragma once - -#include "../Messages/IMessageEmitter.h" -#include "ILoadersContext.h" -#include "DicomSource.h" -#include "OracleScheduler.h" - -#include <boost/thread/recursive_mutex.hpp> -#include <list> - -namespace OrthancStone -{ - // TODO Refactoring - Remove this class - class GenericLoadersContext : public ILoadersContext - { - private: - class Locker; - - // "Recursive mutex" is necessary, to be able to run - // "ILoaderFactory" from a message handler triggered by - // "EmitMessage()" - boost::recursive_mutex mutex_; // TODO Refactoring - This is redundant with IEnvironment - - boost::shared_ptr<OracleScheduler> scheduler_; - - // Necessary to keep the loaders persistent (including global - // function promises), after the function that created them is - // left. This avoids creating one global variable for each loader. - std::list< boost::shared_ptr<IObserver> > loaders_; - - public: - GenericLoadersContext(unsigned int maxHighPriority, - unsigned int maxStandardPriority, - unsigned int maxLowPriority); - - virtual ~GenericLoadersContext(); - - virtual ILock* Lock() ORTHANC_OVERRIDE; - - void WaitUntilComplete(); - }; -}
--- a/OrthancStone/Sources/Loaders/LoaderStateMachine.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/LoaderStateMachine.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -101,11 +101,8 @@ ") < simultaneousDownloads_ (" << simultaneousDownloads_ << ") --> will Schedule command addr " << std::hex << nextCommand << std::dec; - { - std::unique_ptr<ILoadersContext::ILock> lock(loadersContext_.Lock()); - boost::shared_ptr<IObserver> observer(GetSharedObserver()); - lock->Schedule(observer, 0, nextCommand); // TODO: priority! - } + context_.Schedule(GetSharedObserver(), 0, nextCommand); // TODO: priority! + pendingCommands_.pop_front(); activeCommands_++; @@ -165,12 +162,11 @@ } - LoaderStateMachine::LoaderStateMachine( - ILoadersContext& loadersContext) - : loadersContext_(loadersContext) - , active_(false) - , simultaneousDownloads_(4) - , activeCommands_(0) + LoaderStateMachine::LoaderStateMachine(StoneApplication::Context& context) : + context_(context), + active_(false), + simultaneousDownloads_(4), + activeCommands_(0) { LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::LoaderStateMachine()"; @@ -178,20 +174,15 @@ void LoaderStateMachine::PostConstructor() { - std::unique_ptr<ILoadersContext::ILock> - lock(loadersContext_.Lock()); - - IObservable& observable = lock->GetOracleObservable(); - // TODO => Move this out of constructor Register<OrthancRestApiCommand::SuccessMessage>( - observable, &LoaderStateMachine::HandleSuccessMessage); + context_.GetOracleObservable(), &LoaderStateMachine::HandleSuccessMessage); Register<GetOrthancImageCommand::SuccessMessage>( - observable, &LoaderStateMachine::HandleSuccessMessage); + context_.GetOracleObservable(), &LoaderStateMachine::HandleSuccessMessage); Register<GetOrthancWebViewerJpegCommand::SuccessMessage>( - observable, &LoaderStateMachine::HandleSuccessMessage); + context_.GetOracleObservable(), &LoaderStateMachine::HandleSuccessMessage); Register<OracleCommandExceptionMessage>( - observable, &LoaderStateMachine::HandleExceptionMessage); + context_.GetOracleObservable(), &LoaderStateMachine::HandleExceptionMessage); } LoaderStateMachine::~LoaderStateMachine()
--- a/OrthancStone/Sources/Loaders/LoaderStateMachine.h Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/LoaderStateMachine.h Wed Sep 30 13:56:32 2026 +0200 @@ -30,6 +30,7 @@ #include "../Oracle/IOracle.h" #include "../Oracle/OracleCommandExceptionMessage.h" #include "../Oracle/OrthancRestApiCommand.h" +#include "../StoneApplication.h" #include <IDynamicObject.h> @@ -37,8 +38,6 @@ namespace OrthancStone { - class ILoadersContext; - /** This class is supplied with Oracle commands and will schedule up to simultaneousDownloads_ of them at the same time, then will schedule the @@ -104,7 +103,7 @@ typedef std::list<IOracleCommand*> PendingCommands; - ILoadersContext& loadersContext_; + StoneApplication::Context& context_; bool active_; unsigned int simultaneousDownloads_; PendingCommands pendingCommands_; @@ -112,7 +111,7 @@ public: - explicit LoaderStateMachine(ILoadersContext& loadersContext); + explicit LoaderStateMachine(StoneApplication::Context& context); void PostConstructor();
--- a/OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -562,19 +562,18 @@ return volume_->GetGeometry(); } - OrthancMultiframeVolumeLoader::OrthancMultiframeVolumeLoader( - ILoadersContext& loadersContext, - boost::shared_ptr<DicomVolumeImage> volume, - float outliersHalfRejectionRate) - : LoaderStateMachine(loadersContext) - , volume_(volume) - , isReversedFrameOffsets_(false) - , pixelDataLoaded_(false) - , outliersHalfRejectionRate_(outliersHalfRejectionRate) - , distributionRawMin_(0) - , distributionRawMax_(0) - , computedDistributionMin_(0) - , computedDistributionMax_(0) + OrthancMultiframeVolumeLoader::OrthancMultiframeVolumeLoader(StoneApplication::Context& context, + boost::shared_ptr<DicomVolumeImage> volume, + float outliersHalfRejectionRate) : + LoaderStateMachine(context), + volume_(volume), + isReversedFrameOffsets_(false), + pixelDataLoaded_(false), + outliersHalfRejectionRate_(outliersHalfRejectionRate), + distributionRawMin_(0), + distributionRawMax_(0), + computedDistributionMin_(0), + computedDistributionMax_(0) { if (volume.get() == NULL) { @@ -584,17 +583,15 @@ boost::shared_ptr<OrthancMultiframeVolumeLoader> - OrthancMultiframeVolumeLoader::Create( - ILoadersContext& loadersContext, - boost::shared_ptr<DicomVolumeImage> volume, - float outliersHalfRejectionRate /*= 0.0005*/) + OrthancMultiframeVolumeLoader::Create(StoneApplication::Context& context, + boost::shared_ptr<DicomVolumeImage> volume, + float outliersHalfRejectionRate /*= 0.0005*/) { boost::shared_ptr<OrthancMultiframeVolumeLoader> obj( - new OrthancMultiframeVolumeLoader( - loadersContext, - volume, - outliersHalfRejectionRate)); + new OrthancMultiframeVolumeLoader(context, volume, outliersHalfRejectionRate)); + obj->LoaderStateMachine::PostConstructor(); + return obj; }
--- a/OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.h Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.h Wed Sep 30 13:56:32 2026 +0200 @@ -23,9 +23,10 @@ #pragma once -#include "LoaderStateMachine.h" +#include "../StoneApplication.h" #include "../Volumes/DicomVolumeImage.h" #include "../Volumes/IGeometryProvider.h" +#include "LoaderStateMachine.h" #include <boost/shared_ptr.hpp> @@ -98,13 +99,13 @@ void SetUncompressedPixelData(const std::string& pixelData); protected: - OrthancMultiframeVolumeLoader(ILoadersContext& loadersContext, + OrthancMultiframeVolumeLoader(StoneApplication::Context& context, boost::shared_ptr<DicomVolumeImage> volume, float outliersHalfRejectionRate); public: static boost::shared_ptr<OrthancMultiframeVolumeLoader> Create( - ILoadersContext& loadersContext, + StoneApplication::Context& context, boost::shared_ptr<DicomVolumeImage> volume, float outliersHalfRejectionRate = 0.0005);
--- a/OrthancStone/Sources/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Wed Sep 30 13:56:32 2026 +0200 @@ -323,11 +323,7 @@ command->AcquirePayload(new Orthanc::SingleValueObject<unsigned int>(sliceIndex)); - { - std::unique_ptr<ILoadersContext::ILock> lock(loadersContext_.Lock()); - boost::shared_ptr<IObserver> observer(GetSharedObserver()); - lock->Schedule(observer, sliceSchedulingPriority_, command.release()); - } + context_.Schedule(GetSharedObserver(), sliceSchedulingPriority_, command.release()); } else { @@ -527,45 +523,40 @@ sliceSchedulingPriority_ = p; } - OrthancSeriesVolumeProgressiveLoader::OrthancSeriesVolumeProgressiveLoader( - ILoadersContext& loadersContext, - boost::shared_ptr<DicomVolumeImage> volume, - bool progressiveQuality) - : loadersContext_(loadersContext) - , active_(false) - , progressiveQuality_(progressiveQuality) - , startCenter_(false) - , simultaneousDownloads_(4) - , volume_(volume) - , sorter_(new BasicFetchingItemsSorter::Factory) - , volumeImageReadyInHighQuality_(false) - , medadataSchedulingPriority_(0) - , sliceSchedulingPriority_(0) + OrthancSeriesVolumeProgressiveLoader::OrthancSeriesVolumeProgressiveLoader(StoneApplication::Context& context, + boost::shared_ptr<DicomVolumeImage> volume, + bool progressiveQuality) : + context_(context), + active_(false), + progressiveQuality_(progressiveQuality), + startCenter_(false), + simultaneousDownloads_(4), + volume_(volume), + sorter_(new BasicFetchingItemsSorter::Factory), + volumeImageReadyInHighQuality_(false), + medadataSchedulingPriority_(0), + sliceSchedulingPriority_(0) { } boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> - OrthancSeriesVolumeProgressiveLoader::Create( - ILoadersContext& loadersContext, - boost::shared_ptr<DicomVolumeImage> volume, - bool progressiveQuality) + OrthancSeriesVolumeProgressiveLoader::Create(StoneApplication::Context& context, + boost::shared_ptr<DicomVolumeImage> volume, + bool progressiveQuality) { - std::unique_ptr<ILoadersContext::ILock> lock(loadersContext.Lock()); - boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> obj( - new OrthancSeriesVolumeProgressiveLoader( - loadersContext, volume, progressiveQuality)); + new OrthancSeriesVolumeProgressiveLoader(context, volume, progressiveQuality)); obj->Register<OrthancRestApiCommand::SuccessMessage>( - lock->GetOracleObservable(), + context.GetOracleObservable(), &OrthancSeriesVolumeProgressiveLoader::LoadGeometry); obj->Register<GetOrthancImageCommand::SuccessMessage>( - lock->GetOracleObservable(), + context.GetOracleObservable(), &OrthancSeriesVolumeProgressiveLoader::LoadBestQualitySliceContent); obj->Register<GetOrthancWebViewerJpegCommand::SuccessMessage>( - lock->GetOracleObservable(), + context.GetOracleObservable(), &OrthancSeriesVolumeProgressiveLoader::LoadJpegSliceContent); return obj; @@ -613,11 +604,8 @@ std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); command->SetUri("/series/" + seriesId + "/instances-tags"); - { - std::unique_ptr<ILoadersContext::ILock> lock(loadersContext_.Lock()); - boost::shared_ptr<IObserver> observer(GetSharedObserver()); - lock->Schedule(observer, medadataSchedulingPriority_, command.release()); - } + + context_.Schedule(GetSharedObserver(), medadataSchedulingPriority_, command.release()); } }
--- a/OrthancStone/Sources/Loaders/OrthancSeriesVolumeProgressiveLoader.h Wed Sep 30 11:50:48 2026 +0200 +++ b/OrthancStone/Sources/Loaders/OrthancSeriesVolumeProgressiveLoader.h Wed Sep 30 13:56:32 2026 +0200 @@ -31,6 +31,7 @@ #include "../Oracle/GetOrthancWebViewerJpegCommand.h" #include "../Oracle/IOracle.h" #include "../Oracle/OrthancRestApiCommand.h" +#include "../StoneApplication.h" #include "../Toolbox/SlicesSorter.h" #include "../Volumes/DicomVolumeImage.h" #include "../Volumes/IVolumeSlicer.h" @@ -119,7 +120,7 @@ void LoadJpegSliceContent(const GetOrthancWebViewerJpegCommand::SuccessMessage& message); - ILoadersContext& loadersContext_; + StoneApplication::Context& context_; bool active_; bool progressiveQuality_; bool startCenter_; @@ -139,7 +140,7 @@ int sliceSchedulingPriority_; OrthancSeriesVolumeProgressiveLoader( - ILoadersContext& loadersContext, + StoneApplication::Context& context, boost::shared_ptr<DicomVolumeImage> volume, bool progressiveQuality); @@ -150,7 +151,7 @@ See doc for the progressiveQuality_ field */ static boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> Create( - ILoadersContext& context, + StoneApplication::Context& context, boost::shared_ptr<DicomVolumeImage> volume, bool progressiveQuality = false);
