1 // Created on: 2003-08-11
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
18 #include <DrawTrSurf.hxx>
19 #include <Message.hxx>
20 #include <Message_PrinterOStream.hxx>
21 #include <NCollection_IndexedMap.hxx>
23 #include <OSD_Thread.hxx>
24 #include <Standard_ErrorHandler.hxx>
26 #ifdef OCCT_NO_PLUGINS
27 #include <BOPTest.hxx>
28 #include <DPrsStd.hxx>
29 #if defined(HAVE_OPENGL) || defined(HAVE_GLES2)
30 #include <OpenGlTest.hxx>
32 #include <TObjDRAW.hxx>
33 #include <ViewerTest.hxx>
34 #include <XSDRAWSTLVRML.hxx>
35 #include <XDEDRAW.hxx>
38 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
40 #if defined(__EMSCRIPTEN__)
41 #include <emscripten/bind.h>
42 #include <emscripten/emscripten.h>
43 #include <emscripten/threading.h>
45 //! Signal async command completion to Module.evalAsyncCompleted callback.
46 EM_JS(void, occJSEvalAsyncCompleted, (int theResult), {
47 if (Module.evalAsyncCompleted != undefined) {
48 Module.evalAsyncCompleted (theResult);
50 console.error ("Module.evalAsyncCompleted() is undefined");
54 //! Draw Harness interface for JavaScript.
58 //! Evaluate Tcl command.
59 static int eval (const std::string& theCommand)
65 //aRes = Draw::GetInterpretor().Eval (theCommand.c_str());
66 aRes = Draw_Interprete (theCommand.c_str()) ? 1 : 0;
68 catch (Standard_Failure& anExcept)
70 std::cout << "Failed to evaluate command: " << anExcept.GetMessageString() << std::endl;
75 //! Check if Tcl command is complete.
76 static bool isComplete (const std::string& theCommand)
78 return Draw::GetInterpretor().Complete (theCommand.c_str());
81 //! Evaluate Tcl command asynchronously.
82 static void evalAsync (const std::string& theCommand)
84 #if defined(__EMSCRIPTEN_PTHREADS__)
85 std::string* aCmdPtr = new std::string (theCommand);
86 OSD_Thread aThread (&evalAsyncEntry);
87 aThread.Run (aCmdPtr);
89 // fallback synchronous implementation
90 int aRes = eval (theCommand);
91 occJSEvalAsyncCompleted (aRes);
95 #if defined(__EMSCRIPTEN_PTHREADS__)
97 //! Thread entry for async command execution.
98 static Standard_Address evalAsyncEntry (Standard_Address theData)
100 OSD::SetSignal (false);
101 std::string* aCmdPtr = (std::string* )theData;
102 const std::string aCmd = *aCmdPtr;
104 int aRes = eval (aCmd);
105 emscripten_async_run_in_main_runtime_thread (EM_FUNC_SIG_VI, evalAsyncCompletedEntry, aRes);
109 //! Notify Module.evalAsyncCompleted about async cmd completion.
110 static void evalAsyncCompletedEntry (int theResult)
112 occJSEvalAsyncCompleted (theResult);
117 //! Print message to Module.printMessage callback.
118 EM_JS(void, occJSPrintMessage, (const char* theStr, int theGravity), {
119 if (Module.printMessage != undefined && Module.printMessage != null) {
120 Module.printMessage (UTF8ToString(theStr), theGravity);
121 } else if (Module.print != undefined && Module.print != null) {
122 Module.print (UTF8ToString(theStr));
124 //console.info (UTF8ToString(theStr));
128 //! Auxiliary printer to a Module.printMessage callback accepting text and gravity.
129 class DRAWEXE_WasmModulePrinter : public Message_Printer
131 DEFINE_STANDARD_RTTI_INLINE(DRAWEXE_WasmModulePrinter, Message_Printer)
134 //! Main constructor.
135 DRAWEXE_WasmModulePrinter (const Message_Gravity theTraceLevel = Message_Info)
137 SetTraceLevel (theTraceLevel);
141 virtual ~DRAWEXE_WasmModulePrinter() {}
146 virtual void send (const TCollection_AsciiString& theString,
147 const Message_Gravity theGravity) const Standard_OVERRIDE
149 if (theGravity >= myTraceLevel)
151 occJSPrintMessage (theString.ToCString(), (int )theGravity);
156 EMSCRIPTEN_BINDINGS(DRAWEXE) {
157 emscripten::function("eval", &DRAWEXE::eval);
158 emscripten::function("evalAsync", &DRAWEXE::evalAsync);
159 emscripten::function("isComplete", &DRAWEXE::isComplete);
163 #ifdef OCCT_NO_PLUGINS
164 //! Mimic pload command by loading pre-defined set of statically linked plugins.
165 static Standard_Integer Pload (Draw_Interpretor& theDI,
166 Standard_Integer theNbArgs,
167 const char** theArgVec)
169 NCollection_IndexedMap<TCollection_AsciiString, TCollection_AsciiString> aPlugins;
170 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
172 TCollection_AsciiString anArg (theArgVec[anArgIter]);
174 if (anArg == "DEFAULT")
176 aPlugins.Add ("TOPTEST");
178 else if (anArg == "MODELING")
180 aPlugins.Add ("TOPTEST");
182 else if (anArg == "VISUALIZATION")
184 aPlugins.Add ("AISV");
186 else if (anArg == "OCAFKERNEL")
188 aPlugins.Add ("DCAF");
190 else if (anArg == "DATAEXCHANGEKERNEL")
192 aPlugins.Add ("XSDRAW");
194 else if (anArg == "OCAF")
196 aPlugins.Add ("AISV");
197 aPlugins.Add ("DCAF");
199 else if (anArg == "DATAEXCHANGE")
201 aPlugins.Add ("XSDRAW");
202 aPlugins.Add ("XDEDRAW");
203 aPlugins.Add ("AISV");
205 else if (anArg == "XDE")
207 aPlugins.Add ("XSDRAW");
208 aPlugins.Add ("XDEDRAW");
210 else if (anArg == "ALL")
212 aPlugins.Add ("TOPTEST");
213 aPlugins.Add ("DCAF");
214 aPlugins.Add ("XSDRAW");
215 aPlugins.Add ("XDEDRAW");
216 aPlugins.Add ("AISV");
220 aPlugins.Add (anArg);
224 for (NCollection_IndexedMap<TCollection_AsciiString, TCollection_AsciiString>::Iterator aPluginIter (aPlugins);
225 aPluginIter.More(); aPluginIter.Next())
227 const TCollection_AsciiString& aPlugin = aPluginIter.Value();
228 if (aPlugin == "TOPTEST")
230 BOPTest::Factory (theDI);
232 else if (aPlugin == "DCAF")
234 DPrsStd::Factory (theDI);
236 else if (aPlugin == "AISV")
238 ViewerTest::Factory (theDI);
240 #if defined(HAVE_OPENGL)
241 else if (aPlugin == "GL"
242 || aPlugin == "OPENGL")
244 OpenGlTest::Factory (theDI);
247 #if defined(HAVE_GLES2)
248 else if (aPlugin == "GLES"
249 || aPlugin == "OPENGLES")
251 OpenGlTest::Factory (theDI);
254 else if (aPlugin == "XSDRAW")
256 XSDRAWSTLVRML::Factory (theDI);
258 else if (aPlugin == "XDEDRAW")
260 XDEDRAW::Factory (theDI);
262 //else if (aPlugin == "TOBJ") { TObjDRAW::Factory (theDI); }
263 //else if (aPlugin == "QACOMMANDS") { QADraw::Factory (theDI); }
266 theDI << "Error: unknown plugin '" << aPlugin << "'";
275 //=======================================================================
276 //function : Draw_InitAppli
278 //=======================================================================
280 void Draw_InitAppli (Draw_Interpretor& theDI)
282 #if defined(__EMSCRIPTEN__)
283 // open JavaScript console within the Browser to see this output
284 Message_Gravity aGravity = Message_Info;
285 Handle(Message_PrinterSystemLog) aJSConsolePrinter = new Message_PrinterSystemLog ("DRAWEXE", aGravity);
286 Message::DefaultMessenger()->AddPrinter (aJSConsolePrinter);
287 // replace printer into std::cout by a printer into a custom callback Module.printMessage accepting message gravity
288 Message::DefaultMessenger()->RemovePrinters (STANDARD_TYPE(Message_PrinterOStream));
289 Handle(DRAWEXE_WasmModulePrinter) aJSModulePrinter = new DRAWEXE_WasmModulePrinter (aGravity);
290 Message::DefaultMessenger()->AddPrinter (aJSModulePrinter);
293 Draw::Commands (theDI);
294 DBRep::BasicCommands (theDI);
295 DrawTrSurf::BasicCommands (theDI);
297 #ifdef OCCT_NO_PLUGINS
298 theDI.Add ("pload" , "pload [[Key1] [Key2] ...]: Loads Draw plugins",
299 __FILE__, Pload, "Draw Plugin");
303 #include <Draw_Main.hxx>