changeset 435:e641d3978856 am-vsol-upgrade

WasmWebService now using BaseWebService and supporting cache
author am@osimis.io
date Tue, 04 Dec 2018 11:52:43 +0100
parents 3a8bcc45c221
children 04711a2e12cd
files Applications/Samples/build-wasm.sh Applications/Samples/build-web.sh Framework/Toolbox/BaseWebService.cpp Framework/Toolbox/BaseWebService.h Platforms/Wasm/WasmWebService.cpp Platforms/Wasm/WasmWebService.h Platforms/Wasm/WasmWebService.js Platforms/Wasm/wasm-application-runner.ts
diffstat 8 files changed, 100 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/build-wasm.sh	Mon Dec 03 18:03:30 2018 +0100
+++ b/Applications/Samples/build-wasm.sh	Tue Dec 04 11:52:43 2018 +0100
@@ -1,7 +1,16 @@
 #!/bin/bash
+#
+# usage:
+# to build all targets:
+# ./build-wasm.sh
+#
+# to build a single target:
+# ./build-wasm.sh OrthancStoneSingleFrameEditor
 
 set -e
 
+target=${1:-all}
+
 currentDir=$(pwd)
 samplesRootDir=$(pwd)
 
@@ -10,7 +19,7 @@
 
 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
+make -j 5 $target
 
 echo "-- building the web application -- "
 cd $currentDir
--- a/Applications/Samples/build-web.sh	Mon Dec 03 18:03:30 2018 +0100
+++ b/Applications/Samples/build-web.sh	Tue Dec 04 11:52:43 2018 +0100
@@ -2,6 +2,7 @@
 
 set -e
 
+target=${1:-all}
 # this script currently assumes that the wasm code has been built on its side and is availabie in build-wasm/
 
 currentDir=$(pwd)
@@ -15,29 +16,37 @@
 cp $samplesRootDir/Web/samples-styles.css $outputDir
 
 # build simple-viewer-single-file (obsolete project)
-cp $samplesRootDir/Web/simple-viewer-single-file.html $outputDir
-tsc --allowJs --project $samplesRootDir/Web/simple-viewer-single-file.tsconfig.json
-cp $currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.js  $outputDir
-cp $currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.wasm  $outputDir
+if [[ $target == "all" || $target == "OrthancStoneSimpleViewerSingleFile" ]]; then
+  cp $samplesRootDir/Web/simple-viewer-single-file.html $outputDir
+  tsc --allowJs --project $samplesRootDir/Web/simple-viewer-single-file.tsconfig.json
+  cp $currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.js  $outputDir
+  cp $currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.wasm  $outputDir
+fi
 
 # build single-frame
-cp $samplesRootDir/Web/single-frame.html $outputDir
-tsc --allowJs --project $samplesRootDir/Web/single-frame.tsconfig.json
-cp $currentDir/build-wasm/OrthancStoneSingleFrame.js  $outputDir
-cp $currentDir/build-wasm/OrthancStoneSingleFrame.wasm  $outputDir
+if [[ $target == "all" || $target == "OrthancStoneSingleFrame" ]]; then
+  cp $samplesRootDir/Web/single-frame.html $outputDir
+  tsc --allowJs --project $samplesRootDir/Web/single-frame.tsconfig.json
+  cp $currentDir/build-wasm/OrthancStoneSingleFrame.js  $outputDir
+  cp $currentDir/build-wasm/OrthancStoneSingleFrame.wasm  $outputDir
+fi
 
 # build single-frame-editor
-cp $samplesRootDir/Web/single-frame-editor.html $outputDir
-tsc --allowJs --project $samplesRootDir/Web/single-frame-editor.tsconfig.json
-cp $currentDir/build-wasm/OrthancStoneSingleFrameEditor.js  $outputDir
-cp $currentDir/build-wasm/OrthancStoneSingleFrameEditor.wasm  $outputDir
+if [[ $target == "all" || $target == "OrthancStoneSingleFrameEditor" ]]; then
+  cp $samplesRootDir/Web/single-frame-editor.html $outputDir
+  tsc --allowJs --project $samplesRootDir/Web/single-frame-editor.tsconfig.json
+  cp $currentDir/build-wasm/OrthancStoneSingleFrameEditor.js  $outputDir
+  cp $currentDir/build-wasm/OrthancStoneSingleFrameEditor.wasm  $outputDir
+fi
 
 # build simple-viewer project
