Mercurial > hg > orthanc-stone
diff Applications/IBasicApplication.cpp @ 260:c887eddd48f1 am-2
merge
author | am@osimis.io |
---|---|
date | Tue, 17 Jul 2018 14:43:42 +0200 |
parents | 092db46c6291 106a0f9781d9 |
children |
line wrap: on
line diff
--- a/Applications/IBasicApplication.cpp Tue Jul 10 14:48:13 2018 +0200 +++ b/Applications/IBasicApplication.cpp Tue Jul 17 14:43:42 2018 +0200 @@ -26,9 +26,267 @@ #include <Core/Logging.h> #include <Core/HttpClient.h> +#include <Core/Toolbox.h> #include <Plugins/Samples/Common/OrthancHttpConnection.h> namespace OrthancStone { + // Anonymous namespace to avoid clashes against other compilation modules + namespace + { + class LogStatusBar : public IStatusBar + { + public: + virtual void ClearMessage() + { + } + + virtual void SetMessage(const std::string& message) + { + LOG(WARNING) << message; + } + }; + } + + +#if ORTHANC_ENABLE_SDL == 1 + static void DeclareSdlCommandLineOptions(boost::program_options::options_description& options) + { + // Declare the supported parameters + boost::program_options::options_description generic("Generic options"); + generic.add_options() + ("help", "Display this help and exit") + ("verbose", "Be verbose in logs") + ("orthanc", boost::program_options::value<std::string>()->default_value("http://localhost:8042/"), + "URL to the Orthanc server") + ("username", "Username for the Orthanc server") + ("password", "Password for the Orthanc server") + ("https-verify", boost::program_options::value<bool>()->default_value(true), "Check HTTPS certificates") + ; + + options.add(generic); + + boost::program_options::options_description sdl("SDL options"); + sdl.add_options() + ("width", boost::program_options::value<int>()->default_value(1024), "Initial width of the SDL window") + ("height", boost::program_options::value<int>()->default_value(768), "Initial height of the SDL window") + ("opengl", boost::program_options::value<bool>()->default_value(true), "Enable OpenGL in SDL") + ; + + options.add(sdl); + } + + + int IBasicApplication::ExecuteWithSdl(IBasicApplication& application, + int argc, + char* argv[]) + { + /****************************************************************** + * Initialize all the subcomponents of Orthanc Stone + ******************************************************************/ + + Orthanc::Logging::Initialize(); + Orthanc::Toolbox::InitializeOpenSsl(); + Orthanc::HttpClient::GlobalInitialize(); + SdlWindow::GlobalInitialize(); + + + /****************************************************************** + * Declare and parse the command-line options of the application + ******************************************************************/ + + boost::program_options::options_description options; + DeclareSdlCommandLineOptions(options); + application.DeclareCommandLineOptions(options); + + boost::program_options::variables_map parameters; + bool error = false; + + try + { + boost::program_options::store(boost::program_options::command_line_parser(argc, argv). + options(options).run(), parameters); + boost::program_options::notify(parameters); + } + catch (boost::program_options::error& e) + { + LOG(ERROR) << "Error while parsing the command-line arguments: " << e.what(); + error = true; + } + + + /****************************************************************** + * Configure the application with the command-line parameters + ******************************************************************/ + + if (error || parameters.count("help")) + { + std::cout << std::endl + << "Usage: " << argv[0] << " [OPTION]..." + << std::endl + << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." + << std::endl << std::endl + << "Demonstration application of Orthanc Stone using SDL." + << std::endl; + + std::cout << options << "\n"; + return error ? -1 : 0; + } + + if (parameters.count("https-verify") && + !parameters["https-verify"].as<bool>()) + { + LOG(WARNING) << "Turning off verification of HTTPS certificates (unsafe)"; + Orthanc::HttpClient::ConfigureSsl(false, ""); + } + + if (parameters.count("verbose")) + { + Orthanc::Logging::EnableInfoLevel(true); + } + + if (!parameters.count("width") || + !parameters.count("height") || + !parameters.count("opengl")) + { + LOG(ERROR) << "Parameter \"width\", \"height\" or \"opengl\" is missing"; + return -1; + } + + int w = parameters["width"].as<int>(); + int h = parameters["height"].as<int>(); + if (w <= 0 || h <= 0) + { + LOG(ERROR) << "Parameters \"width\" and \"height\" must be positive"; + return -1; + } + + unsigned int width = static_cast<unsigned int>(w); + unsigned int height = static_cast<unsigned int>(h); + LOG(WARNING) << "Initial display size: " << width << "x" << height; + + bool opengl = parameters["opengl"].as<bool>(); + if (opengl) + { + LOG(WARNING) << "OpenGL is enabled, disable it with option \"--opengl=off\" if the application crashes"; + } + else + { + LOG(WARNING) << "OpenGL is disabled, enable it with option \"--opengl=on\" for best performance"; + } + + bool success = true; + try + { + /**************************************************************** + * Initialize the connection to the Orthanc server + ****************************************************************/ + + Orthanc::WebServiceParameters webService; + + if (parameters.count("orthanc")) + { + webService.SetUrl(parameters["orthanc"].as<std::string>()); + } + + if (parameters.count("username")) + { + webService.SetUsername(parameters["username"].as<std::string>()); + } + + if (parameters.count("password")) + { + webService.SetPassword(parameters["password"].as<std::string>()); + } + + LOG(WARNING) << "URL to the Orthanc REST API: " << webService.GetUrl(); + + { + OrthancPlugins::OrthancHttpConnection orthanc(webService); + if (!MessagingToolbox::CheckOrthancVersion(orthanc)) + { + LOG(ERROR) << "Your version of Orthanc is incompatible with Stone of Orthanc, please upgrade"; + throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + } + } + + + /**************************************************************** + * Initialize the application + ****************************************************************/ + + LOG(WARNING) << "Creating the widgets of the application"; + + LogStatusBar statusBar; + BasicApplicationContext context(webService); + + application.Initialize(context, statusBar, parameters); + + { + BasicApplicationContext::ViewportLocker locker(context); + locker.GetViewport().SetStatusBar(statusBar); + } + + std::string title = application.GetTitle(); + if (title.empty()) + { + title = "Stone of Orthanc"; + } + + { + /************************************************************** + * Run the application inside a SDL window + **************************************************************/ + + LOG(WARNING) << "Starting the application"; + + SdlWindow window(title.c_str(), width, height, opengl); + SdlEngine sdl(window, context); + + { + BasicApplicationContext::ViewportLocker locker(context); + locker.GetViewport().Register(sdl); // (*) + } + + context.Start(); + sdl.Run(); + + LOG(WARNING) << "Stopping the application"; + + // Don't move the "Stop()" command below out of the block, + // otherwise the application might crash, because the + // "SdlEngine" is an observer of the viewport (*) and the + // update thread started by "context.Start()" would call a + // destructed object (the "SdlEngine" is deleted with the + // lexical scope). + context.Stop(); + } + + + /**************************************************************** + * Finalize the application + ****************************************************************/ + + LOG(WARNING) << "The application has stopped"; + application.Finalize(); + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "EXCEPTION: " << e.What(); + success = false; + } + + + /****************************************************************** + * Finalize all the subcomponents of Orthanc Stone + ******************************************************************/ + + SdlWindow::GlobalFinalize(); + Orthanc::HttpClient::GlobalFinalize(); + Orthanc::Toolbox::FinalizeOpenSsl(); + + return (success ? 0 : -1); + } +#endif }