0032806: Coding - get rid of unused headers [Contap to Extrema]
[occt.git] / src / DRAWEXE / DRAWEXE.cxx
1 // Created on: 2003-08-11
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Draw.hxx>
17 #include <DBRep.hxx>
18 #include <DrawTrSurf.hxx>
19 #include <Message.hxx>
20 #include <Message_PrinterOStream.hxx>
21 #include <NCollection_IndexedMap.hxx>
22 #include <OSD.hxx>
23 #include <OSD_Thread.hxx>
24 #include <Standard_ErrorHandler.hxx>
25
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>
31   #endif
32   #include <TObjDRAW.hxx>
33   #include <ViewerTest.hxx>
34   #include <XSDRAWSTLVRML.hxx>
35   #include <XDEDRAW.hxx>
36 #endif
37
38 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
39
40 #if defined(__EMSCRIPTEN__)
41 #include <emscripten/bind.h>
42 #include <emscripten/emscripten.h>
43 #include <emscripten/threading.h>
44
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);
49   } else {
50     console.error ("Module.evalAsyncCompleted() is undefined");
51   }
52 });
53
54 //! Draw Harness interface for JavaScript.
55 class DRAWEXE
56 {
57 public:
58   //! Evaluate Tcl command.
59   static int eval (const std::string& theCommand)
60   {
61     int aRes = 0;
62     try
63     {
64       OCC_CATCH_SIGNALS
65       //aRes = Draw::GetInterpretor().Eval (theCommand.c_str());
66       aRes = Draw_Interprete (theCommand.c_str()) ? 1 : 0;
67     }
68     catch (Standard_Failure& anExcept)
69     {
70       std::cout << "Failed to evaluate command: " << anExcept.GetMessageString() << std::endl;
71     }
72     return aRes;
73   }
74
75   //! Check if Tcl command is complete.
76   static bool isComplete (const std::string& theCommand)
77   {
78     return Draw::GetInterpretor().Complete (theCommand.c_str());
79   }
80
81   //! Evaluate Tcl command asynchronously.
82   static void evalAsync (const std::string& theCommand)
83   {
84   #if defined(__EMSCRIPTEN_PTHREADS__)
85     std::string* aCmdPtr = new std::string (theCommand);
86     OSD_Thread aThread (&evalAsyncEntry);
87     aThread.Run (aCmdPtr);
88   #else
89     // fallback synchronous implementation
90     int aRes = eval (theCommand);
91     occJSEvalAsyncCompleted (aRes);
92   #endif
93   }
94
95 #if defined(__EMSCRIPTEN_PTHREADS__)
96 private:
97   //! Thread entry for async command execution.
98   static Standard_Address evalAsyncEntry (Standard_Address theData)
99   {
100     OSD::SetSignal (false);
101     std::string* aCmdPtr = (std::string* )theData;
102     const std::string aCmd = *aCmdPtr;
103     delete aCmdPtr;
104     int aRes = eval (aCmd);
105     emscripten_async_run_in_main_runtime_thread (EM_FUNC_SIG_VI, evalAsyncCompletedEntry, aRes);
106     return 0;
107   }
108
109   //! Notify Module.evalAsyncCompleted about async cmd completion.
110   static void evalAsyncCompletedEntry (int theResult)
111   {
112     occJSEvalAsyncCompleted (theResult);
113   }
114 #endif
115 };
116
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));
123   } else {
124     //console.info (UTF8ToString(theStr));
125   }
126 });
127
128 //! Auxiliary printer to a Module.printMessage callback accepting text and gravity.
129 class DRAWEXE_WasmModulePrinter : public Message_Printer
130 {
131   DEFINE_STANDARD_RTTI_INLINE(DRAWEXE_WasmModulePrinter, Message_Printer)
132 public:
133
134   //! Main constructor.
135   DRAWEXE_WasmModulePrinter (const Message_Gravity theTraceLevel = Message_Info)
136   {
137     SetTraceLevel (theTraceLevel);
138   }
139
140   //! Destructor.
141   virtual ~DRAWEXE_WasmModulePrinter() {}
142
143 protected:
144
145   //! Puts a message.
146   virtual void send (const TCollection_AsciiString& theString,
147                      const Message_Gravity theGravity) const Standard_OVERRIDE
148   {
149     if (theGravity >= myTraceLevel)
150     {
151       occJSPrintMessage (theString.ToCString(), (int )theGravity);
152     }
153   }
154 };
155
156 EMSCRIPTEN_BINDINGS(DRAWEXE) {
157   emscripten::function("eval",       &DRAWEXE::eval);
158   emscripten::function("evalAsync",  &DRAWEXE::evalAsync);
159   emscripten::function("isComplete", &DRAWEXE::isComplete);
160 }
161 #endif
162
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)
168 {
169   NCollection_IndexedMap<TCollection_AsciiString, TCollection_AsciiString> aPlugins;
170   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
171   {
172     TCollection_AsciiString anArg (theArgVec[anArgIter]);
173     anArg.UpperCase();
174     if (anArg == "DEFAULT")
175     {
176       aPlugins.Add ("TOPTEST");
177     }
178     else if (anArg == "MODELING")
179     {
180       aPlugins.Add ("TOPTEST");
181     }
182     else if (anArg == "VISUALIZATION")
183     {
184       aPlugins.Add ("AISV");
185     }
186     else if (anArg == "OCAFKERNEL")
187     {
188       aPlugins.Add ("DCAF");
189     }
190     else if (anArg == "DATAEXCHANGEKERNEL")
191     {
192       aPlugins.Add ("XSDRAW");
193     }
194     else if (anArg == "OCAF")
195     {
196       aPlugins.Add ("AISV");
197       aPlugins.Add ("DCAF");
198     }
199     else if (anArg == "DATAEXCHANGE")
200     {
201       aPlugins.Add ("XSDRAW");
202       aPlugins.Add ("XDEDRAW");
203       aPlugins.Add ("AISV");
204     }
205     else if (anArg == "XDE")
206     {
207       aPlugins.Add ("XSDRAW");
208       aPlugins.Add ("XDEDRAW");
209     }
210     else if (anArg == "ALL")
211     {
212       aPlugins.Add ("TOPTEST");
213       aPlugins.Add ("DCAF");
214       aPlugins.Add ("XSDRAW");
215       aPlugins.Add ("XDEDRAW");
216       aPlugins.Add ("AISV");
217     }
218     else
219     {
220       aPlugins.Add (anArg);
221     }
222   }
223
224   for (NCollection_IndexedMap<TCollection_AsciiString, TCollection_AsciiString>::Iterator aPluginIter (aPlugins);
225        aPluginIter.More(); aPluginIter.Next())
226   {
227     const TCollection_AsciiString& aPlugin = aPluginIter.Value();
228     if (aPlugin == "TOPTEST")
229     {
230       BOPTest::Factory (theDI);
231     }
232     else if (aPlugin == "DCAF")
233     {
234       DPrsStd::Factory (theDI);
235     }
236     else if (aPlugin == "AISV")
237     {
238       ViewerTest::Factory (theDI);
239     }
240   #if defined(HAVE_OPENGL)
241     else if (aPlugin == "GL"
242           || aPlugin == "OPENGL")
243     {
244       OpenGlTest::Factory (theDI);
245     }
246   #endif
247   #if defined(HAVE_GLES2)
248     else if (aPlugin == "GLES"
249           || aPlugin == "OPENGLES")
250     {
251       OpenGlTest::Factory (theDI);
252     }
253   #endif
254     else if (aPlugin == "XSDRAW")
255     {
256       XSDRAWSTLVRML::Factory (theDI);
257     }
258     else if (aPlugin == "XDEDRAW")
259     {
260       XDEDRAW::Factory (theDI);
261     }
262     //else if (aPlugin == "TOBJ")       { TObjDRAW::Factory (theDI); }
263     //else if (aPlugin == "QACOMMANDS") { QADraw::Factory (theDI); }
264     else
265     {
266       theDI << "Error: unknown plugin '" << aPlugin << "'";
267       return 1;
268     }
269   }
270
271   return 0;
272 }
273 #endif
274
275 //=======================================================================
276 //function : Draw_InitAppli
277 //purpose  : 
278 //=======================================================================
279
280 void Draw_InitAppli (Draw_Interpretor& theDI)
281 {
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);
291 #endif
292
293   Draw::Commands (theDI);
294   DBRep::BasicCommands (theDI);
295   DrawTrSurf::BasicCommands (theDI);
296
297 #ifdef OCCT_NO_PLUGINS
298   theDI.Add ("pload" , "pload [[Key1] [Key2] ...]: Loads Draw plugins",
299              __FILE__, Pload, "Draw Plugin");
300 #endif
301 }
302
303 #include <Draw_Main.hxx>
304 DRAW_MAIN