Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / gui / YACSGui_Observer.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_Observer.h"
21
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"
27
28 #include "SALOME_Event.hxx"
29
30 #include <Node.hxx>
31 #include <ForEachLoop.hxx>
32
33 #include <qapplication.h>
34
35 #include <string>
36 #include <list>
37 #include <cassert>
38 #include "utilities.h"
39
40 using namespace YACS::ENGINE;
41 using namespace std;
42
43 YACSEvent::YACSEvent(std::pair<int,std::string> aYACSEvent)
44   : QCustomEvent(YACS_EVENT), _event(aYACSEvent)
45 {
46 }
47
48
49 YACSGui_Observer::YACSGui_Observer(YACSGui_Graph* theGraph):
50   Observer(),
51   myGraph(theGraph)
52 {
53 }
54
55 void YACSGui_Observer::notifyObserver(YACS::ENGINE::Node* object, const std::string& event)
56 {
57   //MESSAGE("YACSGui_Observer::notifyObserver(YACS::ENGINE::Node* object, const std::string& event)");
58   if (event == "status")
59     {
60       if ( myGraph && !myGraph->getItem(object) )
61         {
62           if ( dynamic_cast<YACS::ENGINE::ForEachLoop*>( object->getFather() )
63                &&
64                myGraph->getItem(object->getFather()) )
65             {
66               // transmit event to ForEachLoop node
67               ProcessVoidEvent( new TVoidMemFunEvent<YACSPrs_ElementaryNode>( myGraph->getItem(object->getFather()), &YACSPrs_ElementaryNode::update ) );
68
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() )
71                 {
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,
77                                                                                                               object ) );
78                 }
79             }
80         }
81       else if ( myGraph && myGraph->getItem(object) )
82         {
83           if ( dynamic_cast<YACS::ENGINE::ForEachLoop*>( object )
84                &&
85                object->getState() == YACS::TOACTIVATE )
86             {
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);   
90             }
91           else
92             ProcessVoidEvent( new TVoidMemFunEvent<YACSPrs_ElementaryNode>( myGraph->getItem(object), &YACSPrs_ElementaryNode::update ) );
93         }
94     }
95 }
96
97 void YACSGui_Observer::notifyObserver(const int theID, const std::string& theEvent) 
98 {
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);
102   
103   // Call notifyObserver() for the node
104   if (aNode)
105     notifyObserver(aNode, theEvent);
106 }
107
108 void YACSGui_Observer::notifyObserver(const std::string& theName, const std::string& theEvent)
109 {
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);
113   
114   // Call notifyObserver() for the node
115   if (aNode)
116     notifyObserver(aNode, theEvent);
117 }
118
119 /*!
120  * set node state in local (GUI) graph. 
121  * setState emit a local event to the local dispatcher for gui events
122  */ 
123 void YACSGui_Observer::setNodeState(const int theID, const int theState)
124 {
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);
128   
129   // Set state
130   if (aNode)
131     aNode->setState(YACS::StatesForNode(theState));
132 }
133
134 /*!
135  * set node state in local (GUI) graph. 
136  * setState emit a local event to the local dispatcher for gui events
137  */ 
138 void YACSGui_Observer::setNodeState(const std::string& theName, const int theState)
139 {
140   //MESSAGE("YACSGui_Observer::setNodeState " << theName << " " << theState);
141   // Get node by its name
142   YACS::ENGINE::Node* aNode = 0; 
143   
144   if (theName != "proc")
145     aNode = myGraph->getNodeByName(theName);
146   else
147     aNode = myGraph->getProc();
148   
149   // Set state
150   if (aNode)
151     aNode->setState(YACS::StatesForNode(theState));
152 }
153
154
155
156
157 Observer_i::Observer_i(YACS::ENGINE::Proc* guiProc,
158                        YACSGui_Module* guiMod,
159                        YACSGui_Executor* guiExec)
160 {
161   //MESSAGE("Observer_i::Observer_i");
162   _guiProc = guiProc;
163   _guiMod = guiMod;
164   _guiExec = guiExec;
165   _engineProc = YACSGui_ORB::ProcExec::_nil();
166   myImpl = 0;
167 }
168
169 Observer_i::~Observer_i()
170 {
171 }
172
173 void Observer_i::setConversion()
174 {
175   //MESSAGE("Observer_i::setConversion");
176   assert(!CORBA::is_nil(_engineProc));
177   YACSGui_ORB::stringArray_var engineNames;
178   YACSGui_ORB::longArray_var engineIds;
179   //MESSAGE("---");
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++)
185     {
186       string aName = "";
187       aName = engineNames[i];
188       int iEng = engineIds[i];
189       //MESSAGE("--- " << aName << " " << iEng);
190       if (aName != "_root_")
191         {
192           int iGui = _guiProc->getChildByName(aName)->getNumId();
193           //MESSAGE("---");
194           _guiToEngineMap[iGui] = iEng;
195           _engineToGuiMap[iEng] = iGui;
196         }
197       else
198         {
199           int iGui = _guiProc->getNumId();
200           _guiToEngineMap[iGui] = iEng;
201           _engineToGuiMap[iEng] = iGui;
202         }
203     }
204 }
205
206 //! process YACS events in main thread (see postEvent)
207 bool Observer_i::event(QEvent *e)
208 {
209   //MESSAGE("Observer_i::event");
210   if (e->type() == YACS_EVENT)
211     {
212       YACSEvent *ye = (YACSEvent*)e;      
213       pair <int, string> myEvent = ye->getYACSEvent();
214       int numid = myEvent.first;
215       string event = myEvent.second;
216
217       if (event == "executor") // --- Executor notification: state
218         {
219           //MESSAGE("Observer_i::run executor");
220           int execState = _engineProc->getExecutorState();
221           YACSGui_RunMode* theRunMode = _guiMod->getRunMode(_guiExec);
222           if (theRunMode)
223             {
224               theRunMode->onNotifyStatus(execState);
225               list<string> nextSteps;
226               if ((execState == YACS::WAITINGTASKS) || (execState == YACS::PAUSED))
227                 {
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());
231                 }
232               theRunMode->onNotifyNextSteps(nextSteps);
233             }
234         }
235       else                     // --- Node notification
236         {
237           if (!myImpl)
238             return true;
239           if (_engineToGuiMap.count(numid) == 0)
240             return true;
241           int iGui = _engineToGuiMap[numid];
242           
243           if (YACS::ENGINE::Node::idMap.count(iGui) == 0)
244             return true;
245           YACS::ENGINE::Node* aNode= YACS::ENGINE::Node::idMap[iGui];
246           
247           string aName = _guiProc->getChildName(aNode);    
248           if (aName == "")
249             return true;
250           
251           if (event == "status") // --- Node notification: status
252             {
253               //MESSAGE("Observer_i::run status");
254               int aState = _engineProc->getNodeState(numid);
255               if (aState < 0)
256                 return true;
257               YACSGui_RunMode* theRunMode = _guiMod->getRunMode(_guiExec);
258               if (theRunMode)
259                 theRunMode->onNotifyNodeStatus(iGui, aState);
260               myImpl->setNodeState(aName, aState);
261             }
262         }
263       return true;
264     }
265   MESSAGE("--- Wrong event ---");
266   return false;
267 }
268
269 //! CORBA servant implementation
270 /*!
271  * post event for treatment by main thread and to avoid deadlocks
272  * in SALOME Engine with CORBA callbacks.
273  */
274 void Observer_i::notifyObserver(CORBA::Long numid, const char* event)
275 {
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
280 }
281
282 void Observer_i::SetImpl(YACSGui_Observer* theImpl)
283 {
284   //MESSAGE("Observer_i::SetImpl");
285   myImpl = theImpl;
286 }
287
288 void Observer_i::SetRemoteProc(YACSGui_ORB::ProcExec_ptr engineProc)
289 {
290   _engineProc = YACSGui_ORB::ProcExec::_duplicate(engineProc);
291 }