1 #ifndef _BLOCPARSER_HXX_
2 #define _BLOCPARSER_HXX_
4 #include "parserBase.hxx"
5 #include "linkParsers.hxx"
6 #include "xmlrpcParsers.hxx"
7 #include "nodeParsers.hxx"
12 #include "Runtime.hxx"
13 #include "ForLoop.hxx"
14 #include "ForEachLoop.hxx"
15 #include "WhileLoop.hxx"
18 #include "Exception.hxx"
19 #include "InlineNode.hxx"
20 #include "DataNode.hxx"
21 #include "ServiceNode.hxx"
22 #include "ServiceInlineNode.hxx"
23 #include "OutputDataStreamPort.hxx"
24 #include "InputDataStreamPort.hxx"
28 extern YACS::ENGINE::Proc* currentProc;
29 extern YACS::ENGINE::Runtime* theRuntime;
34 template <class T=YACS::ENGINE::Bloc*>
35 struct bloctypeParser:parser
37 static bloctypeParser<T> blocParser;
39 bloctypeParser():parser()
41 _orders["property"]=0;
46 _orders["datanode"]=2;
54 _orders["datalink"]=3;
56 _orders["parameter"]=3;
58 virtual void onStart(const XML_Char* el, const XML_Char** attr);
59 virtual void onEnd(const char *el,parser* child);
60 virtual void buildAttr(const XML_Char** attr)
62 this->required("name",attr);
63 for (int i = 0; attr[i]; i += 2)
65 if(std::string(attr[i]) == "name")name(attr[i+1]);
66 if(std::string(attr[i]) == "state")state(attr[i+1]);
69 void name (const std::string& name)
72 virtual void state (const std::string& name){
73 DEBTRACE( "bloc_state: " << name )
75 if(_state == "disabled")
77 DEBTRACE( "Bloc disabled: " << _bloc->getName())
78 _bloc->exDisabledState();
81 virtual void property (const myprop& prop)
83 DEBTRACE( "property_set: " << prop._name << prop._value )
84 _bloc->setProperty(prop._name,prop._value);
86 virtual void inline_ (YACS::ENGINE::InlineNode* const& n)
88 DEBTRACE( "bloc_pynode_set: " << n->getName() )
90 std::string fullname = currentProc->names.back()+n->getName();
91 currentProc->nodeMap[fullname]=n;
92 currentProc->inlineMap[fullname]=n;
94 virtual void sinline (YACS::ENGINE::ServiceInlineNode* const& n)
96 DEBTRACE( "bloc_sinline: " << n->getName() )
98 std::string fullname = currentProc->names.back()+n->getName();
99 currentProc->nodeMap[fullname]=n;
100 currentProc->serviceMap[fullname]=n;
102 virtual void service (YACS::ENGINE::ServiceNode* const& n)
104 DEBTRACE( "bloc_service_set: " << n->getName() )
105 _bloc->edAddChild(n);
106 std::string fullname = currentProc->names.back()+n->getName();
107 currentProc->nodeMap[fullname]=n;
108 currentProc->serviceMap[fullname]=n;
110 virtual void node (YACS::ENGINE::InlineNode* const& n)
112 DEBTRACE( "bloc_node_set: " << n->getName() )
113 _bloc->edAddChild(n);
114 std::string fullname = currentProc->names.back()+n->getName();
115 DEBTRACE( "bloc_node_set fullname = " << fullname )
116 currentProc->nodeMap[fullname]=n;
117 currentProc->inlineMap[fullname]=n;
119 virtual void forloop (YACS::ENGINE::ForLoop* const& b)
121 DEBTRACE( "bloc_forloop_set: " << b->getName() )
122 _bloc->edAddChild(b);
123 std::string fullname = currentProc->names.back()+b->getName();
124 currentProc->nodeMap[fullname]=b;
126 virtual void foreach (YACS::ENGINE::ForEachLoop* const& b)
128 DEBTRACE( "bloc_foreach_set: " << b->getName() )
129 _bloc->edAddChild(b);
130 std::string fullname = currentProc->names.back()+b->getName();
131 currentProc->nodeMap[fullname]=b;
132 fullname += ".splitter";
133 currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
135 virtual void while_ (YACS::ENGINE::WhileLoop* const& b)
137 DEBTRACE( "bloc_while_set: " << b->getName() )
138 _bloc->edAddChild(b);
139 std::string fullname = currentProc->names.back()+b->getName();
140 currentProc->nodeMap[fullname]=b;
142 virtual void switch_ (YACS::ENGINE::Switch* const& b)
144 DEBTRACE( "bloc_switch_set: " << b->getName() )
145 _bloc->edAddChild(b);
146 std::string fullname = currentProc->names.back()+b->getName();
147 currentProc->nodeMap[fullname]=b;
149 virtual void bloc (YACS::ENGINE::Bloc* const& b)
151 DEBTRACE( "bloc_bloc_set: " << b->getName() )
152 _bloc->edAddChild(b);
153 std::string fullname=currentProc->names.back()+ b->getName();
154 currentProc->nodeMap[fullname]=b;
156 virtual void control (const mycontrol& l)
158 DEBTRACE( "bloc_control_set: " << l.fromnode() << " "<< l.tonode() )
161 if(currentProc->nodeMap.count(currentProc->names.back()+l.fromnode()) == 0)
163 msg="from node " + l.fromnode() + " does not exist in control link: ";
164 msg=msg+l.fromnode()+"->"+l.tonode();
165 msg=msg+ " context: "+currentProc->names.back();
169 if(currentProc->nodeMap.count(currentProc->names.back()+l.tonode()) == 0)
171 msg="to node " + l.tonode() + " does not exist in control link: ";
172 msg=msg+l.fromnode()+"->"+l.tonode();
173 msg=msg+ " context: "+currentProc->names.back();
177 // We only link local nodes
180 _bloc->edAddCFLink(currentProc->nodeMap[currentProc->names.back()+l.fromnode()],
181 currentProc->nodeMap[currentProc->names.back()+l.tonode()]);
183 catch(YACS::Exception& e)
185 this->logError(e.what());
188 virtual void datalink (const mylink& l)
190 DEBTRACE( "bloc_datalink_set: "<<l.fromnode()<<"("<<l.fromport()<<")->"<<l.tonode()<<"("<<l.toport()<<")")
193 //Try only relative name for from node
194 std::string fromname = currentProc->names.back()+l.fromnode();
195 if(currentProc->nodeMap.count(fromname) == 0)
197 msg="from node " + l.fromnode() + " does not exist in data link: ";
198 msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
202 //Try relative name for to node and then absolute one
203 std::string toname = currentProc->names.back()+l.tonode();
204 if(currentProc->nodeMap.count(toname) == 0)
206 //It's not a relative name. Try an absolute one (I think it's not possible)
208 if(currentProc->nodeMap.count(toname) == 0)
210 // The TO node does not exist -> error
211 msg="to node " + l.tonode() + " does not exist in data link: ";
212 msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
217 // We only link local node and other nodes (relative or absolute name in this order)
218 DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport());
222 _bloc->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
223 currentProc->nodeMap[toname]->getInputPort(l.toport()));
225 _bloc->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
226 currentProc->nodeMap[toname]->getInputPort(l.toport()));
228 catch(YACS::Exception& e)
230 this->logError(e.what());
233 virtual void stream (const mystream& l)
235 DEBTRACE( "bloc_stream_set: " << l.fromnode() << l.fromport() << l.tonode() << l.toport() )
237 std::string fromname = currentProc->names.back()+l.fromnode();
238 std::string toname = currentProc->names.back()+l.tonode();
239 //only relative names
240 if(currentProc->nodeMap.count(fromname) == 0)
242 msg="from node " + l.fromnode() + " does not exist in stream link: ";
243 msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
247 if(currentProc->nodeMap.count(toname) == 0)
249 msg="to node " + l.tonode() + " does not exist in stream link: ";
250 msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
254 YACS::ENGINE::OutputDataStreamPort* pout=currentProc->nodeMap[fromname]->getOutputDataStreamPort(l.fromport());
255 YACS::ENGINE::InputDataStreamPort* pin=currentProc->nodeMap[toname]->getInputDataStreamPort(l.toport());
256 _bloc->edAddLink(pout,pin);
257 // Set all properties for this link
258 std::map<std::string, std::string>::const_iterator pt;
259 for(pt=l._props.begin();pt!=l._props.end();pt++)
261 pin->setProperty((*pt).first,(*pt).second);
262 pout->setProperty((*pt).first,(*pt).second);
265 virtual void parameter (const myparam& param)
267 DEBTRACE( "++++++++++++++++++++Parameter+++++++++++++++++++++" );
269 std::string toname = currentProc->names.back()+param._tonode;
270 if(currentProc->nodeMap.count(toname) == 0)
272 msg="to node " + param._tonode + " does not exist in parameter: ";
273 msg=msg+"->"+param._tonode+"("+param._toport+")";
277 YACS::ENGINE::InputPort* inport=currentProc->nodeMap[toname]->getInputPort(param._toport);
278 //We don't know the parameter type. So we try to initialize the port
279 //with the value. If it's not the right type, edInit throws an exception
282 inport->edInit("XML",param._value.c_str());
284 catch(YACS::Exception& e)
286 this->logError(e.what());
288 DEBTRACE( "++++++++++++++++++++End parameter+++++++++++++++++++++" );
291 virtual void preset (ENGINE::DataNode* const& n);
292 virtual void outnode (ENGINE::DataNode* const& n);
296 DEBTRACE( "bloc_post" )
297 currentProc->names.pop_back();
309 std::vector<YACS::ENGINE::Bloc *> _blocs;
312 template <class T> bloctypeParser<T> bloctypeParser<T>::blocParser;
315 void bloctypeParser<T>::preset (ENGINE::DataNode* const& n)
317 DEBTRACE("bloc_preset_set: " << n->getName() );
318 _bloc->edAddChild(n);
319 std::string fullname = currentProc->names.back()+n->getName();
320 currentProc->nodeMap[fullname]=n;
324 void bloctypeParser<T>::outnode (ENGINE::DataNode* const& n)
326 DEBTRACE("bloc_outnode: " << n->getName() );
327 _bloc->edAddChild(n);
328 std::string fullname = currentProc->names.back()+n->getName();
329 currentProc->nodeMap[fullname]=n;
333 void bloctypeParser<YACS::ENGINE::Bloc*>::name (const std::string& name)
335 DEBTRACE( "bloc_name: " << name )
336 std::string fullname=currentProc->names.back()+name;
337 _bloc=theRuntime->createBloc(name);
338 _blocs.push_back(_bloc);
339 currentProc->names.push_back(fullname+'.');
344 #include "loopParsers.hxx"
345 #include "switchParsers.hxx"
346 #include "presetParsers.hxx"
347 #include "outputParsers.hxx"
353 void bloctypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
355 DEBTRACE( "bloctypeParser::onStart: " << el )
356 std::string element(el);
358 parser* pp=&parser::main_parser;
359 if(element == "property")pp=&propertytypeParser::propertyParser;
361 else if(element == "inline")pp=&inlinetypeParser<>::inlineParser;
362 else if(element == "sinline")pp=&sinlinetypeParser<>::sinlineParser;
363 else if(element == "service")pp=&servicetypeParser<>::serviceParser;
364 else if(element == "node")pp=&nodetypeParser<>::nodeParser;
365 else if(element == "datanode")pp=&presettypeParser<>::presetParser;
366 else if(element == "outnode")pp=&outnodetypeParser<>::outnodeParser;
368 else if(element == "bloc")pp=&bloctypeParser<>::blocParser;
369 else if(element == "forloop")pp=&forlooptypeParser<>::forloopParser;
370 else if(element == "foreach")pp=&foreachlooptypeParser<>::foreachloopParser;
371 else if(element == "while")pp=&whilelooptypeParser<>::whileloopParser;
372 else if(element == "switch")pp=&switchtypeParser::switchParser;
374 else if(element == "control")pp=&controltypeParser<>::controlParser;
375 else if(element == "datalink")pp=&linktypeParser<>::linkParser;
376 else if(element == "stream")pp=&streamtypeParser<>::streamParser;
377 else if(element == "parameter")pp=¶metertypeParser::parameterParser;
379 this->SetUserDataAndPush(pp);
386 void bloctypeParser<T>::onEnd(const char *el,parser* child)
388 DEBTRACE( "bloctypeParser::onEnd: " << el )
389 std::string element(el);
390 if(element == "property")property(((propertytypeParser*)child)->post());
391 else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
392 else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
393 else if(element == "service")service(((servicetypeParser<>*)child)->post());
394 else if(element == "node")node(((nodetypeParser<>*)child)->post());
395 else if(element == "datanode")preset(((presettypeParser<>*)child)->post());
396 else if(element == "outnode")outnode(((outnodetypeParser<>*)child)->post());
398 else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
399 else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
400 else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
401 else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
402 else if(element == "switch")switch_(((switchtypeParser*)child)->post());
404 else if(element == "control") control(((controltypeParser<>*)child)->post());
405 else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());
406 else if(element == "stream") stream(((streamtypeParser<>*)child)->post());
407 else if(element == "parameter") parameter(((parametertypeParser*)child)->post());