Mercurial > hg > orthanc-stone
changeset 295:b04b13810540 am-2
unified CMakeLists.txt into a single file for WASM/Native + bootstrap Command (to rework) + doc
line wrap: on
line diff
--- a/.hgignore Thu Aug 30 17:17:11 2018 +0200 +++ b/.hgignore Tue Sep 04 15:09:42 2018 +0200 @@ -1,7 +1,6 @@ -Platforms/Generic/CMakeLists.txt.user +CMakeLists.txt.user Platforms/Generic/ThirdPartyDownloads/ -Platforms/Wasm/CMakeLists.txt.user -Platforms/Wasm/build/ -Platforms/Wasm/build-web/ -Platforms/Wasm/ThirdPartyDownloads/ Applications/Qt/archive/ +Applications/Samples/ThirdPartyDownloads/ +Applications/Samples/build-wasm/ +Applications/Samples/build-web/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/BaseCommandFactory.cpp Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,50 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "BaseCommandFactory.h" +#include "Core/OrthancException.h" + +namespace OrthancStone +{ + ICommand* BaseCommandFactory::CreateFromJson(const Json::Value& commandJson) + { + if (!commandJson.isObject() || !commandJson["command"].isString()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); // TODO: use StoneException ? + } + + std::string commandName = commandJson["command"].asString(); + CommandCreationFunctions::const_iterator it = commands_.find(commandName); + if (it == commands_.end()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); // TODO: use StoneException ? + } + + // call the CreateCommandFn to build the command + ICommand* command = it->second(); + if (commandJson["args"].isObject()) + { + command->Configure(commandJson["args"]); + } + + return command; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/BaseCommandFactory.h Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,50 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#pragma once + +#include <map> +#include <memory> + +#include "ICommand.h" +#include "../../Applications/Commands/ICommandFactory.h" + +// TODO: must be reworked completely (check trello) + +namespace OrthancStone +{ + class BaseCommandFactory + { + typedef ICommand* (*CommandCreationFn)(void); + typedef std::map<std::string, CommandCreationFn> CommandCreationFunctions; + CommandCreationFunctions commands_; + + public: + virtual ICommand* CreateFromJson(const Json::Value& commandJson); + + template<typename TCommand> void RegisterCommandClass() + { + // create the command only to get its name + std::auto_ptr<ICommand> command(TCommand::Create()); + + commands_[command->GetName()] = &TCommand::Create; + } + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/BaseCommands.yml Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,10 @@ +SelectTool: + target: Application + toolName: string + comment: Selects the current application tool +DownloadDicom: + target: LayerWidget + comment: Downloads the slice currently displayed in the LayerWidget +Export: + target: IWidget + comment: Export the content of the widget \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/ICommand.h Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,74 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <json/json.h> + +// TODO: must be reworked completely (check trello) + +namespace OrthancStone +{ + class ICommand // TODO noncopyable + { + protected: + const char* name_; + ICommand(const char* name) + : name_(name) + {} + public: + virtual void Execute() = 0; + virtual void Configure(const Json::Value& arguments) = 0; + const char* GetName() + { + return name_; + } + }; + + + template <typename TCommand> + class BaseCommand : ICommand + { + protected: + BaseCommand(const char* name) + : ICommand(name) + {} + + public: + static ICommand* Create() { + return new TCommand(); + } + + virtual void Configure(const Json::Value& arguments) { + } + }; + + class NoopCommand : public BaseCommand<NoopCommand> + { + public: + NoopCommand() + : BaseCommand("noop") + {} + virtual void Execute() {} + }; + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/ICommandExecutor.h Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,32 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <boost/noncopyable.hpp> + +namespace OrthancStone +{ + class ICommandExecutor : public boost::noncopyable + { + + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/ICommandFactory.h Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,38 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <boost/noncopyable.hpp> +#include <json/json.h> + +#include "ICommand.h" + +namespace OrthancStone +{ + + class ICommandFactory : public boost::noncopyable + { + public: + virtual ICommand* CreateFromJson(const Json::Value& commandJson) = 0; + template<typename TCommand> void RegisterCommandClass(); + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/CMakeLists.txt Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,165 @@ +# Usage (Linux): +# to build the WASM samples +# source ~/Downloads/emsdk/emsdk_env.sh && cmake -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DSTONE_SOURCES_DIR=$currentDir/../../../orthanc-stone -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc -DALLOW_DOWNLOADS=ON .. -DENABLE_WASM=ON +# to build the Qt samples + +cmake_minimum_required(VERSION 2.8.3) +project(OrthancStone) + +include(../../Resources/CMake/OrthancStoneParameters.cmake) + + +set(ENABLE_SDL OFF CACHE BOOL "Target SDL Native application") +set(ENABLE_QT OFF CACHE BOOL "Target Qt Native application") +set(ENABLE_WASM OFF CACHE BOOL "Target WASM application") + +if (ENABLE_WASM) + ##################################################################### + ## Configuration of the Emscripten compiler for WebAssembly target + ##################################################################### + + set(WASM_FLAGS "-s WASM=1") + set(WASM_MODULE_NAME "StoneFrameworkModule" CACHE STRING "Name of the WebAssembly module") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Applications/Samples/samples-library.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'") + + # Handling of memory + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1") # Resize + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_MEMORY=536870912") # 512MB + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='\"${WASM_MODULE_NAME}\"' -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=536870912 -s TOTAL_STACK=128000000") # 512MB + resize + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=1073741824") # 1GB + resize + + # To debug exceptions + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=2") + + add_definitions(-DORTHANC_ENABLE_WASM=1) + set(ORTHANC_SANDBOXED ON) + +elseif (ENABLE_QT OR ENABLE_SDL) + + set(ENABLE_NATIVE ON) + set(ORTHANC_SANDBOXED OFF) + set(ENABLE_CRYPTO_OPTIONS ON) + set(ENABLE_GOOGLE_TEST ON) + set(ENABLE_WEB_CLIENT ON) + +endif() + +##################################################################### +## Configuration for Orthanc +##################################################################### + +# include(../../Resources/CMake/Version.cmake) + +if (ORTHANC_STONE_VERSION STREQUAL "mainline") + set(ORTHANC_FRAMEWORK_VERSION "mainline") + set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg") +else() + set(ORTHANC_FRAMEWORK_VERSION "1.4.1") + set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web") +endif() + +set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")") +set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"") +set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"") + + +##################################################################### +## Build a static library containing the Orthanc Stone framework +##################################################################### + + +LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options) + +include(../../Resources/CMake/OrthancStoneConfiguration.cmake) + +add_library(OrthancStone STATIC + ${ORTHANC_STONE_SOURCES} + ) + +##################################################################### +## Build all the sample applications +##################################################################### + +include_directories(${ORTHANC_STONE_ROOT}) + +# files common to all samples +list(APPEND APPLICATIONS_SOURCES + ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleInteractor.h + ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleApplicationBase.h + ) + +if (ENABLE_QT) + list(APPEND APPLICATIONS_SOURCES + ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleQtApplicationRunner.h + ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.cpp + ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.ui + ) +endif() + +if (ENABLE_NATIVE) + list(APPEND APPLICATIONS_SOURCES + ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleMainNative.cpp + ) + +elseif (ENABLE_WASM) + + list(APPEND APPLICATIONS_SOURCES + ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleMainWasm.cpp + ${STONE_WASM_SOURCES} + ) +endif() + + +macro(BuildSingleFileSample Target Header Sample) + add_executable(${Target} + ${ORTHANC_STONE_ROOT}/Applications/Samples/${Header} + ${APPLICATIONS_SOURCES} + ) + set_target_properties(${Target} PROPERTIES COMPILE_DEFINITIONS ORTHANC_STONE_SAMPLE=${Sample}) + target_link_libraries(${Target} OrthancStone) +endmacro() + +#BuildSingleFileSample(OrthancStoneEmpty EmptyApplication.h 1) +#BuildSingleFileSample(OrthancStoneTestPattern TestPatternApplication.h 2) +#BuildSingleFileSample(OrthancStoneSingleFrame SingleFrameApplication.h 3) +#BuildSingleFileSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4) +#BuildSingleFileSample(OrthancStoneBasicPetCtFusion 5) +#BuildSingleFileSample(OrthancStoneSynchronizedSeries 6) +#BuildSingleFileSample(OrthancStoneLayoutPetCtFusion 7) +BuildSingleFileSample(OrthancStoneSimpleViewer SimpleViewerApplication.h 8) + +##################################################################### +## Build the unit tests +##################################################################### + +if (ENABLE_NATIVE) + add_executable(UnitTests + ${GOOGLE_TEST_SOURCES} + ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestMessageBroker.cpp + ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestCommands.cpp + ${ORTHANC_STONE_ROOT}/UnitTestsSources/UnitTestsMain.cpp + ) + + target_link_libraries(UnitTests OrthancStone) +endif() + +##################################################################### +## Generate the documentation if Doxygen is present +##################################################################### + +find_package(Doxygen) +if (DOXYGEN_FOUND) + configure_file( + ${ORTHANC_STONE_ROOT}/Resources/OrthancStone.doxygen + ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen + @ONLY) + + add_custom_target(doc + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen + COMMENT "Generating documentation with Doxygen" VERBATIM + ) +else() + message("Doxygen not found. The documentation will not be built.") +endif()
--- a/Applications/Samples/SampleApplicationBase.h Thu Aug 30 17:17:11 2018 +0200 +++ b/Applications/Samples/SampleApplicationBase.h Tue Sep 04 15:09:42 2018 +0200 @@ -13,7 +13,7 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ @@ -34,9 +34,7 @@ IStatusBar& statusBar, const boost::program_options::variables_map& parameters) { - } - - + } virtual std::string GetTitle() const { @@ -48,11 +46,11 @@ virtual void OnTool1Clicked() {} virtual void OnTool2Clicked() {} - virtual void GetButtonNames(std::string& pushButton1, - std::string& pushButton2, - std::string& tool1, - std::string& tool2 - ) { + virtual void GetButtonNames(std::string& pushButton1, + std::string& pushButton2, + std::string& tool1, + std::string& tool2 + ) { pushButton1 = "action1"; pushButton2 = "action2"; tool1 = "tool1";
--- a/Applications/Samples/Web/tsconfig-simple-viewer.json Thu Aug 30 17:17:11 2018 +0200 +++ b/Applications/Samples/Web/tsconfig-simple-viewer.json Tue Sep 04 15:09:42 2018 +0200 @@ -1,7 +1,7 @@ { "extends" : "./tsconfig-samples", "compilerOptions": { - "outFile": "../../../Platforms/Wasm/build-web/app-simple-viewer.js" + "outFile": "../build-web/app-simple-viewer.js" }, "include" : [ "simple-viewer.ts",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/build-wasm.sh Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,15 @@ +#!/bin/bash + +currentDir=$(pwd) +samplesRootDir=$(pwd) + +mkdir -p $samplesRootDir/build-wasm +cd $samplesRootDir/build-wasm + +source ~/Downloads/emsdk/emsdk_env.sh +cmake -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DSTONE_SOURCES_DIR=$currentDir/../../../orthanc-stone -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc -DALLOW_DOWNLOADS=ON .. -DENABLE_WASM=ON +make -j 5 + +echo "-- building the web application -- " +cd $currentDir +./build-web.sh \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/build-web.sh Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,19 @@ +#!/bin/bash + +# this script currently assumes that the wasm code has been built on its side and is availabie in Wasm/build/ + +currentDir=$(pwd) +samplesRootDir=$(pwd) + +outputDir=$samplesRootDir/build-web/ +mkdir -p $outputDir + +cp $samplesRootDir/Web/index.html $outputDir +cp $samplesRootDir/Web/samples-styles.css $outputDir + +cp $samplesRootDir/Web/simple-viewer.html $outputDir +tsc --allowJs --project $samplesRootDir/Web/tsconfig-simple-viewer.json +cp $currentDir/build-wasm/OrthancStoneSimpleViewer.js $outputDir +cp $currentDir/build-wasm/OrthancStoneSimpleViewer.wasm $outputDir + +cd $currentDir
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/nginx.local.conf Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,44 @@ +# Local config to serve the WASM samples static files and reverse proxy Orthanc. +# Uses port 9977 instead of 80. + +# `events` section is mandatory +events { + worker_connections 1024; # Default: 1024 +} + +http { + + # prevent nginx sync issues on OSX + proxy_buffering off; + + server { + listen 9977 default_server; + client_max_body_size 4G; + + # location may have to be adjusted depending on your OS and nginx install + include /etc/nginx/mime.types; + # if not in your system mime.types, add this line to support WASM: + # types { + # application/wasm wasm; + # } + + # serve WASM static files + root build-web/; + location / { + } + + # reverse proxy orthanc + location /orthanc/ { + rewrite /orthanc(.*) $1 break; + proxy_pass http://127.0.0.1:8042; + proxy_set_header Host $http_host; + proxy_set_header my-auth-header good-token; + proxy_request_buffering off; + proxy_max_temp_file_size 0; + client_max_body_size 0; + } + + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Samples/tsconfig-stone.json Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,7 @@ +{ + "include" : [ + "../../Platforms/Wasm/stone-framework-loader.ts", + "../../Platforms/Wasm/wasm-application-runner.ts", + "../../Platforms/Wasm/wasm-viewport.ts" + ] +}
--- a/Framework/SmartLoader.cpp Thu Aug 30 17:17:11 2018 +0200 +++ b/Framework/SmartLoader.cpp Tue Sep 04 15:09:42 2018 +0200 @@ -46,12 +46,12 @@ switch (message.GetType()) { case MessageType_LayerSource_GeometryReady: { - const OrthancFrameLayerSource* layerSource=dynamic_cast<const OrthancFrameLayerSource*>(&from); + //const OrthancFrameLayerSource* layerSource=dynamic_cast<const OrthancFrameLayerSource*>(&from); // TODO keep track of objects that have been loaded already }; break; case MessageType_LayerSource_LayerReady: { - const OrthancFrameLayerSource* layerSource=dynamic_cast<const OrthancFrameLayerSource*>(&from); + //const OrthancFrameLayerSource* layerSource=dynamic_cast<const OrthancFrameLayerSource*>(&from); // TODO keep track of objects that have been loaded already }; break; // case MessageType_OrthancApi_GetStudyIds_Ready:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/StoneException.h Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,31 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "Core/OrthancException.h" + +namespace OrthancStone +{ + + +} +
--- a/Platforms/Generic/CMakeLists.txt Thu Aug 30 17:17:11 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(OrthancStone) - - -##################################################################### -## Configuration for Orthanc -##################################################################### - -include(../../Resources/CMake/Version.cmake) - -if (ORTHANC_STONE_VERSION STREQUAL "mainline") - set(ORTHANC_FRAMEWORK_VERSION "mainline") - set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg") -else() - set(ORTHANC_FRAMEWORK_VERSION "1.3.2") - set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web") -endif() - -set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")") -set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"") -set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"") - - -##################################################################### -## Build a static library containing the Orthanc Stone framework -##################################################################### - -include(../../Resources/CMake/OrthancStoneParameters.cmake) - -LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options) - -SET(ENABLE_SDL ON) -SET(ENABLE_QT OFF) -SET(ORTHANC_SANDBOXED OFF) -SET(ENABLE_CRYPTO_OPTIONS ON) -SET(ENABLE_GOOGLE_TEST ON) -SET(ENABLE_WEB_CLIENT ON) - -include(../../Resources/CMake/OrthancStoneConfiguration.cmake) - -add_library(OrthancStone STATIC - ${ORTHANC_STONE_SOURCES} - ) - - -##################################################################### -## Build all the sample applications -##################################################################### - -if (ENABLE_QT) - list(APPEND APPLICATIONS_SOURCES - ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleQtApplicationRunner.h - ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.cpp - ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.ui - ) -endif() - -macro(BuildSingeFileSample Target Header Sample) - add_executable(${Target} - ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleMainNative.cpp - ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleInteractor.h - ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleApplicationBase.h - ${ORTHANC_STONE_ROOT}/Applications/Samples/${Header} - ${APPLICATIONS_SOURCES} - ) - set_target_properties(${Target} PROPERTIES COMPILE_DEFINITIONS ORTHANC_STONE_SAMPLE=${Sample}) - target_link_libraries(${Target} OrthancStone) -endmacro() - - -# TODO - Re-enable all these samples! - -#BuildSample(OrthancStoneEmpty EmptyApplication.h 1) -#BuildSample(OrthancStoneTestPattern TestPatternApplication.h 2) -#BuildSample(OrthancStoneSingleFrame SingleFrameApplication.h 3) -#BuildSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4) -##BuildSample(OrthancStoneBasicPetCtFusion 5) -##BuildSample(OrthancStoneSynchronizedSeries 6) -##BuildSample(OrthancStoneLayoutPetCtFusion 7) -BuildSingeFileSample(OrthancStoneSimpleViewer SimpleViewerApplication.h 8) - - -##################################################################### -## Build the unit tests -##################################################################### - -add_executable(UnitTests - ${GOOGLE_TEST_SOURCES} - ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestMessageBroker.cpp - ${ORTHANC_STONE_ROOT}/UnitTestsSources/UnitTestsMain.cpp - ) - -target_link_libraries(UnitTests OrthancStone) - - -##################################################################### -## Generate the documentation if Doxygen is present -##################################################################### - -find_package(Doxygen) -if (DOXYGEN_FOUND) - configure_file( - ${ORTHANC_STONE_ROOT}/Resources/OrthancStone.doxygen - ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen - @ONLY) - - add_custom_target(doc - ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen - COMMENT "Generating documentation with Doxygen" VERBATIM - ) -else() - message("Doxygen not found. The documentation will not be built.") -endif()
--- a/Platforms/Generic/OracleWebService.h Thu Aug 30 17:17:11 2018 +0200 +++ b/Platforms/Generic/OracleWebService.h Tue Sep 04 15:09:42 2018 +0200 @@ -30,6 +30,8 @@ namespace OrthancStone { // The OracleWebService performs HTTP requests in a native environment. + // It uses a thread pool to handle multiple HTTP requests in a same time. + // It works asynchronously to mimick the behaviour of the WebService running in a WASM environment. class OracleWebService : public IWebService { private:
--- a/Platforms/Wasm/CMakeLists.txt Thu Aug 30 17:17:11 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -# Usage (Linux): -# source ~/Downloads/emsdk/emsdk_env.sh && cmake -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake .. - -cmake_minimum_required(VERSION 2.8.3) - - -##################################################################### -## Configuration of the Emscripten compiler for WebAssembly target -##################################################################### - -set(WASM_FLAGS "-s WASM=1") -set(WASM_MODULE_NAME "StoneFrameworkModule" CACHE STRING "Name of the WebAssembly module") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Applications/Samples/samples-library.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'") - -# Handling of memory -#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1") # Resize -#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_MEMORY=536870912") # 512MB -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='\"${WASM_MODULE_NAME}\"' -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=536870912 -s TOTAL_STACK=128000000") # 512MB + resize -#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=1073741824") # 1GB + resize - -# To debug exceptions -#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=2") - - -##################################################################### -## Build a static library containing the Orthanc Stone framework -##################################################################### - -include(../../Resources/CMake/OrthancStoneParameters.cmake) - -SET(ORTHANC_SANDBOXED ON) -SET(ENABLE_QT OFF) -SET(ENABLE_SDL OFF) -add_definitions(-DORTHANC_ENABLE_WASM=1) - -include(../../Resources/CMake/OrthancStoneConfiguration.cmake) - -add_library(OrthancStone STATIC ${ORTHANC_STONE_SOURCES}) - - - -# Regenerate a dummy "WasmWebService.c" file each time the "WasmWebService.js" file -# is modified, so as to force a new execution of the linking -add_custom_command( - OUTPUT "${AUTOGENERATED_DIR}/WasmWebService.c" - COMMAND ${CMAKE_COMMAND} -E touch "${AUTOGENERATED_DIR}/WasmWebService.c" "" - DEPENDS "${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmWebService.js") - -add_custom_command( - OUTPUT "${AUTOGENERATED_DIR}/default-library.c" - COMMAND ${CMAKE_COMMAND} -E touch "${AUTOGENERATED_DIR}/default-library.c" "" - DEPENDS "${ORTHANC_STONE_ROOT}/Platforms/Wasm/default-library.js") - - -##################################################################### -## Build all the sample applications -##################################################################### - -include_directories(${ORTHANC_STONE_ROOT}) - - -macro(BuildSample Target Header Sample) - add_executable(${Target} - ${STONE_WASM_SOURCES} - - ${AUTOGENERATED_DIR}/WasmWebService.c - ${AUTOGENERATED_DIR}/default-library.c - - ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleMainWasm.cpp -# ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleApplicationContext.cpp - ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleInteractor.h - ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleApplicationBase.h - ${ORTHANC_STONE_ROOT}/Applications/Samples/${Header} - ) - set_target_properties(${Target} PROPERTIES COMPILE_DEFINITIONS ORTHANC_STONE_SAMPLE=${Sample}) - target_link_libraries(${Target} OrthancStone) -endmacro() - -#BuildSample(OrthancStoneEmpty EmptyApplication.h 1) -#BuildSample(OrthancStoneTestPattern TestPatternApplication.h 2) -#BuildSample(OrthancStoneSingleFrame SingleFrameApplication.h 3) -#BuildSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4) -#BuildSample(OrthancStoneBasicPetCtFusion 5) -#BuildSample(OrthancStoneSynchronizedSeries 6) -#BuildSample(OrthancStoneLayoutPetCtFusion 7) -BuildSample(OrthancStoneSimpleViewer SimpleViewerApplication.h 8)
--- a/Platforms/Wasm/build-wasm.sh Thu Aug 30 17:17:11 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#!/bin/bash - -currentDir=$(pwd) -wasmRootDir=$(pwd) - -mkdir -p $wasmRootDir/build -cd $wasmRootDir/build - -source ~/Downloads/emsdk/emsdk_env.sh -cmake -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DSTONE_SOURCES_DIR=$currentDir/../../../orthanc-stone -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc -DALLOW_DOWNLOADS=ON .. -make -j 5 - -echo "-- building the web application -- " -cd $currentDir -./build-web.sh \ No newline at end of file
--- a/Platforms/Wasm/build-web.sh Thu Aug 30 17:17:11 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -#!/bin/bash - -# this script currently assumes that the wasm code has been built on its side and is availabie in Wasm/build/ - -currentDir=$(pwd) -wasmRootDir=$(pwd) -samplesRootDir=$(pwd)/../../Applications/Samples/ - -outputDir=$wasmRootDir/build-web/ -mkdir -p $outputDir - -cp $samplesRootDir/Web/index.html $outputDir -cp $samplesRootDir/Web/samples-styles.css $outputDir - -cp $samplesRootDir/Web/simple-viewer.html $outputDir -tsc --allowJs --project $samplesRootDir/Web/tsconfig-simple-viewer.json -cp $currentDir/build/OrthancStoneSimpleViewer.js $outputDir -cp $currentDir/build/OrthancStoneSimpleViewer.wasm $outputDir - - -# cat ../wasm/build/wasm-app.js $currentDir/../../../orthanc-stone/Platforms/WebAssembly/defaults.js > $outputDir/app.js - -cd $currentDir -
--- a/Platforms/Wasm/nginx.local.conf Thu Aug 30 17:17:11 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -# Local config to serve the WASM samples static files and reverse proxy Orthanc. -# Uses port 9977 instead of 80. - -# `events` section is mandatory -events { - worker_connections 1024; # Default: 1024 -} - -http { - - # prevent nginx sync issues on OSX - proxy_buffering off; - - server { - listen 9977 default_server; - client_max_body_size 4G; - - # location may have to be adjusted depending on your OS and nginx install - include /etc/nginx/mime.types; - # if not in your system mime.types, add this line to support WASM: - # types { - # application/wasm wasm; - # } - - # serve WASM static files - root build-web/; - location / { - } - - # reverse proxy orthanc - location /orthanc/ { - rewrite /orthanc(.*) $1 break; - proxy_pass http://127.0.0.1:8042; - proxy_set_header Host $http_host; - proxy_set_header my-auth-header good-token; - proxy_request_buffering off; - proxy_max_temp_file_size 0; - client_max_body_size 0; - } - - - } - -}
--- a/Platforms/Wasm/tsconfig-stone.json Thu Aug 30 17:17:11 2018 +0200 +++ b/Platforms/Wasm/tsconfig-stone.json Tue Sep 04 15:09:42 2018 +0200 @@ -1,7 +1,7 @@ { "include" : [ - "../../../Platforms/Wasm/stone-framework-loader.ts", - "../../../Platforms/Wasm/wasm-application-runner.ts", - "../../../Platforms/Wasm/wasm-viewport.ts" + "stone-framework-loader.ts", + "wasm-application-runner.ts", + "wasm-viewport.ts" ] }
--- a/README Thu Aug 30 17:17:11 2018 +0200 +++ b/README Tue Sep 04 15:09:42 2018 +0200 @@ -93,7 +93,7 @@ to build the WASM samples: ------------------------- ``` -cd ~/orthanc-stone/Platforms/Wasm +cd ~/orthanc-stone/Applications/Samples ./build-wasm.sh ``` @@ -112,7 +112,7 @@ ``` mkdir -p ~/builds/orthanc-stone-build cd ~/builds/orthanc-stone-build -cmake -DALLOW_DOWNLOADS=ON ~/orthanc-stone/ +cmake -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ~/orthanc-stone/Applications/Samples/ cmake --build . --target OrthancStoneSimpleViewer -- -j 5 ``` @@ -122,7 +122,7 @@ Orthanc # launch the sample -./OrthancStoneSimpleViewer --instance1=XX --instance2=XX +./OrthancStoneSimpleViewer --studyId=XX ```
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Thu Aug 30 17:17:11 2018 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Tue Sep 04 15:09:42 2018 +0200 @@ -164,6 +164,10 @@ set(APPLICATIONS_SOURCES ${ORTHANC_STONE_ROOT}/Applications/IStoneApplication.h ${ORTHANC_STONE_ROOT}/Applications/StoneApplicationContext.cpp + ${ORTHANC_STONE_ROOT}/Applications/Commands/BaseCommandFactory.cpp + ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommand.h + ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandExecutor.h + ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandFactory.h ) if (NOT ORTHANC_SANDBOXED) @@ -190,7 +194,7 @@ ) endif() endif() -else() +elseif (ENABLE_WASM) list(APPEND APPLICATIONS_SOURCES ${ORTHANC_STONE_ROOT}/Applications/Wasm/StartupParametersBuilder.cpp ) @@ -200,7 +204,20 @@ ${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmWebService.cpp ${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmViewport.cpp ${ORTHANC_STONE_ROOT}/Platforms/Wasm/IStoneApplicationToWebApplicationAdapter.h + ${AUTOGENERATED_DIR}/WasmWebService.c + ${AUTOGENERATED_DIR}/default-library.c ) + + # Regenerate a dummy "WasmWebService.c" file each time the "WasmWebService.js" file + # is modified, so as to force a new execution of the linking + add_custom_command( + OUTPUT "${AUTOGENERATED_DIR}/WasmWebService.c" + COMMAND ${CMAKE_COMMAND} -E touch "${AUTOGENERATED_DIR}/WasmWebService.c" "" + DEPENDS "${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmWebService.js") + add_custom_command( + OUTPUT "${AUTOGENERATED_DIR}/default-library.c" + COMMAND ${CMAKE_COMMAND} -E touch "${AUTOGENERATED_DIR}/default-library.c" "" + DEPENDS "${ORTHANC_STONE_ROOT}/Platforms/Wasm/default-library.js") endif() list(APPEND ORTHANC_STONE_SOURCES @@ -209,6 +226,8 @@ #${ORTHANC_STONE_ROOT}/Framework/Layers/SingleFrameRendererFactory.cpp ${ORTHANC_STONE_ROOT}/Framework/StoneEnumerations.cpp ${ORTHANC_STONE_ROOT}/Framework/SmartLoader.cpp + ${ORTHANC_STONE_ROOT}/Framework/dev.h + ${ORTHANC_STONE_ROOT}/Framework/StoneException.h ${ORTHANC_STONE_ROOT}/Framework/Layers/CircleMeasureTracker.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/ColorFrameRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/DicomStructureSetRendererFactory.cpp
--- a/Resources/CMake/OrthancStoneParameters.cmake Thu Aug 30 17:17:11 2018 +0200 +++ b/Resources/CMake/OrthancStoneParameters.cmake Tue Sep 04 15:09:42 2018 +0200 @@ -49,5 +49,3 @@ ## the Stone of Orthanc ##################################################################### -set(ENABLE_SDL ON CACHE INTERNAL "Include support for SDL") -set(ENABLE_QT OFF CACHE INTERNAL "Include support for Qt")
--- a/Resources/Orthanc/DownloadOrthancFramework.cmake Thu Aug 30 17:17:11 2018 +0200 +++ b/Resources/Orthanc/DownloadOrthancFramework.cmake Tue Sep 04 15:09:42 2018 +0200 @@ -84,6 +84,8 @@ set(ORTHANC_FRAMEWORK_MD5 "dac95bd6cf86fb19deaf4e612961f378") elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.3.2") set(ORTHANC_FRAMEWORK_MD5 "d0ccdf68e855d8224331f13774992750") + elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.4.1") + set(ORTHANC_FRAMEWORK_MD5 "d41d8cd98f00b204e9800998ecf8427e") endif() endif() endif()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UnitTestsSources/TestCommands.cpp Tue Sep 04 15:09:42 2018 +0200 @@ -0,0 +1,108 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "gtest/gtest.h" + +#include "../Applications/Commands/BaseCommandFactory.h" +#include "Core/OrthancException.h" + +class CommandIncrement: public OrthancStone::BaseCommand<CommandIncrement> +{ +public: + static int counter; + int increment_; +public: + CommandIncrement() + : OrthancStone::BaseCommand<CommandIncrement>("increment"), + increment_(0) + {} + + virtual void Execute() + { + counter += increment_; + } + virtual void Configure(const Json::Value& arguments) + { + increment_ = arguments["increment"].asInt(); + } +}; + +// COMMAND("name", "arg1", "int", "arg2", "string") +// COMMAND(name, arg1, arg2) + + +int CommandIncrement::counter = 0; + +TEST(Commands, CreateNoop) +{ + OrthancStone::BaseCommandFactory factory; + + factory.RegisterCommandClass<OrthancStone::NoopCommand>(); + + Json::Value cmdJson; + cmdJson["command"] = "noop"; + + std::auto_ptr<OrthancStone::ICommand> command(factory.CreateFromJson(cmdJson)); + + ASSERT_TRUE(command.get() != NULL); + ASSERT_EQ("noop", command->GetName()); +} + +TEST(Commands, Execute) +{ + OrthancStone::BaseCommandFactory factory; + + factory.RegisterCommandClass<OrthancStone::NoopCommand>(); + factory.RegisterCommandClass<CommandIncrement>(); + + Json::Value cmdJson; + cmdJson["command"] = "increment"; + cmdJson["args"]["increment"] = 2; + + std::auto_ptr<OrthancStone::ICommand> command(factory.CreateFromJson(cmdJson)); + + ASSERT_TRUE(command.get() != NULL); + CommandIncrement::counter = 0; + command->Execute(); + ASSERT_EQ(2, CommandIncrement::counter); +} + +TEST(Commands, TryCreateUnknowCommand) +{ + OrthancStone::BaseCommandFactory factory; + factory.RegisterCommandClass<OrthancStone::NoopCommand>(); + + Json::Value cmdJson; + cmdJson["command"] = "unknown"; + + ASSERT_THROW(std::auto_ptr<OrthancStone::ICommand> command(factory.CreateFromJson(cmdJson)), Orthanc::OrthancException); +} + +TEST(Commands, TryCreateCommandFromInvalidJson) +{ + OrthancStone::BaseCommandFactory factory; + factory.RegisterCommandClass<OrthancStone::NoopCommand>(); + + Json::Value cmdJson; + cmdJson["command-name"] = "noop"; + + ASSERT_THROW(std::auto_ptr<OrthancStone::ICommand> command(factory.CreateFromJson(cmdJson)), Orthanc::OrthancException); +}