Mercurial > hg > orthanc-stone
annotate Platforms/Wasm/Defaults.cpp @ 407:842a3c7cfdc0
renames
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 12 Nov 2018 11:44:20 +0100 |
parents | 3e6e10a5a6c8 |
children | aee3d7941c9b |
rev | line source |
---|---|
222 | 1 #include "Defaults.h" |
2 | |
223 | 3 #include "WasmWebService.h" |
4 #include <Framework/dev.h> | |
5 #include "Framework/Widgets/TestCairoWidget.h" | |
6 #include <Framework/Viewport/WidgetViewport.h> | |
228 | 7 #include <algorithm> |
242 | 8 #include "Applications/Wasm/StartupParametersBuilder.h" |
307 | 9 #include "Platforms/Wasm/WasmPlatformApplicationAdapter.h" |
223 | 10 |
11 static unsigned int width_ = 0; | |
12 static unsigned int height_ = 0; | |
13 | |
14 /**********************************/ | |
15 | |
288 | 16 static std::unique_ptr<OrthancStone::IStoneApplication> application; |
307 | 17 static std::unique_ptr<OrthancStone::WasmPlatformApplicationAdapter> applicationWasmAdapter = NULL; |
288 | 18 static std::unique_ptr<OrthancStone::StoneApplicationContext> context; |
242 | 19 static OrthancStone::StartupParametersBuilder startupParametersBuilder; |
253 | 20 static OrthancStone::MessageBroker broker; |
242 | 21 |
385
6cc3ce74dc05
using message broker in widgets
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
22 static OrthancStone::ViewportContentChangedObserver viewportContentChangedObserver_(broker); |
223 | 23 static OrthancStone::StatusBar statusBar_; |
24 | |
227 | 25 static std::list<std::shared_ptr<OrthancStone::WidgetViewport>> viewports_; |
26 | |
228 | 27 std::shared_ptr<OrthancStone::WidgetViewport> FindViewportSharedPtr(ViewportHandle viewport) { |
28 for (const auto& v : viewports_) { | |
29 if (v.get() == viewport) { | |
30 return v; | |
31 } | |
32 } | |
229 | 33 assert(false); |
34 return std::shared_ptr<OrthancStone::WidgetViewport>(); | |
228 | 35 } |
36 | |
223 | 37 #ifdef __cplusplus |
38 extern "C" { | |
39 #endif | |
40 | |
41 using namespace OrthancStone; | |
227 | 42 |
43 // when WASM needs a C++ viewport | |
44 ViewportHandle EMSCRIPTEN_KEEPALIVE CreateCppViewport() { | |
45 | |
385
6cc3ce74dc05
using message broker in widgets
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
46 std::shared_ptr<OrthancStone::WidgetViewport> viewport(new OrthancStone::WidgetViewport(broker)); |
287 | 47 printf("viewport %x\n", (int)viewport.get()); |
227 | 48 |
49 viewports_.push_back(viewport); | |
50 | |
51 printf("There are now %d viewports in C++\n", viewports_.size()); | |
52 | |
53 viewport->SetStatusBar(statusBar_); | |
385
6cc3ce74dc05
using message broker in widgets
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
54 |
6cc3ce74dc05
using message broker in widgets
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
55 viewport->RegisterObserverCallback( |
6cc3ce74dc05
using message broker in widgets
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
56 new Callable<ViewportContentChangedObserver, IViewport::ViewportChangedMessage> |
6cc3ce74dc05
using message broker in widgets
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
57 (viewportContentChangedObserver_, &ViewportContentChangedObserver::OnViewportChanged)); |
227 | 58 |
59 return viewport.get(); | |
60 } | |
61 | |
62 // when WASM does not need a viewport anymore, it should release it | |
63 void EMSCRIPTEN_KEEPALIVE ReleaseCppViewport(ViewportHandle viewport) { | |
64 viewports_.remove_if([viewport](const std::shared_ptr<OrthancStone::WidgetViewport>& v) { return v.get() == viewport;}); | |
65 | |
66 printf("There are now %d viewports in C++\n", viewports_.size()); | |
67 } | |
68 | |
69 void EMSCRIPTEN_KEEPALIVE CreateWasmApplication(ViewportHandle viewport) { | |
223 | 70 |
71 printf("CreateWasmApplication\n"); | |
72 | |
253 | 73 application.reset(CreateUserApplication(broker)); |
307 | 74 applicationWasmAdapter.reset(CreateWasmApplicationAdapter(broker, application.get())); |
255 | 75 WasmWebService::SetBroker(broker); |
223 | 76 |
242 | 77 startupParametersBuilder.Clear(); |
223 | 78 } |
79 | |
80 void EMSCRIPTEN_KEEPALIVE SetStartupParameter(const char* keyc, | |
81 const char* value) { | |
242 | 82 startupParametersBuilder.SetStartupParameter(keyc, value); |
223 | 83 } |
84 | |
231
5027cb2feb51
viewport is now part of the Application itself and not global anymore
am@osimis.io
parents:
229
diff
changeset
|
85 void EMSCRIPTEN_KEEPALIVE StartWasmApplication() { |
223 | 86 |
87 printf("StartWasmApplication\n"); | |
88 | |
89 // recreate a command line from uri arguments and parse it | |
90 boost::program_options::variables_map parameters; | |
242 | 91 boost::program_options::options_description options; |
92 application->DeclareStartupOptions(options); | |
93 startupParametersBuilder.GetStartupParameters(parameters, options); | |
223 | 94 |
288 | 95 context.reset(new OrthancStone::StoneApplicationContext()); |
272 | 96 context->SetWebService(OrthancStone::WasmWebService::GetInstance()); |
242 | 97 application->Initialize(context.get(), statusBar_, parameters); |
98 application->InitializeWasm(); | |
223 | 99 |
231
5027cb2feb51
viewport is now part of the Application itself and not global anymore
am@osimis.io
parents:
229
diff
changeset
|
100 // viewport->SetSize(width_, height_); |
223 | 101 printf("StartWasmApplication - completed\n"); |
102 } | |
103 | |
386
e33659decec5
renamed UpdateContent() as DoAnimation()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
385
diff
changeset
|
104 void EMSCRIPTEN_KEEPALIVE WasmDoAnimation() |
223 | 105 { |
228 | 106 for (auto viewport : viewports_) { |
386
e33659decec5
renamed UpdateContent() as DoAnimation()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
385
diff
changeset
|
107 // TODO Only launch the JavaScript timer if "HasAnimation()" |
e33659decec5
renamed UpdateContent() as DoAnimation()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
385
diff
changeset
|
108 if (viewport->HasAnimation()) |
228 | 109 { |
386
e33659decec5
renamed UpdateContent() as DoAnimation()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
385
diff
changeset
|
110 viewport->DoAnimation(); |
228 | 111 } |
112 | |
223 | 113 } |
114 | |
115 } | |
116 | |
117 | |
228 | 118 void EMSCRIPTEN_KEEPALIVE ViewportSetSize(ViewportHandle viewport, unsigned int width, unsigned int height) |
223 | 119 { |
120 width_ = width; | |
121 height_ = height; | |
122 | |
228 | 123 viewport->SetSize(width, height); |
223 | 124 } |
125 | |
228 | 126 int EMSCRIPTEN_KEEPALIVE ViewportRender(ViewportHandle viewport, |
227 | 127 unsigned int width, |
223 | 128 unsigned int height, |
129 uint8_t* data) | |
130 { | |
278 | 131 viewportContentChangedObserver_.Reset(); |
223 | 132 |
133 //printf("ViewportRender called %dx%d\n", width, height); | |
134 if (width == 0 || | |
135 height == 0) | |
136 { | |
137 return 1; | |
138 } | |
139 | |
140 Orthanc::ImageAccessor surface; | |
141 surface.AssignWritable(Orthanc::PixelFormat_BGRA32, width, height, 4 * width, data); | |
142 | |
227 | 143 viewport->Render(surface); |
223 | 144 |
145 // Convert from BGRA32 memory layout (only color mode supported by | |
146 // Cairo, which corresponds to CAIRO_FORMAT_ARGB32) to RGBA32 (as | |
147 // expected by HTML5 canvas). This simply amounts to swapping the | |
148 // B and R channels. | |
149 uint8_t* p = data; | |
150 for (unsigned int y = 0; y < height; y++) { | |
151 for (unsigned int x = 0; x < width; x++) { | |
152 uint8_t tmp = p[0]; | |
153 p[0] = p[2]; | |
154 p[2] = tmp; | |
155 | |
156 p += 4; | |
157 } | |
158 } | |
159 | |
160 return 1; | |
161 } | |
162 | |
163 | |
228 | 164 void EMSCRIPTEN_KEEPALIVE ViewportMouseDown(ViewportHandle viewport, |
165 unsigned int rawButton, | |
223 | 166 int x, |
167 int y, | |
168 unsigned int rawModifiers) | |
169 { | |
170 OrthancStone::MouseButton button; | |
171 switch (rawButton) | |
172 { | |
173 case 0: | |
174 button = OrthancStone::MouseButton_Left; | |
175 break; | |
176 | |
177 case 1: | |
178 button = OrthancStone::MouseButton_Middle; | |
179 break; | |
180 | |
181 case 2: | |
182 button = OrthancStone::MouseButton_Right; | |
183 break; | |
184 | |
185 default: | |
186 return; // Unknown button | |
187 } | |
188 | |
228 | 189 viewport->MouseDown(button, x, y, OrthancStone::KeyboardModifiers_None /* TODO */); |
223 | 190 } |
191 | |
192 | |
228 | 193 void EMSCRIPTEN_KEEPALIVE ViewportMouseWheel(ViewportHandle viewport, |
194 int deltaY, | |
223 | 195 int x, |
196 int y, | |
197 int isControl) | |
198 { | |
228 | 199 if (deltaY != 0) |
223 | 200 { |
201 OrthancStone::MouseWheelDirection direction = (deltaY < 0 ? | |
202 OrthancStone::MouseWheelDirection_Up : | |
203 OrthancStone::MouseWheelDirection_Down); | |
204 OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None; | |
205 | |
206 if (isControl != 0) | |
207 { | |
208 modifiers = OrthancStone::KeyboardModifiers_Control; | |
209 } | |
210 | |
228 | 211 viewport->MouseWheel(direction, x, y, modifiers); |
223 | 212 } |
213 } | |
214 | |
215 | |
228 | 216 void EMSCRIPTEN_KEEPALIVE ViewportMouseMove(ViewportHandle viewport, |
217 int x, | |
223 | 218 int y) |
219 { | |
228 | 220 viewport->MouseMove(x, y); |
223 | 221 } |
222 | |
228 | 223 void EMSCRIPTEN_KEEPALIVE ViewportKeyPressed(ViewportHandle viewport, |
327 | 224 int key, |
225 const char* keyChar, | |
223 | 226 bool isShiftPressed, |
227 bool isControlPressed, | |
228 bool isAltPressed) | |
229 | |
230 { | |
228 | 231 OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None; |
232 if (isShiftPressed) { | |
233 modifiers = static_cast<OrthancStone::KeyboardModifiers>(modifiers + OrthancStone::KeyboardModifiers_Shift); | |
223 | 234 } |
228 | 235 if (isControlPressed) { |
236 modifiers = static_cast<OrthancStone::KeyboardModifiers>(modifiers + OrthancStone::KeyboardModifiers_Control); | |
237 } | |
238 if (isAltPressed) { | |
239 modifiers = static_cast<OrthancStone::KeyboardModifiers>(modifiers + OrthancStone::KeyboardModifiers_Alt); | |
240 } | |
327 | 241 |
242 char c = 0; | |
243 if (keyChar != NULL && key == OrthancStone::KeyboardKeys_Generic) { | |
244 c = keyChar[0]; | |
245 } | |
246 viewport->KeyPressed(static_cast<OrthancStone::KeyboardKeys>(key), c, modifiers); | |
223 | 247 } |
248 | |
249 | |
228 | 250 void EMSCRIPTEN_KEEPALIVE ViewportMouseUp(ViewportHandle viewport) |
223 | 251 { |
228 | 252 viewport->MouseUp(); |
223 | 253 } |
254 | |
255 | |
228 | 256 void EMSCRIPTEN_KEEPALIVE ViewportMouseEnter(ViewportHandle viewport) |
223 | 257 { |
228 | 258 viewport->MouseEnter(); |
223 | 259 } |
260 | |
261 | |
228 | 262 void EMSCRIPTEN_KEEPALIVE ViewportMouseLeave(ViewportHandle viewport) |
223 | 263 { |
228 | 264 viewport->MouseLeave(); |
223 | 265 } |
266 | |
287 | 267 const char* EMSCRIPTEN_KEEPALIVE SendMessageToStoneApplication(const char* message) |
268 { | |
269 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) | |
270 | |
307 | 271 printf("SendMessageToStoneApplication\n"); |
309 | 272 printf("%s", message); |
307 | 273 |
274 if (applicationWasmAdapter.get() != NULL) { | |
275 printf("sending message to C++\n"); | |
276 applicationWasmAdapter->HandleMessageFromWeb(output, std::string(message)); | |
287 | 277 return output.c_str(); |
278 } | |
307 | 279 printf("This stone application does not have a Web Adapter"); |
280 return NULL; | |
287 | 281 } |
282 | |
223 | 283 |
284 #ifdef __cplusplus | |
285 } | |
286 #endif |