# HG changeset patch # User am@osimis.io # Date 1537881293 -7200 # Node ID be2660b6e40a530363bef30d2ac635fc471360ef # Parent 6c22e0506587fdda179af69baac7a03861c893d7 wip: commands + status update diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/BaseCommandBuilder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/BaseCommandBuilder.cpp Tue Sep 25 15:14:53 2018 +0200 @@ -0,0 +1,63 @@ +/** + * 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 . + **/ + +#include "BaseCommandBuilder.h" +#include "Core/OrthancException.h" +#include +#include "Framework/StoneException.h" + +namespace OrthancStone +{ + ICommand* BaseCommandBuilder::CreateFromJson(const Json::Value& commandJson) + { + if (!commandJson.isObject() || !commandJson["command"].isString()) + { + throw StoneException(ErrorCode_CommandJsonInvalidFormat); + } + + if (commandJson["commandType"].isString() && commandJson["commandType"].asString() == "simple") + { + printf("creating a simple command\n"); + return new SimpleCommand(commandJson["command"].asString().c_str()); + } + + return NULL; + // 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; + } + +} diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/BaseCommandBuilder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/BaseCommandBuilder.h Tue Sep 25 15:14:53 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 . + **/ + +#pragma once + +#include +#include + +#include "ICommand.h" +#include "../../Applications/Commands/ICommandBuilder.h" + +// TODO: must be reworked completely (check trello) + +namespace OrthancStone +{ + class BaseCommandBuilder : public ICommandBuilder + { + public: + virtual ICommand* CreateFromJson(const Json::Value& commandJson); + }; +} diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/BaseCommandFactory.cpp --- a/Applications/Commands/BaseCommandFactory.cpp Tue Sep 18 18:20:10 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/** - * 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 . - **/ - -#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; - } - -} diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/BaseCommandFactory.h --- a/Applications/Commands/BaseCommandFactory.h Tue Sep 18 18:20:10 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/** - * 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 . - **/ - -#pragma once - -#include -#include - -#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 CommandCreationFunctions; - CommandCreationFunctions commands_; - - public: - virtual ICommand* CreateFromJson(const Json::Value& commandJson); - - template void RegisterCommandClass() - { - // create the command only to get its name - std::auto_ptr command(TCommand::Create()); - - commands_[command->GetName()] = &TCommand::Create; - } - }; -} diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/ICommand.h --- a/Applications/Commands/ICommand.h Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/Commands/ICommand.h Tue Sep 25 15:14:53 2018 +0200 @@ -30,14 +30,14 @@ class ICommand // TODO noncopyable { protected: - const char* name_; - ICommand(const char* name) + std::string name_; + ICommand(const std::string& name) : name_(name) {} public: virtual void Execute() = 0; - virtual void Configure(const Json::Value& arguments) = 0; - const char* GetName() +// virtual void Configure(const Json::Value& arguments) = 0; + const std::string& GetName() const { return name_; } @@ -45,10 +45,10 @@ template - class BaseCommand : ICommand + class BaseCommand : public ICommand { protected: - BaseCommand(const char* name) + BaseCommand(const std::string& name) : ICommand(name) {} @@ -70,5 +70,13 @@ virtual void Execute() {} }; + class SimpleCommand : public BaseCommand + { + public: + SimpleCommand(const std::string& name) + : BaseCommand(name) + {} + virtual void Execute() {} // TODO currently not used but this is not nice at all ! + }; } diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/ICommandBuilder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Commands/ICommandBuilder.h Tue Sep 25 15:14:53 2018 +0200 @@ -0,0 +1,37 @@ +/** + * 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 . + **/ + + +#pragma once + +#include +#include + +#include "ICommand.h" + +namespace OrthancStone +{ + + class ICommandBuilder : public boost::noncopyable + { + public: + virtual ICommand* CreateFromJson(const Json::Value& commandJson) = 0; + }; +} diff -r 6c22e0506587 -r be2660b6e40a Applications/Commands/ICommandFactory.h --- a/Applications/Commands/ICommandFactory.h Tue Sep 18 18:20:10 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#include -#include - -#include "ICommand.h" - -namespace OrthancStone -{ - - class ICommandFactory : public boost::noncopyable - { - public: - virtual ICommand* CreateFromJson(const Json::Value& commandJson) = 0; - template void RegisterCommandClass(); - }; -} diff -r 6c22e0506587 -r be2660b6e40a Applications/IStoneApplication.h --- a/Applications/IStoneApplication.h Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/IStoneApplication.h Tue Sep 25 15:14:53 2018 +0200 @@ -25,6 +25,8 @@ #include #include "../Framework/Viewport/WidgetViewport.h" #include "json/json.h" +#include "Commands/ICommand.h" +#include "Commands/BaseCommandBuilder.h" namespace OrthancStone { @@ -53,6 +55,12 @@ virtual IWidget* GetCentralWidget() = 0; virtual void Finalize() = 0; + + virtual BaseCommandBuilder& GetCommandBuilder() = 0; + + virtual void ExecuteCommand(ICommand& command) + { + } }; } diff -r 6c22e0506587 -r be2660b6e40a Applications/Samples/SampleApplicationBase.h --- a/Applications/Samples/SampleApplicationBase.h Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/Samples/SampleApplicationBase.h Tue Sep 25 15:14:53 2018 +0200 @@ -29,6 +29,8 @@ { class SampleApplicationBase : public IStoneApplication { + protected: + BaseCommandBuilder commandBuilder_; public: virtual void Initialize(StoneApplicationContext* context, IStatusBar& statusBar, @@ -57,6 +59,8 @@ tool2 = "tool2"; } + virtual BaseCommandBuilder& GetCommandBuilder() {return commandBuilder_;} + }; } } diff -r 6c22e0506587 -r be2660b6e40a Applications/Samples/SimpleViewerApplication.h --- a/Applications/Samples/SimpleViewerApplication.h Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/Samples/SimpleViewerApplication.h Tue Sep 25 15:14:53 2018 +0200 @@ -32,7 +32,7 @@ #include "../../Framework/SmartLoader.h" #if ORTHANC_ENABLE_WASM==1 -#include "../../Platforms/Wasm/IStoneApplicationToWebApplicationAdapter.h" +#include "../../Platforms/Wasm/WasmPlatformApplicationAdapter.h" #include "../../Platforms/Wasm/Defaults.h" #endif #include @@ -43,9 +43,6 @@ { class SimpleViewerApplication : public SampleApplicationBase, -#if ORTHANC_ENABLE_WASM==1 - public IStoneApplicationToWebApplicationAdapter, -#endif public IObserver { private: @@ -172,6 +169,38 @@ } }; + +#if ORTHANC_ENABLE_WASM==1 + class SimpleViewerApplicationAdapter : public WasmPlatformApplicationAdapter + { + public: + SimpleViewerApplicationAdapter(MessageBroker& broker, SimpleViewerApplication& application) + : WasmPlatformApplicationAdapter(broker, application) + { + + } + + virtual void HandleMessageFromWeb(std::string& output, const std::string& input) { + if (input == "select-tool:line-measure") + { + application.currentTool_ = Tools_LineMeasure; + NotifyStatusUpdateFromCppToWeb("currentTool=line-measure"); + } + else if (input == "select-tool:circle-measure") + { + application.currentTool_ = Tools_CircleMeasure; + NotifyStatusUpdateFromCppToWeb("currentTool=circle-measure"); + } + + output = "ok"; + } + + virtual void NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage) { + UpdateStoneApplicationStatusFromCpp(statusUpdateMessage.c_str()); + } + + }; +#endif enum Tools { Tools_LineMeasure, Tools_CircleMeasure @@ -251,7 +280,7 @@ mainLayout_->AddWidget(mainWidget_); // sources - smartLoader_.reset(new SmartLoader(broker_, context_->GetWebService())); + smartLoader_.reset(new SmartLoader(IObserver::broker_, context_->GetWebService())); smartLoader_->SetImageQuality(SliceImageQuality_FullPam); mainLayout_->SetTransmitMouseOver(true); @@ -263,7 +292,7 @@ statusBar.SetMessage("Use the key \"s\" to reinitialize the layout"); statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport"); - orthancApiClient_.reset(new OrthancApiClient(broker_, context_->GetWebService())); + orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService())); if (parameters.count("studyId") < 1) { @@ -328,7 +357,7 @@ void LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId) { LOG(INFO) << "Loading thumbnail for series " << seriesId; - LayerWidget* thumbnailWidget = new LayerWidget(broker_, "thumbnail-series-" + seriesId); + LayerWidget* thumbnailWidget = new LayerWidget(IObserver::broker_, "thumbnail-series-" + seriesId); thumbnails_.push_back(thumbnailWidget); thumbnailsLayout_->AddWidget(thumbnailWidget); thumbnailWidget->RegisterObserverCallback(new Callable(*this, &SimpleViewerApplication::OnWidgetGeometryChanged)); @@ -371,25 +400,6 @@ } #if ORTHANC_ENABLE_WASM==1 - virtual void HandleMessageFromWeb(std::string& output, const std::string& input) { - if (input == "select-tool:line-measure") - { - currentTool_ = Tools_LineMeasure; - NotifyStatusUpdateFromCppToWeb("currentTool=line-measure"); - } - else if (input == "select-tool:circle-measure") - { - currentTool_ = Tools_CircleMeasure; - NotifyStatusUpdateFromCppToWeb("currentTool=circle-measure"); - } - - output = "ok"; - } - - virtual void NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage) { - UpdateStoneApplicationStatusFromCpp(statusUpdateMessage.c_str()); - } - virtual void InitializeWasm() { AttachWidgetToWasmViewport("canvas", thumbnailsLayout_); diff -r 6c22e0506587 -r be2660b6e40a Applications/Samples/Web/simple-viewer.ts --- a/Applications/Samples/Web/simple-viewer.ts Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/Samples/Web/simple-viewer.ts Tue Sep 25 15:14:53 2018 +0200 @@ -3,11 +3,23 @@ InitializeWasmApplication("OrthancStoneSimpleViewer", "/orthanc"); function SelectTool(toolName: string) { - SendMessageToStoneApplication("select-tool:" + toolName); + var command = { + command: "selectTool", + args: { + toolName: toolName + } + }; + SendMessageToStoneApplication(JSON.stringify(command)); + } -function PerformAction(actionName: string) { - SendMessageToStoneApplication("perform-action:" + actionName); +function PerformAction(commandName: string) { + var command = { + command: commandName, + commandType: "simple", + args: {} + }; + SendMessageToStoneApplication(JSON.stringify(command)); } //initializes the buttons diff -r 6c22e0506587 -r be2660b6e40a Applications/Samples/build-wasm.sh --- a/Applications/Samples/build-wasm.sh Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/Samples/build-wasm.sh Tue Sep 25 15:14:53 2018 +0200 @@ -1,5 +1,7 @@ #!/bin/bash +set -e + currentDir=$(pwd) samplesRootDir=$(pwd) diff -r 6c22e0506587 -r be2660b6e40a Applications/Samples/build-web.sh --- a/Applications/Samples/build-web.sh Tue Sep 18 18:20:10 2018 +0200 +++ b/Applications/Samples/build-web.sh Tue Sep 25 15:14:53 2018 +0200 @@ -1,5 +1,7 @@ #!/bin/bash +set -e + # this script currently assumes that the wasm code has been built on its side and is availabie in Wasm/build/ currentDir=$(pwd) diff -r 6c22e0506587 -r be2660b6e40a Framework/StoneException.h --- a/Framework/StoneException.h Tue Sep 18 18:20:10 2018 +0200 +++ b/Framework/StoneException.h Tue Sep 25 15:14:53 2018 +0200 @@ -32,9 +32,11 @@ ErrorCode_OrthancError, // this StoneException is actually an OrthancException with an Orthanc error code ErrorCode_ApplicationException, // this StoneException is specific to an application (and should have its own internal error code) ErrorCode_NotImplemented, // case not implemented + ErrorCode_PromiseSingleSuccessHandler, // a Promise can only have a single success handler ErrorCode_PromiseSingleFailureHandler, // a Promise can only have a single failure handler + ErrorCode_CommandJsonInvalidFormat, ErrorCode_Last }; diff -r 6c22e0506587 -r be2660b6e40a Platforms/Wasm/Defaults.cpp --- a/Platforms/Wasm/Defaults.cpp Tue Sep 18 18:20:10 2018 +0200 +++ b/Platforms/Wasm/Defaults.cpp Tue Sep 25 15:14:53 2018 +0200 @@ -7,7 +7,7 @@ #include #include #include "Applications/Wasm/StartupParametersBuilder.h" -#include "Platforms/Wasm/IStoneApplicationToWebApplicationAdapter.h" +#include "Platforms/Wasm/WasmPlatformApplicationAdapter.h" static unsigned int width_ = 0; static unsigned int height_ = 0; @@ -15,7 +15,7 @@ /**********************************/ static std::unique_ptr application; -static OrthancStone::IStoneApplicationToWebApplicationAdapter* applicationWebAdapter = NULL; +static std::unique_ptr applicationWasmAdapter = NULL; static std::unique_ptr context; static OrthancStone::StartupParametersBuilder startupParametersBuilder; static OrthancStone::MessageBroker broker; @@ -69,7 +69,7 @@ printf("CreateWasmApplication\n"); application.reset(CreateUserApplication(broker)); - applicationWebAdapter = dynamic_cast(application.get()); + applicationWasmAdapter.reset(CreateWasmApplicationAdapter(broker, application.get())); WasmWebService::SetBroker(broker); startupParametersBuilder.Clear(); @@ -261,12 +261,16 @@ { static std::string output; // we don't want the string to be deallocated when we return to JS code so we always use the same string (this is fine since JS is single-thread) - if (applicationWebAdapter != NULL) { - printf("sending message to C++"); - applicationWebAdapter->HandleMessageFromWeb(output, std::string(message)); + printf("SendMessageToStoneApplication\n"); + printf(message); + + if (applicationWasmAdapter.get() != NULL) { + printf("sending message to C++\n"); + applicationWasmAdapter->HandleMessageFromWeb(output, std::string(message)); return output.c_str(); } - return "This stone application does not have a Web Adapter"; + printf("This stone application does not have a Web Adapter"); + return NULL; } diff -r 6c22e0506587 -r be2660b6e40a Platforms/Wasm/Defaults.h --- a/Platforms/Wasm/Defaults.h Tue Sep 18 18:20:10 2018 +0200 +++ b/Platforms/Wasm/Defaults.h Tue Sep 25 15:14:53 2018 +0200 @@ -7,6 +7,7 @@ #include #include #include +#include typedef OrthancStone::WidgetViewport* ViewportHandle; // the objects exchanged between JS and C++ @@ -27,7 +28,9 @@ } #endif +// these methods must be implemented in the custom app "mainWasm.cpp" extern OrthancStone::IStoneApplication* CreateUserApplication(OrthancStone::MessageBroker& broker); +extern OrthancStone::WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(OrthancStone::MessageBroker& broker, OrthancStone::IStoneApplication* application); namespace OrthancStone { diff -r 6c22e0506587 -r be2660b6e40a Platforms/Wasm/IStoneApplicationToWebApplicationAdapter.h --- a/Platforms/Wasm/IStoneApplicationToWebApplicationAdapter.h Tue Sep 18 18:20:10 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace OrthancStone -{ - class IStoneApplicationToWebApplicationAdapter - { - public: - virtual void HandleMessageFromWeb(std::string& output, const std::string& input) = 0; - virtual void NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage) = 0; - }; -} \ No newline at end of file diff -r 6c22e0506587 -r be2660b6e40a Platforms/Wasm/WasmPlatformApplicationAdapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp Tue Sep 25 15:14:53 2018 +0200 @@ -0,0 +1,42 @@ +#include "WasmPlatformApplicationAdapter.h" + +#include "Framework/Toolbox/MessagingToolbox.h" +#include "Framework/StoneException.h" +#include +#include +#include "Platforms/Wasm/Defaults.h" + +namespace OrthancStone +{ + WasmPlatformApplicationAdapter::WasmPlatformApplicationAdapter(MessageBroker& broker, IStoneApplication& application) + : IObserver(broker), + application_(application) + { + } + + void WasmPlatformApplicationAdapter::HandleMessageFromWeb(std::string& output, const std::string& input) + { + try + { + Json::Value inputJson; + if (MessagingToolbox::ParseJson(inputJson, input.c_str(), input.size())) + { + std::unique_ptr command(application_.GetCommandBuilder().CreateFromJson(inputJson)); + application_.ExecuteCommand(*command); + } + } + catch (StoneException& exc) + { + printf("Error while handling message from web (error code = %d):\n", exc.GetErrorCode()); + printf("While interpreting input: '%s'\n", input.c_str()); + } + } + + void WasmPlatformApplicationAdapter::NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage) + { + printf("NotifyStatusUpdateFromCppToWeb (TODO)\n"); + UpdateStoneApplicationStatusFromCpp(statusUpdateMessage.c_str()); + printf("NotifyStatusUpdateFromCppToWeb (DONE)\n"); + } + +} \ No newline at end of file diff -r 6c22e0506587 -r be2660b6e40a Platforms/Wasm/WasmPlatformApplicationAdapter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/Wasm/WasmPlatformApplicationAdapter.h Tue Sep 25 15:14:53 2018 +0200 @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include + +namespace OrthancStone +{ + class WasmPlatformApplicationAdapter : public IObserver + { + IStoneApplication& application_; + public: + WasmPlatformApplicationAdapter(MessageBroker& broker, IStoneApplication& application); + + virtual void HandleMessageFromWeb(std::string& output, const std::string& input); + virtual void NotifyStatusUpdateFromCppToWeb(const std::string& statusUpdateMessage); + }; +} \ No newline at end of file diff -r 6c22e0506587 -r be2660b6e40a Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Tue Sep 18 18:20:10 2018 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Tue Sep 25 15:14:53 2018 +0200 @@ -164,10 +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/BaseCommandBuilder.cpp ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommand.h ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandExecutor.h - ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandFactory.h + ${ORTHANC_STONE_ROOT}/Applications/Commands/ICommandBuilder.h ) if (NOT ORTHANC_SANDBOXED) @@ -203,7 +203,7 @@ ${ORTHANC_STONE_ROOT}/Platforms/Wasm/Defaults.cpp ${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmWebService.cpp ${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmViewport.cpp - ${ORTHANC_STONE_ROOT}/Platforms/Wasm/IStoneApplicationToWebApplicationAdapter.h + ${ORTHANC_STONE_ROOT}/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp ${AUTOGENERATED_DIR}/WasmWebService.c ${AUTOGENERATED_DIR}/default-library.c ) diff -r 6c22e0506587 -r be2660b6e40a UnitTestsSources/TestCommands.cpp --- a/UnitTestsSources/TestCommands.cpp Tue Sep 18 18:20:10 2018 +0200 +++ b/UnitTestsSources/TestCommands.cpp Tue Sep 25 15:14:53 2018 +0200 @@ -1,108 +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 . - **/ +///** +// * 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 . +// **/ -#include "gtest/gtest.h" +//#include "gtest/gtest.h" -#include "../Applications/Commands/BaseCommandFactory.h" -#include "Core/OrthancException.h" +//#include "../Applications/Commands/BaseCommandFactory.h" +//#include "Core/OrthancException.h" -class CommandIncrement: public OrthancStone::BaseCommand -{ -public: - static int counter; - int increment_; -public: - CommandIncrement() - : OrthancStone::BaseCommand("increment"), - increment_(0) - {} +//class CommandIncrement: public OrthancStone::BaseCommand +//{ +//public: +// static int counter; +// int increment_; +//public: +// CommandIncrement() +// : OrthancStone::BaseCommand("increment"), +// increment_(0) +// {} - virtual void Execute() - { - counter += increment_; - } - virtual void Configure(const Json::Value& arguments) - { - increment_ = arguments["increment"].asInt(); - } -}; +// 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) +//// COMMAND("name", "arg1", "int", "arg2", "string") +//// COMMAND(name, arg1, arg2) -int CommandIncrement::counter = 0; +//int CommandIncrement::counter = 0; -TEST(Commands, CreateNoop) -{ - OrthancStone::BaseCommandFactory factory; +//TEST(Commands, CreateNoop) +//{ +// OrthancStone::BaseCommandFactory factory; - factory.RegisterCommandClass(); +// factory.RegisterCommandClass(); - Json::Value cmdJson; - cmdJson["command"] = "noop"; +// Json::Value cmdJson; +// cmdJson["command"] = "noop"; - std::auto_ptr command(factory.CreateFromJson(cmdJson)); +// std::auto_ptr command(factory.CreateFromJson(cmdJson)); - ASSERT_TRUE(command.get() != NULL); - ASSERT_EQ("noop", command->GetName()); -} +// ASSERT_TRUE(command.get() != NULL); +// ASSERT_EQ("noop", command->GetName()); +//} -TEST(Commands, Execute) -{ - OrthancStone::BaseCommandFactory factory; +//TEST(Commands, Execute) +//{ +// OrthancStone::BaseCommandFactory factory; - factory.RegisterCommandClass(); - factory.RegisterCommandClass(); +// factory.RegisterCommandClass(); +// factory.RegisterCommandClass(); - Json::Value cmdJson; - cmdJson["command"] = "increment"; - cmdJson["args"]["increment"] = 2; +// Json::Value cmdJson; +// cmdJson["command"] = "increment"; +// cmdJson["args"]["increment"] = 2; - std::auto_ptr command(factory.CreateFromJson(cmdJson)); +// std::auto_ptr command(factory.CreateFromJson(cmdJson)); - ASSERT_TRUE(command.get() != NULL); - CommandIncrement::counter = 0; - command->Execute(); - ASSERT_EQ(2, CommandIncrement::counter); -} +// ASSERT_TRUE(command.get() != NULL); +// CommandIncrement::counter = 0; +// command->Execute(); +// ASSERT_EQ(2, CommandIncrement::counter); +//} -TEST(Commands, TryCreateUnknowCommand) -{ - OrthancStone::BaseCommandFactory factory; - factory.RegisterCommandClass(); +//TEST(Commands, TryCreateUnknowCommand) +//{ +// OrthancStone::BaseCommandFactory factory; +// factory.RegisterCommandClass(); - Json::Value cmdJson; - cmdJson["command"] = "unknown"; +// Json::Value cmdJson; +// cmdJson["command"] = "unknown"; - ASSERT_THROW(std::auto_ptr command(factory.CreateFromJson(cmdJson)), Orthanc::OrthancException); -} +// ASSERT_THROW(std::auto_ptr command(factory.CreateFromJson(cmdJson)), Orthanc::OrthancException); +//} -TEST(Commands, TryCreateCommandFromInvalidJson) -{ - OrthancStone::BaseCommandFactory factory; - factory.RegisterCommandClass(); +//TEST(Commands, TryCreateCommandFromInvalidJson) +//{ +// OrthancStone::BaseCommandFactory factory; +// factory.RegisterCommandClass(); - Json::Value cmdJson; - cmdJson["command-name"] = "noop"; +// Json::Value cmdJson; +// cmdJson["command-name"] = "noop"; - ASSERT_THROW(std::auto_ptr command(factory.CreateFromJson(cmdJson)), Orthanc::OrthancException); -} +// ASSERT_THROW(std::auto_ptr command(factory.CreateFromJson(cmdJson)), Orthanc::OrthancException); +//} diff -r 6c22e0506587 -r be2660b6e40a UnitTestsSources/UnitTestsMain.cpp --- a/UnitTestsSources/UnitTestsMain.cpp Tue Sep 18 18:20:10 2018 +0200 +++ b/UnitTestsSources/UnitTestsMain.cpp Tue Sep 25 15:14:53 2018 +0200 @@ -26,6 +26,7 @@ #include "../Framework/Layers/LayerSourceBase.h" #include "../Framework/Toolbox/DownloadStack.h" #include "../Framework/Toolbox/FiniteProjectiveCamera.h" +#include "../Framework/Toolbox/MessagingToolbox.h" #include "../Framework/Toolbox/OrthancSlicesLoader.h" #include "../Framework/Volumes/ImageBuffer3D.h" #include "../Framework/Volumes/SlicedVolumeBase.h" @@ -724,6 +725,12 @@ */ } +TEST(MessagingToolbox, ParseJson) +{ + Json::Value response; + std::string source = "{\"command\":\"panel:takeDarkImage\",\"commandType\":\"simple\",\"args\":{}}"; + ASSERT_TRUE(OrthancStone::MessagingToolbox::ParseJson(response, source.c_str(), source.size())); +} int main(int argc, char **argv) {