comparison Applications/Sdl/BasicSdlApplication.cpp @ 274:dc1beee33134 am-2

split SdlApplication into NativeApplication and SdlApplication
author am@osimis.io
date Fri, 24 Aug 2018 13:52:55 +0200
parents 46c5296d867e
children 5de5699ad570
comparison
equal deleted inserted replaced
273:f21ba2468570 274:dc1beee33134
35 #include <Plugins/Samples/Common/OrthancHttpConnection.h> 35 #include <Plugins/Samples/Common/OrthancHttpConnection.h>
36 #include "../../Platforms/Generic/OracleWebService.h" 36 #include "../../Platforms/Generic/OracleWebService.h"
37 37
38 namespace OrthancStone 38 namespace OrthancStone
39 { 39 {
40 // Anonymous namespace to avoid clashes against other compilation modules 40 void BasicSdlApplication::Initialize()
41 namespace
42 { 41 {
43 class LogStatusBar : public IStatusBar 42 SdlWindow::GlobalInitialize();
44 {
45 public:
46 virtual void ClearMessage()
47 {
48 }
49
50 virtual void SetMessage(const std::string& message)
51 {
52 LOG(WARNING) << message;
53 }
54 };
55 } 43 }
56 44
57 45 void BasicSdlApplication::DeclareCommandLineOptions(boost::program_options::options_description& options)
58 static void DeclareSdlCommandLineOptions(boost::program_options::options_description& options)
59 { 46 {
60 // Declare the supported parameters 47 // Declare the supported parameters
61 boost::program_options::options_description generic("Generic options"); 48 boost::program_options::options_description generic("Generic options");
62 generic.add_options() 49 generic.add_options()
63 ("help", "Display this help and exit") 50 ("help", "Display this help and exit")
64 ("verbose", "Be verbose in logs") 51 ("verbose", "Be verbose in logs")
65 ("orthanc", boost::program_options::value<std::string>()->default_value("http://localhost:8042/"), 52 ("orthanc", boost::program_options::value<std::string>()->default_value("http://localhost:8042/"),
66 "URL to the Orthanc server") 53 "URL to the Orthanc server")
67 ("username", "Username for the Orthanc server") 54 ("username", "Username for the Orthanc server")
68 ("password", "Password for the Orthanc server") 55 ("password", "Password for the Orthanc server")
69 ("https-verify", boost::program_options::value<bool>()->default_value(true), "Check HTTPS certificates") 56 ("https-verify", boost::program_options::value<bool>()->default_value(true), "Check HTTPS certificates")
70 ; 57 ;
71 58
72 options.add(generic); 59 options.add(generic);
73 60
74 boost::program_options::options_description sdl("SDL options"); 61 boost::program_options::options_description sdl("SDL options");
75 sdl.add_options() 62 sdl.add_options()
76 ("width", boost::program_options::value<int>()->default_value(1024), "Initial width of the SDL window") 63 ("width", boost::program_options::value<int>()->default_value(1024), "Initial width of the SDL window")
77 ("height", boost::program_options::value<int>()->default_value(768), "Initial height of the SDL window") 64 ("height", boost::program_options::value<int>()->default_value(768), "Initial height of the SDL window")
78 ("opengl", boost::program_options::value<bool>()->default_value(true), "Enable OpenGL in SDL") 65 ("opengl", boost::program_options::value<bool>()->default_value(true), "Enable OpenGL in SDL")
79 ; 66 ;
80 67
81 options.add(sdl); 68 options.add(sdl);
82 } 69 }
83 70
71 void BasicSdlApplication::Run(BasicNativeApplicationContext& context, const std::string& title, unsigned int width, unsigned int height, bool enableOpenGl)
72 {
73 /**************************************************************
74 * Run the application inside a SDL window
75 **************************************************************/
84 76
85 int BasicSdlApplication::ExecuteWithSdl(MessageBroker& broker, 77 LOG(WARNING) << "Starting the application";
86 IBasicApplication& application, 78
87 int argc, 79 SdlWindow window(title.c_str(), width, height, enableOpenGl);
88 char* argv[]) 80 SdlEngine sdl(window, context);
81
82 {
83 BasicNativeApplicationContext::GlobalMutexLocker locker(context);
84 context.GetCentralViewport().Register(sdl); // (*)
85 }
86
87 context.Start();
88 sdl.Run();
89
90 LOG(WARNING) << "Stopping the application";
91
92 // Don't move the "Stop()" command below out of the block,
93 // otherwise the application might crash, because the
94 // "SdlEngine" is an observer of the viewport (*) and the
95 // update thread started by "context.Start()" would call a
96 // destructed object (the "SdlEngine" is deleted with the
97 // lexical scope).
98 context.Stop();
99 }
100
101 void BasicSdlApplication::Finalize()
89 { 102 {
90 /****************************************************************** 103 SdlWindow::GlobalFinalize();
91 * Initialize all the subcomponents of Orthanc Stone 104 }
92 ******************************************************************/
93
94 Orthanc::Logging::Initialize();
95 Orthanc::Toolbox::InitializeOpenSsl();
96 Orthanc::HttpClient::GlobalInitialize();
97 SdlWindow::GlobalInitialize();
98 105
99 106
100 /******************************************************************
101 * Declare and parse the command-line options of the application
102 ******************************************************************/
103
104 boost::program_options::options_description options;
105 DeclareSdlCommandLineOptions(options);
106 application.DeclareStartupOptions(options);
107
108 boost::program_options::variables_map parameters;
109 bool error = false;
110
111 try
112 {
113 boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
114 options(options).run(), parameters);
115 boost::program_options::notify(parameters);
116 }
117 catch (boost::program_options::error& e)
118 {
119 LOG(ERROR) << "Error while parsing the command-line arguments: " << e.what();
120 error = true;
121 }
122
123
124 /******************************************************************
125 * Configure the application with the command-line parameters
126 ******************************************************************/
127
128 if (error || parameters.count("help"))
129 {
130 std::cout << std::endl
131 << "Usage: " << argv[0] << " [OPTION]..."
132 << std::endl
133 << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research."
134 << std::endl << std::endl
135 << "Demonstration application of Orthanc Stone using SDL."
136 << std::endl;
137
138 std::cout << options << "\n";
139 return error ? -1 : 0;
140 }
141
142 if (parameters.count("https-verify") &&
143 !parameters["https-verify"].as<bool>())
144 {
145 LOG(WARNING) << "Turning off verification of HTTPS certificates (unsafe)";
146 Orthanc::HttpClient::ConfigureSsl(false, "");
147 }
148
149 if (parameters.count("verbose"))
150 {
151 Orthanc::Logging::EnableInfoLevel(true);
152 }
153
154 if (!parameters.count("width") ||
155 !parameters.count("height") ||
156 !parameters.count("opengl"))
157 {
158 LOG(ERROR) << "Parameter \"width\", \"height\" or \"opengl\" is missing";
159 return -1;
160 }
161
162 int w = parameters["width"].as<int>();
163 int h = parameters["height"].as<int>();
164 if (w <= 0 || h <= 0)
165 {
166 LOG(ERROR) << "Parameters \"width\" and \"height\" must be positive";
167 return -1;
168 }
169
170 unsigned int width = static_cast<unsigned int>(w);
171 unsigned int height = static_cast<unsigned int>(h);
172 LOG(WARNING) << "Initial display size: " << width << "x" << height;
173
174 bool opengl = parameters["opengl"].as<bool>();
175 if (opengl)
176 {
177 LOG(WARNING) << "OpenGL is enabled, disable it with option \"--opengl=off\" if the application crashes";
178 }
179 else
180 {
181 LOG(WARNING) << "OpenGL is disabled, enable it with option \"--opengl=on\" for best performance";
182 }
183
184 bool success = true;
185 try
186 {
187 /****************************************************************
188 * Initialize the connection to the Orthanc server
189 ****************************************************************/
190
191 Orthanc::WebServiceParameters webServiceParameters;
192
193 if (parameters.count("orthanc"))
194 {
195 webServiceParameters.SetUrl(parameters["orthanc"].as<std::string>());
196 }
197
198 if (parameters.count("username"))
199 {
200 webServiceParameters.SetUsername(parameters["username"].as<std::string>());
201 }
202
203 if (parameters.count("password"))
204 {
205 webServiceParameters.SetPassword(parameters["password"].as<std::string>());
206 }
207
208 LOG(WARNING) << "URL to the Orthanc REST API: " << webServiceParameters.GetUrl();
209
210 {
211 OrthancPlugins::OrthancHttpConnection orthanc(webServiceParameters);
212 if (!MessagingToolbox::CheckOrthancVersion(orthanc))
213 {
214 LOG(ERROR) << "Your version of Orthanc is incompatible with Stone of Orthanc, please upgrade";
215 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
216 }
217 }
218
219
220 /****************************************************************
221 * Initialize the application
222 ****************************************************************/
223
224 LOG(WARNING) << "Creating the widgets of the application";
225
226 LogStatusBar statusBar;
227
228 BasicSdlApplicationContext context;
229 Oracle oracle(4); // use 4 threads to download content
230 OracleWebService webService(broker, oracle, webServiceParameters, context);
231 context.SetWebService(webService);
232
233 application.Initialize(&context, statusBar, parameters);
234
235 {
236 BasicSdlApplicationContext::GlobalMutexLocker locker(context);
237 context.SetCentralWidget(application.GetCentralWidget());
238 context.GetCentralViewport().SetStatusBar(statusBar);
239 }
240
241 std::string title = application.GetTitle();
242 if (title.empty())
243 {
244 title = "Stone of Orthanc";
245 }
246
247 {
248 /**************************************************************
249 * Run the application inside a SDL window
250 **************************************************************/
251
252 LOG(WARNING) << "Starting the application";
253
254 SdlWindow window(title.c_str(), width, height, opengl);
255 SdlEngine sdl(window, context);
256
257 {
258 BasicSdlApplicationContext::GlobalMutexLocker locker(context);
259 context.GetCentralViewport().Register(sdl); // (*)
260 }
261
262 context.Start();
263 sdl.Run();
264
265 LOG(WARNING) << "Stopping the application";
266
267 // Don't move the "Stop()" command below out of the block,
268 // otherwise the application might crash, because the
269 // "SdlEngine" is an observer of the viewport (*) and the
270 // update thread started by "context.Start()" would call a
271 // destructed object (the "SdlEngine" is deleted with the
272 // lexical scope).
273 context.Stop();
274 }
275
276
277 /****************************************************************
278 * Finalize the application
279 ****************************************************************/
280
281 LOG(WARNING) << "The application has stopped";
282 application.Finalize();
283 }
284 catch (Orthanc::OrthancException& e)
285 {
286 LOG(ERROR) << "EXCEPTION: " << e.What();
287 success = false;
288 }
289
290
291 /******************************************************************
292 * Finalize all the subcomponents of Orthanc Stone
293 ******************************************************************/
294
295 SdlWindow::GlobalFinalize();
296 Orthanc::HttpClient::GlobalFinalize();
297 Orthanc::Toolbox::FinalizeOpenSsl();
298
299 return (success ? 0 : -1);
300 }
301
302 } 107 }