-mkdir -p $outputDir/simple-viewer/
-cp $samplesRootDir/SimpleViewer/Wasm/simple-viewer.html $outputDir/simple-viewer/
-cp $samplesRootDir/SimpleViewer/Wasm/styles.css $outputDir/simple-viewer/
-tsc --allowJs --project $samplesRootDir/SimpleViewer/Wasm/tsconfig-simple-viewer.json
-cp $currentDir/build-wasm/OrthancStoneSimpleViewer.js  $outputDir/simple-viewer/
-cp $currentDir/build-wasm/OrthancStoneSimpleViewer.wasm  $outputDir/simple-viewer/
+if [[ $target == "all" || $target == "OrthancStoneSimpleViewer" ]]; then
+  mkdir -p $outputDir/simple-viewer/
+  cp $samplesRootDir/SimpleViewer/Wasm/simple-viewer.html $outputDir/simple-viewer/
+  cp $samplesRootDir/SimpleViewer/Wasm/styles.css $outputDir/simple-viewer/
+  tsc --allowJs --project $samplesRootDir/SimpleViewer/Wasm/tsconfig-simple-viewer.json
+  cp $currentDir/build-wasm/OrthancStoneSimpleViewer.js  $outputDir/simple-viewer/
+  cp $currentDir/build-wasm/OrthancStoneSimpleViewer.wasm  $outputDir/simple-viewer/
+fi
 
 cd $currentDir
--- a/Framework/Toolbox/BaseWebService.cpp	Mon Dec 03 18:03:30 2018 +0100
+++ b/Framework/Toolbox/BaseWebService.cpp	Tue Dec 04 11:52:43 2018 +0100
@@ -24,7 +24,7 @@
 #include <Core/OrthancException.h>
 #include "Framework/Messages/IObservable.h"
 #include "Platforms/Generic/IOracleCommand.h"
-
+#include <boost/shared_ptr.hpp>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/BaseWebService.h	Mon Dec 03 18:03:30 2018 +0100
+++ b/Framework/Toolbox/BaseWebService.h	Tue Dec 04 11:52:43 2018 +0100
@@ -32,7 +32,7 @@
   // the HTTP GET requests
   class BaseWebService : public IWebService, public IObserver
   {
-  protected:
+  public:
     class CachedHttpRequestSuccessMessage
     {
     protected:
@@ -77,7 +77,7 @@
       }
 
     };
-
+  protected:
     class BaseWebServicePayload;
 
     bool          cacheEnabled_;
--- a/Platforms/Wasm/WasmWebService.cpp	Mon Dec 03 18:03:30 2018 +0100
+++ b/Platforms/Wasm/WasmWebService.cpp	Tue Dec 04 11:52:43 2018 +0100
@@ -2,6 +2,15 @@
 #include "json/value.h"
 #include "json/writer.h"
 #include <emscripten/emscripten.h>
+#include <boost/shared_ptr.hpp>
+
+struct CachedSuccessNotification
+{
+  boost::shared_ptr<OrthancStone::BaseWebService::CachedHttpRequestSuccessMessage>    cachedMessage;
+  std::auto_ptr<Orthanc::IDynamicObject>                                              payload;
+  OrthancStone::MessageHandler<OrthancStone::IWebService::HttpRequestSuccessMessage>* successCallback;
+};
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -14,6 +23,8 @@
                                       void* payload,
                                       unsigned int timeoutInSeconds);
 
+  extern void WasmWebService_ScheduleLaterCachedSuccessNotification(void* brol);
+
   extern void WasmWebService_PostAsync(void* callableSuccess,
                                        void* callableFailure,
                                        const char* uri,
@@ -45,6 +56,20 @@
     }
   }
 
+  void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifyCachedSuccess(void* notification_)
+  {
+    // notification has been allocated in C++ and passed to JS.  It must be deleted by this method
+    std::auto_ptr<CachedSuccessNotification> notification(reinterpret_cast<CachedSuccessNotification*>(notification_));
+
+    notification->successCallback->Apply(OrthancStone::IWebService::HttpRequestSuccessMessage(
+      notification->cachedMessage->GetUri(), 
+      notification->cachedMessage->GetAnswer(),
+      notification->cachedMessage->GetAnswerSize(),
+      notification->cachedMessage->GetAnswerHttpHeaders(),
+      notification->payload.get()
+      ));
+  }
+
   void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifySuccess(void* successCallable,
                                                          const char* uri,
                                                          const void* body,
@@ -61,7 +86,7 @@
       OrthancStone::IWebService::HttpHeaders headers;
 
       // TODO - Parse "answerHeaders"
-      printf("[%s]\n", answerHeaders);
+      printf("TODO: parse headers [%s]\n", answerHeaders);
       
       reinterpret_cast<OrthancStone::MessageHandler<OrthancStone::IWebService::HttpRequestSuccessMessage>*>(successCallable)->
         Apply(OrthancStone::IWebService::HttpRequestSuccessMessage(uri, body, bodySize, headers,
@@ -134,4 +159,17 @@
     WasmWebService_GetAsync(successCallable, failureCallable, relativeUri.c_str(),
                             headersInJsonString.c_str(), payload, timeoutInSeconds);
   }
+
+  void WasmWebService::NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedMessage,
+                                                Orthanc::IDynamicObject* payload, // takes ownership
+                                                MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback)
+  {
+    CachedSuccessNotification* notification = new CachedSuccessNotification();  // allocated on the heap, it will be passed to JS and deleted when coming back to C++
+    notification->cachedMessage = cachedMessage;
+    notification->payload.reset(payload);
+    notification->successCallback = successCallback;
+
+    WasmWebService_ScheduleLaterCachedSuccessNotification(notification);
+  }
+
 }
