0032342: Draw Harness - preload basic Tcl scripts into WebAssembly
authorkgv <kgv@opencascade.com>
Thu, 29 Apr 2021 19:13:20 +0000 (22:13 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 30 Apr 2021 15:39:33 +0000 (18:39 +0300)
DrawResources Tcl scripts and $tcl_library (init.tcl) are now preloaded into WebAssembly emulated filesystem for DRAWEXE.wasm.
DRAWEXE now mimics "pload" command for statically linked plugins.

src/DRAWEXE/CMakeLists.txt
src/DRAWEXE/DRAWEXE.cxx

index 45e9f4d..3c2b631 100644 (file)
@@ -28,6 +28,20 @@ unset (EXECUTABLE_PROJECT)
 unset (CUSTOM_EXTERNLIB)
 
 if (EMSCRIPTEN)
+  # Look for Tcl version string from file tcl.h
+  set (TCL_MAJOR_VERSION  8)
+  set (TCL_MINOR_VERSION  0)
+  set (TCL_RELEASE_SERIAL 0)
+  set (TCL_VERSION_FILE "${3RDPARTY_TCL_INCLUDE_DIR}/tcl.h")
+  if (EXISTS "${TCL_VERSION_FILE}")
+    file(READ "${TCL_VERSION_FILE}" aTclHeader)
+    foreach (SOUGHT_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_RELEASE_SERIAL)
+      string(REGEX MATCH "#define ${SOUGHT_VERSION} * [0-9]+" macrodef "${aTclHeader}")
+      string(REGEX MATCH "[0-9]+" ${SOUGHT_VERSION} "${macrodef}")
+    endforeach()
+  endif()
+  #message(STATUS "Tcl version: ${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}.${TCL_RELEASE_SERIAL}")
+
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MAX_WEBGL_VERSION=2")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
@@ -36,6 +50,13 @@ if (EMSCRIPTEN)
   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MODULARIZE=1")
   set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='createDRAWEXE'")
 
+  # Embed Draw Harness .tcl scripts at recognizable location.
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../DrawResources@/DrawResources")
+  # Tcl will look for "init.tcl" at path "$tcl_library/init.tcl" on startup (configurable from environment variable TCL_LIBRARY)
+  # In case of WebAssembly build $tcl_library looks like "tcl8.6.11/library" by default.
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --preload-file ${3RDPARTY_TCL_LIBRARY_DIR}/tcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}@/tcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}.${TCL_RELEASE_SERIAL}/library")
+
   install(FILES ${PROJECT_NAME}.html      DESTINATION "${INSTALL_DIR_BIN}/${OCCT_INSTALL_BIN_LETTER}")
   install(FILES ../DrawResources/lamp.ico DESTINATION "${INSTALL_DIR_BIN}/${OCCT_INSTALL_BIN_LETTER}")
+  install(FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/bin\${OCCT_INSTALL_BIN_LETTER}/${PROJECT_NAME}.data DESTINATION "${INSTALL_DIR_BIN}/${OCCT_INSTALL_BIN_LETTER}")
 endif()
index 4e3e7f4..0f4a2f2 100644 (file)
@@ -18,6 +18,8 @@
 #include <DrawTrSurf.hxx>
 #include <Message.hxx>
 #include <Message_PrinterSystemLog.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <Standard_ErrorHandler.hxx>
 
 #ifdef OCCT_NO_PLUGINS
   #include <BOPTest.hxx>
   #include <XDEDRAW.hxx>
 #endif
 
