Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / gui / YACSGui_Executor.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <YACSGui_Executor.h>
21 #include <YACSGui_XMLDriver.h>
22 #include <YACSGui_Observer.h>
23 #include <YACSGui_Module.h>
24 #include <SUIT_MessageBox.h>
25 #include <SalomeApp_Application.h>
26 #include <Executor.hxx>
27 #include "utilities.h"
28
29 #include <Qtx.h>
30
31 #include <qdir.h>
32
33 using namespace YACS::ENGINE;
34 using namespace YACS;
35 using namespace std;
36
37 //! Constructor
38 /*!
39  */
40 YACSGui_Executor::YACSGui_Executor(YACSGui_Module* guiMod, Proc* theProc) :
41   QThread(),
42   _guiMod(guiMod),
43   _proc(theProc)
44 {
45   _localEngine = 0;
46   _engineRef = YACSGui_ORB::YACSGui_Gen::_nil();
47   _procRef = YACSGui_ORB::ProcExec::_nil();
48   _observerRef = YACSGui_ORB::Observer::_nil();
49   _serv = 0;
50   _isRunning = false;
51   _isSuspended = false;
52   _execMode = YACS::CONTINUE;
53 }
54
55 //! Destructor
56 /*!
57  */
58 YACSGui_Executor::~YACSGui_Executor()
59 {
60 }
61
62 //! local run in a QThread
63 /*! local run in a QThread Reimplemented from QThread class.
64  */
65 void YACSGui_Executor::run()
66 {
67   if (!_proc)
68     return;
69   int debug = 0; // for debug only
70   _localEngine->RunW(_proc, debug);
71   _isRunning = false;
72 }
73
74 //! Run dataflow.
75 /*! local run or remote (in a SALOME Container)
76  */
77 void YACSGui_Executor::runDataflow(const bool isRemoteRun)
78 {
79   MESSAGE("YACSGui_Executor::runDataflow");
80   _isRemoteRun = isRemoteRun;
81   if (!isRemoteRun)  // --- wanted local run
82     {
83       if (! _localEngine)
84         _localEngine = new Executor();
85       if (_isRunning)
86         if (! checkEndOfDataFlow()) return;
87       _isRunning = true;
88       _localEngine->setExecMode(YACS::CONTINUE); // --- control only on remote run
89       start();
90     }
91   else              // --- wanted run in a SALOME Container
92     {
93       if (CORBA::is_nil(_engineRef))
94         _engineRef = YACSGui_Module::InitYACSGuiGen(_guiMod->getApp());
95
96       if (_isRunning)
97         if (! checkEndOfDataFlow()) return;
98       _isRunning = true;
99       //Export the proc into temporary XML file
100       QString aFileName = Qtx::tmpDir() + QDir::QDir::separator() + "tmp_" + _proc->getName();
101       
102       if (CORBA::is_nil(_procRef))
103         {
104           MESSAGE("init _procRef");
105           VisitorSaveSchema aWriter( _proc );
106           aWriter.openFileSchema( aFileName );
107           aWriter.visitProc( _proc );
108           aWriter.closeFileSchema();
109           _procRef = _engineRef->LoadProc(aFileName.latin1());
110           registerStatusObservers();
111           MESSAGE("_procRef _init");
112         }
113       _procRef->setExecMode(getCurrentExecMode());
114       _setBPList();
115       _procRef->Run();
116     }
117 }
118
119 //! test if a dataflow is running
120 /*!
121  * return true if no running dataflow (TODO: check save state ? delete procexec servant ?)
122  */
123 bool YACSGui_Executor::checkEndOfDataFlow(bool display)
124 {
125   if (_isRunning)
126     {
127       if(running()) // --- local run not finished
128         {
129           if (display)
130             SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), 
131                                     tr("ERROR"), 
132                                     tr("Local Execution Already running..."), 
133                                     tr("BUT_OK"));
134           return false;
135         }
136       if (CORBA::is_nil(_procRef))
137         {
138           if (display)
139             SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), 
140                                     tr("ERROR"), 
141                                     tr("Runtime error: connection lost on a running scheme"), 
142                                     tr("BUT_OK"));
143           _isRunning = false;
144           return false;              
145         }
146       if (_procRef->isNotFinished())
147         {
148           if (display)
149             SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), 
150                                     tr("ERROR"), 
151                                     tr("Remote Execution Already running..."), 
152                                     tr("BUT_OK"));
153           return false;
154         }
155       else
156         {
157           _isRunning = false;
158           // --- TODO: delete procExec on server ...
159         }
160     }
161   return true;
162 }
163
164 //! Kill dataflow.
165 /*!
166  */
167 void YACSGui_Executor::killDataflow()
168 {
169   MESSAGE("YACSGui_Executor::killDataflow");
170   //terminate(); // not safe!
171   if (running())        // --- local run
172     {
173       _localEngine->stopExecution();
174     }
175   else if (_isRunning)  // --- remote run
176     {
177       _procRef->stopExecution();
178     }
179 }
180
181
182 //! Suspend/Resume dataflow.
183 /*!
184  */
185 void YACSGui_Executor::suspendResumeDataflow()
186 {
187   MESSAGE("YACSGui_Executor::suspendResumeDataflow");
188   if (running())        // --- local run
189     {
190       if (_isSuspended)
191         {
192           _localEngine->setExecMode(_execMode);
193           _localEngine->resumeCurrentBreakPoint();
194         }
195       else
196         _localEngine->setExecMode(YACS::STEPBYSTEP);
197     }
198   else if (_isRunning)  // --- remote run
199     {
200       if (_isSuspended)
201         {
202           _procRef->setExecMode(getCurrentExecMode());
203           _procRef->resumeCurrentBreakPoint();
204         }
205       else
206         _procRef->setExecMode(YACSGui_ORB::STEPBYSTEP);
207     }
208   _isSuspended = !_isSuspended;
209 }
210
211 void YACSGui_Executor::suspendDataflow()
212 {
213   MESSAGE("YACSGui_Executor::suspendDataflow");
214   if (running())        // --- local run
215     {
216       _localEngine->setExecMode(YACS::STEPBYSTEP);
217     }
218   else if (_isRunning)  // --- remote run
219     {
220       _procRef->setExecMode(YACSGui_ORB::STEPBYSTEP);
221     }
222 }
223
224 void YACSGui_Executor::resumeDataflow()
225 {
226   MESSAGE("YACSGui_Executor::ResumeDataflow");
227   if (running())        // --- local run
228     {
229       _localEngine->setExecMode(_execMode);
230       _localEngine->resumeCurrentBreakPoint();
231     }
232   else if (_isRunning)  // --- remote run
233     {
234       _procRef->setExecMode(getCurrentExecMode());
235       _procRef->resumeCurrentBreakPoint();
236     }
237 }
238
239 void YACSGui_Executor::stopDataflow()
240 {
241   MESSAGE("YACSGui_Executor::stopDataflow");
242   if (running())        // --- local run
243     {
244       _localEngine->stopExecution();
245     }
246   else if (_isRunning)  // --- remote run
247     {
248       _procRef->stopExecution();
249     }
250
251 }
252
253 void YACSGui_Executor::setStepByStepMode()
254 {
255   MESSAGE("YACSGui_Executor::setStepByStepMode");
256   _execMode = YACS::STEPBYSTEP;
257   if (running())        // --- local run
258     {
259       _localEngine->setExecMode(YACS::STEPBYSTEP);
260     }
261   else if (_isRunning)  // --- remote run
262     {
263       _procRef->setExecMode(YACSGui_ORB::STEPBYSTEP);
264     }
265 }
266
267 void YACSGui_Executor::setContinueMode()
268 {
269   MESSAGE("YACSGui_Executor::setContinueMode");
270   _execMode = YACS::CONTINUE;
271   if (running())        // --- local run
272     {
273       _localEngine->setExecMode(YACS::CONTINUE);
274     }
275   else if (_isRunning)  // --- remote run
276     {
277       _procRef->setExecMode(YACSGui_ORB::CONTINUE);
278     }
279 }
280
281 void YACSGui_Executor::setBreakpointMode()
282 {
283   MESSAGE("YACSGui_Executor::setBreakpointMode");
284   _execMode = YACS::STOPBEFORENODES;
285   if (running())        // --- local run
286     {
287       _localEngine->setExecMode(YACS::STOPBEFORENODES);
288     }
289   else if (_isRunning)  // --- remote run
290     {
291       _procRef->setExecMode(YACSGui_ORB::STOPBEFORENODES);
292     }
293 }
294
295 void YACSGui_Executor::setStopOnError(bool aMode)
296 {
297   MESSAGE("YACSGui_Executor::setStopOnError");
298   if (running())        // --- local run
299     {
300       _localEngine->setStopOnError(aMode, "/tmp/dumpStateOnError.xml");
301     }
302   else if (_isRunning)  // --- remote run
303     {
304       _procRef->setStopOnError(aMode, "/tmp/dumpStateOnError.xml");
305     }
306 }
307
308 void YACSGui_Executor::setNextStepList(std::list<std::string> nextStepList)
309 {
310   MESSAGE("YACSGui_Executor::setNextStepList");
311   if (running())        // --- local run
312     {
313       _localEngine->setStepsToExecute(nextStepList);
314     }
315   else if (_isRunning)  // --- remote run
316     {
317       YACSGui_ORB::stringArray listOfNextStep;
318       listOfNextStep.length(nextStepList.size());
319       int i=0;
320       for (list<string>::iterator it = nextStepList.begin(); it != nextStepList.end(); ++it)
321         listOfNextStep[i++] = (*it).c_str();
322       _procRef->setStepsToExecute(listOfNextStep);
323     }
324 }
325
326 void YACSGui_Executor::setBreakpointList(std::list<std::string> breakpointList)
327 {
328   MESSAGE("YACSGui_Executor::setBreakpointList");
329   _breakpointList.clear();
330   _breakpointList = breakpointList;
331   _setBPList();
332 }
333
334 //! list must be sent, even empty (only way to remove all breakpoints)
335 void YACSGui_Executor::_setBPList()
336 {
337   if (running())        // --- local run
338     {
339       _localEngine->setListOfBreakPoints(_breakpointList);
340     }
341   else if (_isRunning)  // --- remote run
342     {
343       YACSGui_ORB::stringArray listOfBreakPoints;
344       listOfBreakPoints.length(_breakpointList.size());
345       int i=0;
346       for (list<string>::iterator it = _breakpointList.begin(); it != _breakpointList.end(); ++it)
347         listOfBreakPoints[i++] = (*it).c_str();
348       _procRef->setListOfBreakPoints(listOfBreakPoints);
349     }
350 }
351
352 void YACSGui_Executor::registerStatusObservers()
353 {
354   MESSAGE("YACSGui_Executor::registerStatusObservers");
355   if (CORBA::is_nil(_procRef))
356     {
357       SUIT_MessageBox::error1(_guiMod->getApp()->desktop(), 
358                               tr("ERROR"), 
359                               tr("Runtime error (yacsgui): Lost connection on YACS executor"), 
360                               tr("BUT_OK"));
361       return;
362     }
363   if (CORBA::is_nil(_observerRef))
364     {
365       _serv = new Observer_i(_proc, _guiMod, this);
366       _observerRef = _serv->_this();
367       _serv->SetImpl(_graph->getStatusObserver());
368     }
369   MESSAGE("---");
370   _serv->SetRemoteProc(_procRef);
371   _serv->setConversion();
372   MESSAGE("---");
373   std::set<Node*> aNodeSet = _proc->getAllRecursiveConstituents();
374   for ( std::set<Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ )
375     {
376       _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "status");
377     }
378   _procRef->addObserver(_observerRef, _serv->getEngineId(_proc->getNumId()) , "executor"); 
379 }
380
381 YACSGui_ORB::executionMode YACSGui_Executor::getCurrentExecMode()
382 {
383   switch (_execMode)
384     {
385     case YACS::CONTINUE: return YACSGui_ORB::CONTINUE;
386     case YACS::STEPBYSTEP: return YACSGui_ORB::STEPBYSTEP;
387     case YACS::STOPBEFORENODES: return YACSGui_ORB::STOPBEFORENODES;
388     default: return YACSGui_ORB::CONTINUE;
389     }
390 }