--- a/Platforms/Wasm/WasmWebService.h	Mon Dec 03 18:03:30 2018 +0100
+++ b/Platforms/Wasm/WasmWebService.h	Tue Dec 04 11:52:43 2018 +0100
@@ -1,17 +1,17 @@
 #pragma once
 
-#include <Framework/Toolbox/IWebService.h>
+#include <Framework/Toolbox/BaseWebService.h>
 #include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
-class WasmWebService : public IWebService
+class WasmWebService : public BaseWebService
 {
 private:
   static MessageBroker *broker_;
 
   // Private constructor => Singleton design pattern
-  WasmWebService(MessageBroker &broker) : IWebService(broker)
+  WasmWebService(MessageBroker &broker) : BaseWebService(broker)
   {
   }
 
@@ -32,13 +32,6 @@
     broker_ = &broker;
   }
 
-  virtual void GetAsyncInternal(const std::string &uri,
-                                const HttpHeaders &headers,
-                                Orthanc::IDynamicObject *payload,
-                                MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallable,
-                                MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable = NULL,
-                                unsigned int timeoutInSeconds = 60);
-
   virtual void PostAsync(const std::string &uri,
                          const HttpHeaders &headers,
                          const std::string &body,
@@ -54,12 +47,16 @@
                            MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable = NULL,
                            unsigned int timeoutInSeconds = 60);
 
-  // virtual void Start()
-  // {
-  // }
+protected:
+  virtual void GetAsyncInternal(const std::string &uri,
+                                const HttpHeaders &headers,
+                                Orthanc::IDynamicObject *payload,
+                                MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallable,
+                                MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable = NULL,
+                                unsigned int timeoutInSeconds = 60);
 
-  // virtual void Stop()
-  // {
-  // }
+  virtual void NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedHttpMessage,
+                                      Orthanc::IDynamicObject *payload, // takes ownership
+                                      MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallback);
 };
 } // namespace OrthancStone
--- a/Platforms/Wasm/WasmWebService.js	Mon Dec 03 18:03:30 2018 +0100
+++ b/Platforms/Wasm/WasmWebService.js	Tue Dec 04 11:52:43 2018 +0100
@@ -35,6 +35,12 @@
     xhr.send();
   },
 
+  WasmWebService_ScheduleLaterCachedSuccessNotification: function (brol) {
+    setTimeout(function() {
+      WasmWebService_NotifyCachedSuccess(brol);
+    }, 0);
+  },
+
   WasmWebService_PostAsync: function(callableSuccess, callableFailure, url, headersInJsonString, body, bodySize, payload, timeoutInSeconds) {
     var xhr = new XMLHttpRequest();
     var url_ = UTF8ToString(url);
--- a/Platforms/Wasm/wasm-application-runner.ts	Mon Dec 03 18:03:30 2018 +0100
+++ b/Platforms/Wasm/wasm-application-runner.ts	Tue Dec 04 11:52:43 2018 +0100
@@ -10,6 +10,7 @@
 // global functions
 var WasmWebService_NotifyError: Function = null;
 var WasmWebService_NotifySuccess: Function = null;
+var WasmWebService_NotifyCachedSuccess: Function = null;
 var WasmDelayedCallExecutor_ExecuteCallback: Function = null;
 var WasmDoAnimation: Function = null;
 var SetStartupParameter: Function = null;
@@ -92,6 +93,7 @@
     ReleaseCppViewport = StoneFrameworkModule.cwrap('ReleaseCppViewport', null, ['number']);
     StartWasmApplication = StoneFrameworkModule.cwrap('StartWasmApplication', null, ['string']);
 
+    WasmWebService_NotifyCachedSuccess = StoneFrameworkModule.cwrap('WasmWebService_NotifyCachedSuccess', null, ['number']);
     WasmWebService_NotifySuccess = StoneFrameworkModule.cwrap('WasmWebService_NotifySuccess', null, ['number', 'string', 'array', 'number', 'number']);
     WasmWebService_NotifyError = StoneFrameworkModule.cwrap('WasmWebService_NotifyError', null, ['number', 'string', 'number']);
     WasmDelayedCallExecutor_ExecuteCallback = StoneFrameworkModule.cwrap('WasmDelayedCallExecutor_ExecuteCallback', null, ['number']);