+#ifdef OCCT_NO_PLUGINS
+//! Mimic pload command by loading pre-defined set of statically linked plugins.
+static Standard_Integer Pload (Draw_Interpretor& theDI,
+                               Standard_Integer  theNbArgs,
+                               const char**      theArgVec)
+{
+  NCollection_IndexedMap<TCollection_AsciiString, TCollection_AsciiString> aPlugins;
+  for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.UpperCase();
+    if (anArg == "DEFAULT")
+    {
+      aPlugins.Add ("TOPTEST");
+    }
+    else if (anArg == "MODELING")
+    {
+      aPlugins.Add ("TOPTEST");
+    }
+    else if (anArg == "VISUALIZATION")
+    {
+      aPlugins.Add ("AISV");
+    }
+    else if (anArg == "OCAFKERNEL")
+    {
+      aPlugins.Add ("DCAF");
+    }
+    else if (anArg == "DATAEXCHANGEKERNEL")
+    {
+      aPlugins.Add ("XSDRAW");
+    }
+    else if (anArg == "OCAF")
+    {
+      aPlugins.Add ("AISV");
+      aPlugins.Add ("DCAF");
+    }
+    else if (anArg == "DATAEXCHANGE")
+    {
+      aPlugins.Add ("XSDRAW");
+      aPlugins.Add ("XDEDRAW");
+      aPlugins.Add ("AISV");
+    }
+    else if (anArg == "XDE")
+    {
+      aPlugins.Add ("XSDRAW");
+      aPlugins.Add ("XDEDRAW");
+    }
+    else if (anArg == "ALL")
+    {
+      aPlugins.Add ("TOPTEST");
+      aPlugins.Add ("DCAF");
+      aPlugins.Add ("XSDRAW");
+      aPlugins.Add ("XDEDRAW");
+      aPlugins.Add ("AISV");
+    }
+    else
+    {
+      aPlugins.Add (anArg);
+    }
+  }
+
+  for (NCollection_IndexedMap<TCollection_AsciiString, TCollection_AsciiString>::Iterator aPluginIter (aPlugins);
+       aPluginIter.More(); aPluginIter.Next())
+  {
+    const TCollection_AsciiString& aPlugin = aPluginIter.Value();
+    if (aPlugin == "TOPTEST")
+    {
+      BOPTest::Factory (theDI);
+    }
+    else if (aPlugin == "DCAF")
+    {
+      DPrsStd::Factory (theDI);
+    }
+    else if (aPlugin == "AISV")
+    {
+      ViewerTest::Factory (theDI);
+    }
+  #if defined(HAVE_OPENGL)
+    else if (aPlugin == "GL"
+          || aPlugin == "OPENGL")
+    {
+      OpenGlTest::Factory (theDI);
+    }
+  #endif
+  #if defined(HAVE_GLES2)
+    else if (aPlugin == "GLES"
+          || aPlugin == "OPENGLES")
+    {
+      OpenGlTest::Factory (theDI);
+    }
+  #endif
+    else if (aPlugin == "XSDRAW")
+    {
+      XSDRAWSTLVRML::Factory (theDI);
+    }
+    else if (aPlugin == "XDEDRAW")
+    {
+      XDEDRAW::Factory (theDI);
+    }
+    //else if (aPlugin == "TOBJ")       { TObjDRAW::Factory (theDI); }
+    //else if (aPlugin == "QACOMMANDS") { QADraw::Factory (theDI); }
+    else
+    {
+      theDI << "Error: unknown plugin '" << aPlugin << "'";
+      return 1;
+    }
+  }
+
+  return 0;
+}
+#endif
+
 //=======================================================================
 //function : Draw_InitAppli
 //purpose  : 
 //=======================================================================
 
-void Draw_InitAppli (Draw_Interpretor& di)
+void Draw_InitAppli (Draw_Interpretor& theDI)
 {
 #if defined(__EMSCRIPTEN__)
   // open JavaScript console within the Browser to see this output
@@ -44,22 +158,13 @@ void Draw_InitAppli (Draw_Interpretor& di)
   Message::DefaultMessenger()->AddPrinter (aJSConsolePrinter);
 #endif
 
-  Draw::Commands (di);
-  DBRep::BasicCommands (di);
-  DrawTrSurf::BasicCommands (di);
+  Draw::Commands (theDI);
+  DBRep::BasicCommands (theDI);
+  DrawTrSurf::BasicCommands (theDI);
 
 #ifdef OCCT_NO_PLUGINS
-  // load a couple of plugins
-  BOPTest::Factory (di);
-  DPrsStd::Factory (di);
-  XSDRAWSTLVRML::Factory (di);
-  XDEDRAW::Factory (di);
-  #if defined(HAVE_OPENGL) || defined(HAVE_GLES2)
-  ViewerTest::Factory (di);
-  OpenGlTest::Factory (di);
-  #endif
-  //TObjDRAW::Factory (di);
-  //QADraw::Factory (di);
+  theDI.Add ("pload" , "pload [[Key1] [Key2] ...]: Loads Draw plugins",
+             __FILE__, Pload, "Draw Plugin");
 #endif
 }