1 // Copyright (C) 2006-2024 CEA, EDF
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, or (at your option) any later version.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "SALOME_LifeCycleCORBA.hxx"
22 #include "SALOME_NamingService_Wrapper.hxx"
23 #include "SALOME_Launcher.hxx"
25 #include "GuiExecutor.hxx"
26 #include "GuiObserver_i.hxx"
27 #include "QtGuiContext.hxx"
29 #include "RuntimeSALOME.hxx"
33 #include "InputPort.hxx"
34 #include "OutputPort.hxx"
35 #include "Executor.hxx"
37 #include "KernelBasis.hxx"
40 #include "YacsTrace.hxx"
43 using namespace YACS::HMI;
44 using namespace YACS::ENGINE;
46 GuiExecutor::GuiExecutor(YACS::ENGINE::Proc* proc)
48 DEBTRACE("GuiExecutor::GuiExecutor");
51 _context = QtGuiContext::getQtCurrent();
53 _engineRef = YACS_ORB::YACS_Gen::_nil();
54 _procRef = YACS_ORB::ProcExec::_nil();
55 _observerRef = YACS_ORB::Observer::_nil();
57 _execMode = YACS::CONTINUE;
62 _isStopOnError = false;
66 _breakpointList.clear();
69 KERNEL::getLauncherSA();
74 GuiExecutor::~GuiExecutor()
76 DEBTRACE("GuiExecutor::~GuiExecutor");
79 void GuiExecutor::closeContext()
81 DEBTRACE("GuiExecutor::closeContext");
85 void GuiExecutor::startResumeDataflow(bool initialize)
87 DEBTRACE("GuiExecutor::runDataflow " << initialize);
90 DEBTRACE("context closed");
93 if (CORBA::is_nil(_engineRef))
95 DEBTRACE("Create YACS ORB engine!");
96 YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
97 CORBA::ORB_ptr orb = runTime->getOrb();
98 SALOME_NamingService_Wrapper namingService(orb);
99 //int iii(0); std::cin >> iii;
101 SALOME_LifeCycleCORBA lcc(&namingService);
102 ostringstream containerName;
103 containerName << "localhost/YACSContainer";
104 Engines::EngineComponent_var comp = lcc.FindOrLoad_Component(containerName.str().c_str(), "YACS" );
105 _engineRef =YACS_ORB::YACS_Gen::_narrow(comp);
106 YASSERT(!CORBA::is_nil(_engineRef));
110 checkEndOfDataflow(); // --- to allow change of the _isRunning state
116 _procRef->setExecMode(getCurrentExecMode());
117 _procRef->resumeCurrentBreakPoint();
118 _isSuspended = false;
125 if (CORBA::is_nil(_procRef))
127 DEBTRACE("init _procRef");
128 _procRef = _engineRef->LoadProc(_context->getFileName().toUtf8());
129 registerStatusObservers();
130 DEBTRACE("_procRef init");
133 YASSERT(!CORBA::is_nil(_procRef));
136 _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
138 _procRef->setExecMode(getCurrentExecMode());
141 if (_loadStateFile.empty())
143 DEBTRACE("Run from scratch!");
148 DEBTRACE("Run from STATE!");
151 _procRef->RunFromState(_loadStateFile.c_str());
155 DEBTRACE("Runtime error: execution from the loaded state failed")
161 bool GuiExecutor::checkEndOfDataflow(bool display)
163 DEBTRACE("GuiExecutor::checkEndOfDataFlow");
166 if (CORBA::is_nil(_procRef))
168 DEBTRACE("Runtime error: connection lost on a running scheme");
172 if (_procRef->isNotFinished())
174 DEBTRACE("Remote Execution Already running...");
180 // --- TODO: cleaning on server ...
186 void GuiExecutor::killDataflow()
188 DEBTRACE("GuiExecutor::killDataflow");
190 _procRef->stopExecution();
193 void GuiExecutor::suspendDataflow()
195 DEBTRACE("GuiExecutor::suspendDataflow");
197 _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
200 void GuiExecutor::resumeDataflow()
202 DEBTRACE("GuiExecutor::resumeDataflow");
205 _procRef->setExecMode(getCurrentExecMode());
206 _procRef->resumeCurrentBreakPoint();
210 void GuiExecutor::stopDataflow()
212 DEBTRACE("GuiExecutor::stopDataflow");
214 _procRef->stopExecution();
217 void GuiExecutor::resetDataflow()
219 DEBTRACE("GuiExecutor::resetDataflow");
221 checkEndOfDataflow();
223 _procRef->stopExecution();
224 checkEndOfDataflow();
229 _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
230 //full reset: set all nodes in error to READY state and start execution
231 _procRef->RestartFromState("");
236 void GuiExecutor::setStepByStepMode()
238 DEBTRACE("GuiExecutor::setStepByStepMode");
239 _execMode = YACS::STEPBYSTEP;
241 _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
244 void GuiExecutor::setContinueMode()
246 DEBTRACE("GuiExecutor::setContinueMode");
247 _execMode = YACS::CONTINUE;
249 _procRef->setExecMode(YACS_ORB::CONTINUE);
252 void GuiExecutor::setBreakpointMode()
254 DEBTRACE("GuiExecutor::setBreakpointMode");
255 _execMode = YACS::STOPBEFORENODES;
257 _procRef->setExecMode(YACS_ORB::STOPBEFORENODES);
260 void GuiExecutor::setStopOnError(bool aMode)
262 DEBTRACE("GuiExecutor::setStopOnError " << aMode);
266 _procRef->setStopOnError(aMode, (getenv("TEMP") + string("\\dumpStateOnError_") + getenv("USER") + string(".xml")).c_str());
268 _procRef->setStopOnError(aMode, (string("/tmp/dumpStateOnError_") + getenv("USER") + string(".xml")).c_str());
270 _isStopOnError = true;
274 void GuiExecutor::unsetStopOnError()
276 DEBTRACE("GuiExecutor::unsetStopOnError");
279 _procRef->unsetStopOnError();
280 _isStopOnError = false;
285 void GuiExecutor::saveState(const std::string& xmlFile)
287 DEBTRACE("GuiExecutor::saveState " << xmlFile);
288 bool StartFinish = (getExecutorState() == YACS::NOTYETINITIALIZED ||
289 getExecutorState() == YACS::FINISHED);
291 !(CORBA::is_nil(_procRef)) && StartFinish ) {
292 if ( !_procRef->saveState(xmlFile.c_str()) ) {
293 string what = "Impossible to open file for writing: " + xmlFile;
294 throw Exception(what);
299 void GuiExecutor::setLoadStateFile(std::string xmlFile)
301 DEBTRACE("GuiExecutor::setLoadStateFile " << xmlFile);
302 _loadStateFile = xmlFile;
306 YACS_ORB::executionMode GuiExecutor::getCurrentExecMode()
308 DEBTRACE("GuiExecutor::getCurrentExecMode");
311 case YACS::CONTINUE: return YACS_ORB::CONTINUE;
312 case YACS::STEPBYSTEP: return YACS_ORB::STEPBYSTEP;
313 case YACS::STOPBEFORENODES: return YACS_ORB::STOPBEFORENODES;
314 default: return YACS_ORB::CONTINUE;
318 int GuiExecutor::getExecutorState()
320 DEBTRACE("GuiExecutor::getExecutorState");
321 if (_isRunning || !CORBA::is_nil(_procRef))
322 return _procRef->getExecutorState();
323 else if (CORBA::is_nil(_procRef))
324 return YACS::NOTYETINITIALIZED;
326 return YACS::FINISHED;
330 void GuiExecutor::setBreakpointList(std::list<std::string> breakpointList)
332 DEBTRACE("GuiExecutor::setBreakpointList");
335 DEBTRACE("context closed");
338 _breakpointList.clear();
339 _breakpointList = breakpointList;
341 if ((_execMode == YACS::CONTINUE) && ! _breakpointList.empty())
343 _context->getGMain()->_breakpointsModeAct->setChecked(true);
348 void GuiExecutor::addBreakpoint(std::string breakpoint)
350 DEBTRACE("addBreakpoint " << breakpoint);
353 DEBTRACE("context closed");
356 _breakpointList.push_back(breakpoint);
358 if ((_execMode == YACS::CONTINUE) && ! _breakpointList.empty())
360 _context->getGMain()->_breakpointsModeAct->setChecked(true);
365 void GuiExecutor::removeBreakpoint(std::string breakpoint)
367 DEBTRACE("removeBreakpoint " << breakpoint);
368 _breakpointList.remove(breakpoint);
372 void GuiExecutor::setNextStepList(std::list<std::string> nextStepList)
374 DEBTRACE("GuiExecutor::setNextStepList");
377 YACS_ORB::stringArray listOfNextStep;
378 listOfNextStep.length(nextStepList.size());
380 for (list<string>::iterator it = nextStepList.begin(); it != nextStepList.end(); ++it)
381 listOfNextStep[i++] = (*it).c_str();
382 _procRef->setStepsToExecute(listOfNextStep);
386 void GuiExecutor::registerStatusObservers()
388 DEBTRACE("GuiExecutor::registerStatusObservers");
389 if (CORBA::is_nil(_procRef))
391 DEBTRACE("Runtime error (yacsgui): Lost connection on YACS executor");
394 if (CORBA::is_nil(_observerRef))
396 _serv = new GuiObserver_i(_proc);
397 _serv->SetImpl(this);
398 _observerRef = _serv->_this();
401 _serv->SetRemoteProc(_procRef);
402 _serv->setConversion();
404 std::list<Node*> aNodeSet = _proc->getAllRecursiveConstituents();
405 for ( std::list<Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ )
407 _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "status");
408 _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "progress");
410 _procRef->addObserver(_observerRef, _serv->getEngineId(_proc->getNumId()) , "executor");
415 void GuiExecutor::setEngineRef(YACS_ORB::YACS_Gen_ptr ref)
417 DEBTRACE("GuiExecutor::setEngineRef");
421 std::string GuiExecutor::getErrorDetails(YACS::ENGINE::Node* node)
423 DEBTRACE("GuiExecutor::getErrorDetails");
426 int engineId=_serv->getEngineId(node->getNumId());
427 return _procRef->getErrorDetails(engineId);
432 std::string GuiExecutor::getErrorReport(YACS::ENGINE::Node* node)
434 DEBTRACE("GuiExecutor::getErrorReport");
437 int engineId=_serv->getEngineId(node->getNumId());
438 return _procRef->getErrorReport(engineId);
443 std::string GuiExecutor::getContainerLog()
445 DEBTRACE("GuiExecutor::getContainerLog");
447 if (!CORBA::is_nil(_engineRef))
449 Engines::Container_var cont= _engineRef->GetContainerRef();
450 CORBA::String_var logname = cont->logfilename();
453 std::string::size_type pos = msg.find(":");
454 msg=msg.substr(pos+1);
459 std::string GuiExecutor::getContainerLog(YACS::ENGINE::Node* node)
461 DEBTRACE("GuiExecutor::getContainerLog(YACS::ENGINE::Node* node)");
465 int engineId=_serv->getEngineId(node->getNumId());
466 CORBA::String_var logname = _procRef->getContainerLog(engineId);
468 std::string::size_type pos = msg.find(":");
469 msg=msg.substr(pos+1);
474 void GuiExecutor::shutdownProc()
476 DEBTRACE("GuiExecutor::shutdownProc " << _shutdownLevel << "," << _isRunning);
477 checkEndOfDataflow();
479 _procRef->shutdownProc(_shutdownLevel);
482 void GuiExecutor::setInPortValue(YACS::ENGINE::DataPort* port, std::string value)
484 DEBTRACE("GuiExecutor::setInPortValue");
486 YACS::ENGINE::Node* node = port->getNode();
487 YACS::ENGINE::ComposedNode* rootNode = node->getRootNode();
489 std::string nodeName;
491 nodeName = node->getName();
493 nodeName = rootNode->getChildName(node);
495 std::string msg = _procRef->setInPortValue(nodeName.c_str(), port->getName().c_str(), value.c_str());
498 bool GuiExecutor::event(QEvent *e)
500 DEBTRACE("GuiExecutor::event");
501 YACSEvent *yev = dynamic_cast<YACSEvent*>(e);
502 if (!yev) return false;
503 int numid = yev->getYACSEvent().first;
504 string event = yev->getYACSEvent().second;
505 DEBTRACE("<" << numid << "," << event << ">");
508 DEBTRACE("context closed");
511 if (event == "executor") // --- Executor notification: state
513 int execState = _procRef->getExecutorState();
514 list<string> nextSteps;
515 if ((execState == YACS::WAITINGTASKS) || (execState == YACS::PAUSED))
517 YACS_ORB::stringArray_var nstp = _procRef->getTasksToLoad();
518 for (CORBA::ULong i=0; i<nstp->length(); i++)
519 nextSteps.push_back(nstp[i].in());
520 if (execState == YACS::PAUSED)
523 SubjectProc *sproc = _context->getSubjectProc();
524 sproc->update(YACS::HMI::UPDATEPROGRESS, execState, sproc);
526 else // --- Node notification
528 if (! _serv->_engineToGuiMap.count(numid))
530 int state = _procRef->getNodeState(numid);
531 int iGui = _serv->_engineToGuiMap[numid];
532 YASSERT(_context->_mapOfExecSubjectNode.count(iGui));
533 SubjectNode *snode = _context->_mapOfExecSubjectNode[iGui];
534 DEBTRACE("node " << snode->getName() << " state=" << state);
536 if (event == "progress") { // --- Update progress bar
537 std::string progress = _procRef->getNodeProgress(numid);
538 snode->setProgress( progress );
539 snode->update(YACS::HMI::PROGRESS, state, snode);
541 else { // --- Update node ports
542 YACS::ENGINE::Node *node = snode->getNode();
543 list<InputPort*> inports = node->getLocalInputPorts();
544 list<InputPort*>::iterator iti = inports.begin();
545 for ( ; iti != inports.end(); ++iti)
547 string val = _procRef->getInPortValue(numid, (*iti)->getName().c_str());
548 DEBTRACE("node " << snode->getName() << " inport " << (*iti)->getName()
549 << " value " << val);
550 YASSERT(_context->_mapOfSubjectDataPort.count(*iti));
551 SubjectDataPort* port = _context->_mapOfSubjectDataPort[*iti];
552 port->setExecValue(val);
553 port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
555 list<OutputPort*> outports = node->getLocalOutputPorts();
556 list<OutputPort*>::iterator ito = outports.begin();
557 for ( ; ito != outports.end(); ++ito)
559 string val = _procRef->getOutPortValue(numid, (*ito)->getName().c_str());
560 DEBTRACE("node " << snode->getName() << " outport " << (*ito)->getName()
561 << " value " << val);
562 YASSERT(_context->_mapOfSubjectDataPort.count(*ito));
563 SubjectDataPort* port = _context->_mapOfSubjectDataPort[*ito];
564 port->setExecValue(val);
565 port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
567 snode->update(YACS::HMI::UPDATEPROGRESS, state, snode);
574 void GuiExecutor::setBPList()
576 DEBTRACE("GuiExecutor::setBPList");
579 YACS_ORB::stringArray listOfBreakPoints;
580 listOfBreakPoints.length(_breakpointList.size());
582 for (list<string>::iterator it = _breakpointList.begin(); it != _breakpointList.end(); ++it)
583 listOfBreakPoints[i++] = (*it).c_str();
584 _procRef->setListOfBreakPoints(listOfBreakPoints);
588 YACS::ExecutorState GuiExecutor::updateSchema(string jobState)
590 YACS::ExecutorState execState = YACS::NOTYETINITIALIZED;
594 std::list<Node*> aNodeSet = _proc->getAllRecursiveConstituents();
595 for ( std::list<Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ){
597 numid = (*it)->getNumId();
599 state = _proc->getNodeState(numid);
600 SubjectNode *snode = _context->_mapOfExecSubjectNode[numid];
602 YACS::ENGINE::Node *node = snode->getNode();
603 list<InputPort*> inports = node->getLocalInputPorts();
604 list<InputPort*>::iterator iti = inports.begin();
605 for ( ; iti != inports.end(); ++iti)
607 string val = _proc->getInPortValue(numid, (*iti)->getName().c_str());
608 YASSERT(_context->_mapOfSubjectDataPort.count(*iti));
609 SubjectDataPort* port = _context->_mapOfSubjectDataPort[*iti];
610 port->setExecValue(val);
611 port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
613 list<OutputPort*> outports = node->getLocalOutputPorts();
614 list<OutputPort*>::iterator ito = outports.begin();
615 for ( ; ito != outports.end(); ++ito)
617 string val = _proc->getOutPortValue(numid, (*ito)->getName().c_str());
618 YASSERT(_context->_mapOfSubjectDataPort.count(*ito));
619 SubjectDataPort* port = _context->_mapOfSubjectDataPort[*ito];
620 port->setExecValue(val);
621 port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
623 snode->update(YACS::HMI::UPDATEPROGRESS, state, snode);
625 state = _proc->getRootNode()->getEffectiveState();
628 case YACS::ACTIVATED:
629 if(jobState!="RUNNING")
630 execState = YACS::FINISHED;
632 execState = YACS::RUNNING;
636 execState = YACS::FINISHED;
638 case YACS::SUSPENDED:
639 execState = YACS::PAUSED;
642 SubjectProc *sproc = _context->getSubjectProc();
643 sproc->update(YACS::HMI::UPDATEPROGRESS, execState, sproc);