1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
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.
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
20 #include "YACSGui_Observer.h"
22 #include "YACSGui_Graph.h"
23 #include "YACSGui_Module.h"
24 #include "YACSGui_Executor.h"
25 #include "YACSPrs_ElementaryNode.h"
26 #include "YACSGui_RunMode.h"
28 #include "SALOME_Event.hxx"
31 #include <ForEachLoop.hxx>
33 #include <qapplication.h>
38 #include "utilities.h"
40 using namespace YACS::ENGINE;
43 YACSEvent::YACSEvent(std::pair<int,std::string> aYACSEvent)
44 : QCustomEvent(YACS_EVENT), _event(aYACSEvent)
49 YACSGui_Observer::YACSGui_Observer(YACSGui_Graph* theGraph):
55 void YACSGui_Observer::notifyObserver(YACS::ENGINE::Node* object, const std::string& event)
57 //MESSAGE("YACSGui_Observer::notifyObserver(YACS::ENGINE::Node* object, const std::string& event)");
58 if (event == "status")
60 if ( myGraph && !myGraph->getItem(object) )
62 if ( dynamic_cast<YACS::ENGINE::ForEachLoop*>( object->getFather() )
64 myGraph->getItem(object->getFather()) )
66 // transmit event to ForEachLoop node
67 ProcessVoidEvent( new TVoidMemFunEvent<YACSPrs_ElementaryNode>( myGraph->getItem(object->getFather()), &YACSPrs_ElementaryNode::update ) );
69 // transmit event from the last clone node to original loop body node
70 if ( object == (dynamic_cast<YACS::ENGINE::ForEachLoop*>( object->getFather() ))->getNodes().back() )
72 std::set<Node *> aChildren = dynamic_cast<YACS::ENGINE::ForEachLoop*>( object->getFather() )->edGetDirectDescendants();
73 for(std::set<Node *>::iterator iter=aChildren.begin();iter!=aChildren.end();iter++)
74 if ( myGraph->getItem(*iter) )
75 ProcessVoidEvent( new TVoidMemFun1ArgEvent<YACSPrs_ElementaryNode,YACS::ENGINE::Node*>( myGraph->getItem(*iter),
76 &YACSPrs_ElementaryNode::updateForEachLoopBody,
81 else if ( myGraph && myGraph->getItem(object) )
83 if ( dynamic_cast<YACS::ENGINE::ForEachLoop*>( object )
85 object->getState() == YACS::TOACTIVATE )
87 std::vector<Node *> aCloneNodes = dynamic_cast<YACS::ENGINE::ForEachLoop*>(object)->getNodes();
88 for(std::vector<Node *>::iterator iter=aCloneNodes.begin();iter!=aCloneNodes.end();iter++)
89 myGraph->registerStatusObserverWithNode(*iter);
92 ProcessVoidEvent( new TVoidMemFunEvent<YACSPrs_ElementaryNode>( myGraph->getItem(object), &YACSPrs_ElementaryNode::update ) );
97 void YACSGui_Observer::notifyObserver(const int theID, const std::string& theEvent)
99 //MESSAGE("YACSGui_Observer::notifyObserver(const int theID, const std::string& theEvent)");
100 // Get node by its id
101 YACS::ENGINE::Node* aNode = myGraph->getNodeById(theID);
103 // Call notifyObserver() for the node
105 notifyObserver(aNode, theEvent);
108 void YACSGui_Observer::notifyObserver(const std::string& theName, const std::string& theEvent)
110 //MESSAGE("YACSGui_Observer::notifyObserver(const std::string& theName, const std::string& theEvent)");
111 // Get node by its name
112 YACS::ENGINE::Node* aNode = myGraph->getNodeByName(theName);
114 // Call notifyObserver() for the node
116 notifyObserver(aNode, theEvent);
120 * set node state in local (GUI) graph.
121 * setState emit a local event to the local dispatcher for gui events
123 void YACSGui_Observer::setNodeState(const int theID, const int theState)
125 //MESSAGE("YACSGui_Observer::setNodeState(const int theID, const int theState)");
126 // Get node by its id
127 YACS::ENGINE::Node* aNode = myGraph->getNodeById(theID);
131 aNode->setState(YACS::StatesForNode(theState));
135 * set node state in local (GUI) graph.
136 * setState emit a local event to the local dispatcher for gui events
138 void YACSGui_Observer::setNodeState(const std::string& theName, const int theState)
140 //MESSAGE("YACSGui_Observer::setNodeState " << theName << " " << theState);
141 // Get node by its name
142 YACS::ENGINE::Node* aNode = 0;
144 if (theName != "proc")
145 aNode = myGraph->getNodeByName(theName);
147 aNode = myGraph->getProc();
151 aNode->setState(YACS::StatesForNode(theState));
157 Observer_i::Observer_i(YACS::ENGINE::Proc* guiProc,
158 YACSGui_Module* guiMod,
159 YACSGui_Executor* guiExec)
161 //MESSAGE("Observer_i::Observer_i");
165 _engineProc = YACSGui_ORB::ProcExec::_nil();
169 Observer_i::~Observer_i()
173 void Observer_i::setConversion()
175 //MESSAGE("Observer_i::setConversion");
176 assert(!CORBA::is_nil(_engineProc));
177 YACSGui_ORB::stringArray_var engineNames;
178 YACSGui_ORB::longArray_var engineIds;
180 _engineProc->getIds(engineIds.out(), engineNames.out());
181 int iLength = engineIds->length();
182 int nLength = engineNames->length();
183 if (nLength < iLength) iLength = nLength;
184 for(int i=0; i<iLength; i++)
187 aName = engineNames[i];
188 int iEng = engineIds[i];
189 //MESSAGE("--- " << aName << " " << iEng);
190 if (aName != "_root_")
192 int iGui = _guiProc->getChildByName(aName)->getNumId();
194 _guiToEngineMap[iGui] = iEng;
195 _engineToGuiMap[iEng] = iGui;
199 int iGui = _guiProc->getNumId();
200 _guiToEngineMap[iGui] = iEng;
201 _engineToGuiMap[iEng] = iGui;
206 //! process YACS events in main thread (see postEvent)
207 bool Observer_i::event(QEvent *e)
209 //MESSAGE("Observer_i::event");
210 if (e->type() == YACS_EVENT)
212 YACSEvent *ye = (YACSEvent*)e;
213 pair <int, string> myEvent = ye->getYACSEvent();
214 int numid = myEvent.first;
215 string event = myEvent.second;
217 if (event == "executor") // --- Executor notification: state
219 //MESSAGE("Observer_i::run executor");
220 int execState = _engineProc->getExecutorState();
221 YACSGui_RunMode* theRunMode = _guiMod->getRunMode(_guiExec);
224 theRunMode->onNotifyStatus(execState);
225 list<string> nextSteps;
226 if ((execState == YACS::WAITINGTASKS) || (execState == YACS::PAUSED))
228 YACSGui_ORB::stringArray_var nstp = _engineProc->getTasksToLoad();
229 for (CORBA::ULong i=0; i<nstp->length(); i++)
230 nextSteps.push_back(nstp[i].in());
232 theRunMode->onNotifyNextSteps(nextSteps);
235 else // --- Node notification
239 if (_engineToGuiMap.count(numid) == 0)
241 int iGui = _engineToGuiMap[numid];
243 if (YACS::ENGINE::Node::idMap.count(iGui) == 0)
245 YACS::ENGINE::Node* aNode= YACS::ENGINE::Node::idMap[iGui];
247 string aName = _guiProc->getChildName(aNode);
251 if (event == "status") // --- Node notification: status
253 //MESSAGE("Observer_i::run status");
254 int aState = _engineProc->getNodeState(numid);
257 YACSGui_RunMode* theRunMode = _guiMod->getRunMode(_guiExec);
259 theRunMode->onNotifyNodeStatus(iGui, aState);
260 myImpl->setNodeState(aName, aState);
265 MESSAGE("--- Wrong event ---");
269 //! CORBA servant implementation
271 * post event for treatment by main thread and to avoid deadlocks
272 * in SALOME Engine with CORBA callbacks.
274 void Observer_i::notifyObserver(CORBA::Long numid, const char* event)
276 //MESSAGE("Observer_i::notifyObserver " << numid << " " << event );
277 pair<int,string> myEvent(numid, event);
278 YACSEvent* evt = new YACSEvent(myEvent);
279 QApplication::postEvent(this, evt); // Qt will delete it when done
282 void Observer_i::SetImpl(YACSGui_Observer* theImpl)
284 //MESSAGE("Observer_i::SetImpl");
288 void Observer_i::SetRemoteProc(YACSGui_ORB::ProcExec_ptr engineProc)
290 _engineProc = YACSGui_ORB::ProcExec::_duplicate(engineProc);