2 #include "VisitorSaveSchema.hxx"
4 #include "ElementaryNode.hxx"
5 #include "InlineNode.hxx"
6 #include "ServiceNode.hxx"
7 #include "ServiceInlineNode.hxx"
10 #include "ForEachLoop.hxx"
12 #include "ForLoop.hxx"
13 #include "WhileLoop.hxx"
15 #include "InputPort.hxx"
16 #include "TypeCode.hxx"
17 #include "ComponentInstance.hxx"
18 #include "InputDataStreamPort.hxx"
19 #include "OutputDataStreamPort.hxx"
20 #include "Container.hxx"
27 using namespace YACS::ENGINE;
31 #include "YacsTrace.hxx"
33 VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root)
37 VisitorSaveSchema::~VisitorSaveSchema()
41 _out << "</proc>" << endl;
46 void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(Exception)
48 _out.open(xmlSchema.c_str(), ios::out);
51 string what = "Impossible to open file for writing: " + xmlSchema;
52 throw Exception(what);
54 _out << "<?xml version='1.0'?>" << endl;
55 _out << "<proc>" << endl;
58 void VisitorSaveSchema::closeFileSchema()
60 if (!_out) throw Exception("No file open for save schema");
61 _out << "</proc>" << endl;
65 void VisitorSaveSchema::visitBloc(Bloc *node)
67 DEBTRACE("START visitBloc " << _root->getChildName(node));
69 int depth = depthNode(node);
70 _out << indent(depth) << "<bloc name=\"" << node->getName() << "\"";
71 if (node->getState() == YACS::DISABLED)
72 _out << " state=\"disabled\">" << endl;
75 node->ComposedNode::accept(this);
77 writeSimpleDataLinks(node);
78 writeSimpleStreamLinks(node);
79 _out << indent(depth) << "</bloc>" << endl;
81 DEBTRACE("END visitBloc " << _root->getChildName(node));
84 void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node)
86 DEBTRACE("START visitElementaryNode " << _root->getChildName(node));
88 writeInputPorts(node);
89 writeInputDataStreamPorts(node);
90 writeOutputPorts(node);
91 writeOutputDataStreamPorts(node);
93 DEBTRACE("END visitElementaryNode " << _root->getChildName(node));
96 void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
98 DEBTRACE("START visitForEachLoop " << _root->getChildName(node));
100 int depth = depthNode(node);
102 _out << indent(depth) << "<foreach name=\"" << node->getName() << "\"";
103 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
104 if (node->getState() == YACS::DISABLED)
105 _out << " state=\"disabled\"";
106 if (!nbranch->isEmpty())
107 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
108 if (node->edGetSamplePort())
109 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
112 node->ComposedNode::accept(this);
113 writeSimpleDataLinks(node);
114 writeSimpleStreamLinks(node);
115 _out << indent(depth) << "</foreach>" << endl;
117 DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
120 void VisitorSaveSchema::visitForLoop(ForLoop *node)
122 DEBTRACE("START visitForLoop " << _root->getChildName(node));
124 int depth = depthNode(node);
125 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
126 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
127 if (node->getState() == YACS::DISABLED)
128 _out << " state=\"disabled\"";
129 if (nsteps->isEmpty())
132 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
133 node->ComposedNode::accept(this);
134 writeSimpleDataLinks(node);
135 writeSimpleStreamLinks(node);
136 _out << indent(depth) << "</forloop>" << endl;
138 DEBTRACE("END visitForLoop " << _root->getChildName(node));
141 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
143 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
145 int depth = depthNode(node);
146 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
147 if (node->getState() == YACS::DISABLED)
148 _out << " state=\"disabled\">" << endl;
151 _out << indent(depth+1) << "<script><code><![CDATA[";
152 _out << node->getScript();
153 _out << "]]></code></script>" << endl;
154 writeInputPorts(node);
155 writeInputDataStreamPorts(node);
156 writeOutputPorts(node);
157 writeOutputDataStreamPorts(node);
158 _out << indent(depth) << "</inline>" << endl;
160 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
163 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
165 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
167 int depth = depthNode(node);
168 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
169 if (node->getState() == YACS::DISABLED)
170 _out << " state=\"disabled\">" << endl;
173 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
174 _out << indent(depth+2) << "<code><![CDATA[";
175 _out << node->getScript();
176 _out << "]]></code>" << endl;
177 _out << indent(depth+1) << "</function>" << endl;
178 writeInputPorts(node);
179 writeInputDataStreamPorts(node);
180 writeOutputPorts(node);
181 writeOutputDataStreamPorts(node);
182 _out << indent(depth) << "</inline>" << endl;
184 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
187 void VisitorSaveSchema::visitLoop(Loop *node)
189 DEBTRACE("START visitLoop " << _root->getChildName(node));
191 int depth = depthNode(node);
192 node->ComposedNode::accept(this);
194 writeSimpleDataLinks(node);
195 writeSimpleStreamLinks(node);
197 DEBTRACE("END visitLoop " << _root->getChildName(node));
200 void VisitorSaveSchema::visitProc(Proc *node)
202 DEBTRACE("START visitProc " << node->getName());
204 writeProperties(node);
205 writeTypeCodes(node);
206 writeContainers(node);
207 node->ComposedNode::accept(this);
209 writeSimpleDataLinks(node);
210 writeSimpleStreamLinks(node);
211 writeParameters(node);
213 DEBTRACE("END visitProc " << node->getName());
216 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
218 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
220 int depth = depthNode(node);
221 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
222 if (node->getState() == YACS::DISABLED)
223 _out << " state=\"disabled\">" << endl;
226 if (node->getKind() == "XML")
228 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
229 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
233 ComponentInstance *compo = node->getComponent();
234 if (_componentInstanceMap.find(compo) == _componentInstanceMap.end())
236 _out << indent(depth+1) << compo->getFileRepr() << endl;
237 _componentInstanceMap[compo] = _root->getChildName(node);
238 Container *cont = compo->getContainer();
241 map<string, Container*>::const_iterator it;
242 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
244 if (it->second == cont) break;
246 if (it != _containerMap.end())
247 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
252 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
255 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
257 writeInputPorts(node);
258 writeInputDataStreamPorts(node);
259 writeOutputPorts(node);
260 writeOutputDataStreamPorts(node);
261 _out << indent(depth) << "</service>" << endl;
263 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
266 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
268 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
270 int depth = depthNode(node);
271 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
272 if (node->getState() == YACS::DISABLED)
273 _out << " state=\"disabled\">" << endl;
276 _out << indent(depth+1) << node->getComponent()->getFileRepr() << endl;
277 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
278 _out << indent(depth+2) << "<code><![CDATA[";
279 _out << node->getScript();
280 _out << "]]></code>" << endl;
281 _out << indent(depth+1) << "</function>" << endl;
282 writeInputPorts(node);
283 writeOutputPorts(node);
284 _out << indent(depth) << "</serviceInline>" << endl;
286 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
290 void VisitorSaveSchema::visitSwitch(Switch *node)
292 DEBTRACE("START visitSwitch " << _root->getChildName(node));
294 int depth = depthNode(node);
295 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
296 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
297 if (node->getState() == YACS::DISABLED)
298 _out << " state=\"disabled\"";
299 if (condition->isEmpty())
302 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
303 node->ComposedNode::accept(this);
305 writeSimpleDataLinks(node);
306 writeSimpleStreamLinks(node);
307 _out << indent(depth) << "</switch>" << endl;
309 DEBTRACE("END visitSwitch " << _root->getChildName(node));
312 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
314 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
316 int depth = depthNode(node);
317 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
318 if (node->getState() == YACS::DISABLED)
319 _out << " state=\"disabled\">" << endl;
322 node->ComposedNode::accept(this);
323 writeSimpleDataLinks(node);
324 writeSimpleStreamLinks(node);
325 _out << indent(depth) << "</while>" << endl;
327 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
331 void VisitorSaveSchema::writeProperties(Node *node)
333 int depth = depthNode(node)+1;
334 map<string,string> properties = getNodeProperties(node);
335 map<string,string>::const_iterator it;
336 for(it = properties.begin(); it != properties.end(); ++it)
338 _out << indent(depth) << "<property name=\"" << it->first
339 << "\" value=\"" << it->second << "\"/>" << endl;
343 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
345 int depth = depthNode(proc)+1;
346 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
347 map<string, TypeCode*>::const_iterator it;
348 set<string> typeNames;
350 // --- force definition of simple types first
352 _out << indent(depth) << "<type name=\"Bool\" kind=\"bool\"/>" << endl;
353 _out << indent(depth) << "<type name=\"Double\" kind=\"double\"/>" << endl;
354 _out << indent(depth) << "<type name=\"Int\" kind=\"int\"/>" << endl;
355 _out << indent(depth) << "<type name=\"String\" kind=\"string\"/>" << endl;
356 typeNames.insert("Bool");
357 typeNames.insert("Double");
358 typeNames.insert("Int");
359 typeNames.insert("String");
361 for (it = typeMap.begin(); it != typeMap.end(); it++)
363 DynType kind = (it->second)->kind();
364 string typeId = (it->second)->id();
367 case YACS::ENGINE::Double:
369 if (typeNames.find(typeId) == typeNames.end())
371 typeNames.insert(typeId);
372 _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"double\"/>" << endl;
376 case YACS::ENGINE::Int:
378 if (typeNames.find(typeId) == typeNames.end())
380 typeNames.insert(typeId);
381 _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"int\"/>" << endl;
385 case YACS::ENGINE::String:
387 if (typeNames.find(typeId) == typeNames.end())
389 typeNames.insert(typeId);
390 _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"string\"/>" << endl;
394 case YACS::ENGINE::Bool:
396 if (typeNames.find(typeId) == typeNames.end())
398 typeNames.insert(typeId);
399 _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"bool\"/>" << endl;
403 case YACS::ENGINE::Objref:
405 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(it->second);
407 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
408 _out << indent(depth) << "<objref name=\"" << it->first << "\" id=\""
409 << objref->id() << "\"";
410 if (listOfBases.empty())
411 _out << "/>" << endl;
415 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
417 _out << indent(depth+1) << "<base>";
418 _out << (*il)->name();
419 _out << "</base>" << endl;
421 _out << indent(depth) << "</objref>" << endl;
425 case YACS::ENGINE::Sequence:
427 const TypeCode* content = (it->second)->contentType();
429 _out << indent(depth) << "<sequence name=\"" << it->first << "\" content=\""
430 << content->name() << "\"/>" << endl;
435 string what = "wrong TypeCode: ";
436 throw Exception(what);
442 void VisitorSaveSchema::writeContainers(Proc *proc)
444 int depth = depthNode(proc)+1;
445 _containerMap = getContainerMap(proc);
446 map<string, Container*>::const_iterator it;
447 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
449 string name = it->first;
450 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
451 _out << indent(depth) << "</container>" << endl;
456 void VisitorSaveSchema::writeInputPorts(Node *node)
458 int depth = depthNode(node)+1;
459 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
460 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
462 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
463 << (*it)->edGetType()->name() << "\"/>" << endl;
467 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
469 int depth = depthNode(node)+1;
470 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
471 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
473 std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
474 if ( aPropMap.empty() )
475 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
476 << (*it)->edGetType()->name() << "\"/>" << endl;
479 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
480 << (*it)->edGetType()->name() << "\">" << endl;
481 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
482 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
483 << (*itP).second << "\"/>" << endl;
484 _out << indent(depth) << "</instream>" << endl;
489 void VisitorSaveSchema::writeOutputPorts(Node *node)
491 int depth = depthNode(node)+1;
492 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
493 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
495 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
496 << (*it)->edGetType()->name() << "\"/>" << endl;
500 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
502 int depth = depthNode(node)+1;
503 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
504 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
506 std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
507 if ( aPropMap.empty() )
508 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
509 << (*it)->edGetType()->name() << "\"/>" << endl;
512 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
513 << (*it)->edGetType()->name() << "\">" << endl;
514 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
515 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
516 << (*itP).second << "\"/>" << endl;
517 _out << indent(depth) << "</outstream>" << endl;
522 void VisitorSaveSchema::writeControls(ComposedNode *node)
524 int depth = depthNode(node)+1;
525 set<Node*> setOfChildren = node->edGetDirectDescendants();
526 for (set<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
528 // --- Control links from direct descendant to nodes inside the bloc
529 set<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
530 for (set<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
532 Node *to = (*ig)->getNode();
533 if (node->isInMyDescendance(to))
536 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
537 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
540 // --- Control links from nodes inside the bloc to direct descendant
541 // avoid links between direct descendants (already done above)
542 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
543 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
545 Node *from = (*ig)->getNode();
546 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
549 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
550 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
557 * Write simple data links from and to direct children of node (grand children already done).
558 * First, for all output ports of direct children, write links where the input port is inside
559 * the node scope. Keep in memory the links where the input port is outside the node scope.
560 * Second, retreive links where the output port is inside the scope, using the links kept in memory
561 * and not yet written.
563 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
565 int depth = depthNode(node)+1;
566 set<Node*> setOfChildren = node->edGetDirectDescendants();
568 set<Node*> setOfChildrenPlusSplitters = setOfChildren;
570 for (set<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
571 // add "splitter" node of ForEachLoop nodes to the set of children
572 if ( dynamic_cast<ForEachLoop*>( *ic ) )
573 setOfChildrenPlusSplitters.insert( (*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE) );
575 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
577 for (set<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
580 list<OutputPort*> listOP = from->getLocalOutputPorts();
581 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
583 OutputPort* anOP = *io;
584 set<InPort*> setIP = anOP->edSetInPort();
585 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
588 Node* to = anIP->getNode();
589 cerr << "from " << from->getName() << " outputPort " << anOP->getName()
590 << " to " << to->getName() << " inputPort " << anIP->getName() << endl;
591 Node* child = node->isInMyDescendance(to);
592 if (child && (child->getNumId() != node->getNumId())
593 && (from->getNumId() != to->getNumId()))
595 cerr << "BINGO!" << endl;
598 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
599 fromName = from->getFather()->getName();
601 fromName = node->getChildName(from);
604 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
605 childName = node->getChildName(to->getFather());
607 childName = node->getChildName(to);
608 _out << indent(depth) << "<datalink control=\"false\">" << endl;
609 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
610 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
611 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
612 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
613 _out << indent(depth) << "</datalink>" << endl;
616 { // --- store info to create the link later, given the input port
617 cerr << "For later" << endl;
618 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
619 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
625 // --- second pass, retreive links where the output port is inside the scope.
627 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
629 std::multimap<int, DataLinkInfo>::iterator pos;
630 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
632 Node* to = (pos->second).to;
633 Node* child = node->isInMyDescendance(to);
634 if (child && (child->getNumId() != node->getNumId()))
636 InPort* anIP = (pos->second).inp;
637 int portId = anIP->getNumId();
638 Node* from = (pos->second).from;
639 child = node->isInMyDescendance(from);
640 if (child && (child->getNumId() != node->getNumId()))
641 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
643 string childName = node->getChildName(from);
644 OutPort *anOP = (pos->second).outp;
645 (pos->second).toDelete = true;
646 _out << indent(depth) << "<datalink control=\"false\">" << endl;
647 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
648 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
649 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
650 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
651 _out << indent(depth) << "</datalink>" << endl;
656 // --- remove the link written from the multimap
658 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
660 if ((pos->second).toDelete)
661 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
668 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
670 int depth = depthNode(node)+1;
671 set<Node*> setOfChildren = node->edGetDirectDescendants();
673 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
675 for (set<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
678 if ( dynamic_cast<ComposedNode*>(from) ) continue;
679 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
680 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
682 OutputDataStreamPort* anOP = *io;
683 set<InPort*> setIP = anOP->edSetInPort();
684 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
687 Node* to = anIP->getNode();
688 cerr << "from " << from->getName() << " outputPort " << anOP->getName()
689 << " to " << to->getName() << " inputPort " << anIP->getName() << endl;
690 Node* child = node->isInMyDescendance(to);
691 if (child && (child->getNumId() != node->getNumId())
692 && (from->getNumId() != to->getNumId()))
694 cerr << "BINGO!" << endl;
695 string childName = node->getChildName(to);
696 _out << indent(depth) << "<stream>" << endl;
697 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
698 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
699 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
700 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
702 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
703 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
704 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
705 << (*itP).second << "\"/>" << endl;
707 _out << indent(depth) << "</stream>" << endl;
710 { // --- store info to create the link later, given the input port
711 cerr << "For later" << endl;
712 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
713 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
719 // --- second pass, retreive links where the output port is inside the scope.
721 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
723 std::multimap<int, StreamLinkInfo>::iterator pos;
724 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
726 Node* to = (pos->second).to;
727 Node* child = node->isInMyDescendance(to);
728 if (child && (child->getNumId() != node->getNumId()))
730 InPort* anIP = (pos->second).inp;
731 int portId = anIP->getNumId();
732 Node* from = (pos->second).from;
733 child = node->isInMyDescendance(from);
734 if (child && (child->getNumId() != node->getNumId()))
735 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
737 string childName = node->getChildName(from);
738 OutputDataStreamPort *anOP = (pos->second).outp;
739 (pos->second).toDelete = true;
740 _out << indent(depth) << "<stream>" << endl;
741 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
742 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
743 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
744 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
746 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
747 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
748 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
749 << (*itP).second << "\"/>" << endl;
751 _out << indent(depth) << "</stream>" << endl;
756 // --- remove the link written from the multimap
758 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
760 if ((pos->second).toDelete)
761 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
768 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
771 set<Node *> setOfNode = node->edGetDirectDescendants();
772 for(set<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
774 if ( dynamic_cast<ComposedNode*> (*iter) )
776 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
777 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
782 set<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
783 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
790 void VisitorSaveSchema::writeParameters(Proc *proc)
792 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
793 set<Node*> nodeSet = getAllNodes(proc);
794 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
796 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
798 // writeParametersNode(proc,node);
799 writeParametersNode(proc,(*iter));
803 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
806 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
807 if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
809 DEBTRACE("writeParametersNode foreach");
810 setOfInputPort.push_back( foreach->edGetSeqOfSamplesPort());
812 list<InputPort *>::iterator iter;
813 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
815 if (!(*iter)->isEmpty())
817 _out << indent(depth) << "<parameter>" << endl;
818 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
819 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
822 _out << indent(depth+1) << (*iter)->dump();
824 catch (YACS::Exception &e)
826 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
828 _out << indent(depth) << "</parameter>" << endl;
833 void VisitorSaveSchema::beginCase(Node* node)
835 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
838 int depth = depthNode(node) -1;
839 int myCase = myFather->getRankOfNode(node);
840 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
841 _out << indent(depth) << "<default>" << endl;
843 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
847 void VisitorSaveSchema::endCase(Node* node)
849 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
852 int depth = depthNode(node) -1;
853 int myCase = myFather->getRankOfNode(node);
854 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
855 _out << indent(depth) << "</default>" << endl;
857 _out << indent(depth) << "</case>" << endl;
861 int VisitorSaveSchema::depthNode(Node* node)
864 ComposedNode *father = node->getFather();
868 if (dynamic_cast<Switch*>(father)) depth +=1;
869 if (father->getNumId() == _root->getNumId()) break;
870 father = father->getFather();
875 SchemaSave::SchemaSave(Proc* proc): _p(proc)
880 void SchemaSave::save(std::string xmlSchemaFile)
882 VisitorSaveSchema vss(_p);
883 vss.openFileSchema(xmlSchemaFile);
885 vss.closeFileSchema();