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"
21 #include "DataNode.hxx"
28 using namespace YACS::ENGINE;
32 #include "YacsTrace.hxx"
34 VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root)
38 VisitorSaveSchema::~VisitorSaveSchema()
42 _out << "</proc>" << endl;
47 void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(Exception)
49 _out.open(xmlSchema.c_str(), ios::out);
52 string what = "Impossible to open file for writing: " + xmlSchema;
53 throw Exception(what);
55 _out << "<?xml version='1.0'?>" << endl;
56 _out << "<proc>" << endl;
59 void VisitorSaveSchema::closeFileSchema()
61 if (!_out) throw Exception("No file open for save schema");
62 _out << "</proc>" << endl;
66 void VisitorSaveSchema::visitBloc(Bloc *node)
68 DEBTRACE("START visitBloc " << _root->getChildName(node));
70 int depth = depthNode(node);
71 _out << indent(depth) << "<bloc name=\"" << node->getName() << "\"";
72 if (node->getState() == YACS::DISABLED)
73 _out << " state=\"disabled\">" << endl;
76 writeProperties(node);
77 node->ComposedNode::accept(this);
79 writeSimpleDataLinks(node);
80 writeSimpleStreamLinks(node);
81 _out << indent(depth) << "</bloc>" << endl;
83 DEBTRACE("END visitBloc " << _root->getChildName(node));
86 void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node)
88 DEBTRACE("START visitElementaryNode " << _root->getChildName(node));
90 writeProperties(node);
91 writeInputPorts(node);
92 writeInputDataStreamPorts(node);
93 writeOutputPorts(node);
94 writeOutputDataStreamPorts(node);
96 DEBTRACE("END visitElementaryNode " << _root->getChildName(node));
99 void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
101 DEBTRACE("START visitForEachLoop " << _root->getChildName(node));
103 int depth = depthNode(node);
105 _out << indent(depth) << "<foreach name=\"" << node->getName() << "\"";
106 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
107 if (node->getState() == YACS::DISABLED)
108 _out << " state=\"disabled\"";
109 if (!nbranch->isEmpty())
110 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
111 if (node->edGetSamplePort())
112 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
115 writeProperties(node);
116 node->ComposedNode::accept(this);
117 writeSimpleDataLinks(node);
118 writeSimpleStreamLinks(node);
119 _out << indent(depth) << "</foreach>" << endl;
121 DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
124 void VisitorSaveSchema::visitForLoop(ForLoop *node)
126 DEBTRACE("START visitForLoop " << _root->getChildName(node));
128 int depth = depthNode(node);
129 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
130 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
131 if (node->getState() == YACS::DISABLED)
132 _out << " state=\"disabled\"";
133 if (nsteps->isEmpty())
136 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
137 writeProperties(node);
138 node->ComposedNode::accept(this);
139 writeSimpleDataLinks(node);
140 writeSimpleStreamLinks(node);
141 _out << indent(depth) << "</forloop>" << endl;
143 DEBTRACE("END visitForLoop " << _root->getChildName(node));
146 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
148 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
150 int depth = depthNode(node);
151 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
152 if (node->getState() == YACS::DISABLED)
153 _out << " state=\"disabled\">" << endl;
156 writeProperties(node);
157 _out << indent(depth+1) << "<script><code><![CDATA[";
158 _out << node->getScript();
159 _out << "]]></code></script>" << endl;
160 writeInputPorts(node);
161 writeInputDataStreamPorts(node);
162 writeOutputPorts(node);
163 writeOutputDataStreamPorts(node);
164 _out << indent(depth) << "</inline>" << endl;
166 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
169 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
171 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
173 int depth = depthNode(node);
174 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
175 if (node->getState() == YACS::DISABLED)
176 _out << " state=\"disabled\">" << endl;
179 writeProperties(node);
180 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
181 _out << indent(depth+2) << "<code><![CDATA[";
182 _out << node->getScript();
183 _out << "]]></code>" << endl;
184 _out << indent(depth+1) << "</function>" << endl;
185 writeInputPorts(node);
186 writeInputDataStreamPorts(node);
187 writeOutputPorts(node);
188 writeOutputDataStreamPorts(node);
189 _out << indent(depth) << "</inline>" << endl;
191 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
194 void VisitorSaveSchema::visitLoop(Loop *node)
196 DEBTRACE("START visitLoop " << _root->getChildName(node));
198 int depth = depthNode(node);
199 writeProperties(node);
200 node->ComposedNode::accept(this);
202 writeSimpleDataLinks(node);
203 writeSimpleStreamLinks(node);
205 DEBTRACE("END visitLoop " << _root->getChildName(node));
208 void VisitorSaveSchema::visitProc(Proc *node)
210 DEBTRACE("START visitProc " << node->getName());
212 writeProperties(node);
213 writeTypeCodes(node);
214 writeContainers(node);
215 node->ComposedNode::accept(this);
217 writeSimpleDataLinks(node);
218 writeSimpleStreamLinks(node);
219 writeParameters(node);
221 DEBTRACE("END visitProc " << node->getName());
224 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
226 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
228 int depth = depthNode(node);
229 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
230 if (node->getState() == YACS::DISABLED)
231 _out << " state=\"disabled\">" << endl;
234 writeProperties(node);
235 if (node->getKind() == "XML")
237 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
238 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
242 ComponentInstance *compo = node->getComponent();
243 if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
245 _out << indent(depth+1) << compo->getFileRepr() << endl;
246 _componentInstanceMap[compo] = _root->getChildName(node);
247 Container *cont = compo->getContainer();
250 map<string, Container*>::const_iterator it;
251 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
253 if (it->second == cont) break;
255 if (it != _containerMap.end())
256 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
261 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
264 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
266 writeInputPorts(node);
267 writeInputDataStreamPorts(node);
268 writeOutputPorts(node);
269 writeOutputDataStreamPorts(node);
270 _out << indent(depth) << "</service>" << endl;
272 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
275 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
277 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
279 int depth = depthNode(node);
280 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
281 if (node->getState() == YACS::DISABLED)
282 _out << " state=\"disabled\">" << endl;
286 writeProperties(node);
287 ComponentInstance *compo = node->getComponent();
289 _out << indent(depth+1) << compo->getFileRepr() << endl;
291 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
292 _out << indent(depth+2) << "<code><![CDATA[";
293 _out << node->getScript();
294 _out << "]]></code>" << endl;
295 _out << indent(depth+1) << "</function>" << endl;
296 writeInputPorts(node);
297 writeOutputPorts(node);
298 _out << indent(depth) << "</serviceInline>" << endl;
300 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
303 void VisitorSaveSchema::visitPresetNode(DataNode *node)
305 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
306 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
309 void VisitorSaveSchema::visitOutNode(DataNode *node)
311 DEBTRACE("START visitOutNode " << _root->getChildName(node));
312 DEBTRACE("END visitOutNode " << _root->getChildName(node));
315 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
317 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
318 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
321 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
323 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
324 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
328 void VisitorSaveSchema::visitSwitch(Switch *node)
330 DEBTRACE("START visitSwitch " << _root->getChildName(node));
332 int depth = depthNode(node);
333 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
334 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
335 if (node->getState() == YACS::DISABLED)
336 _out << " state=\"disabled\"";
337 if (condition->isEmpty())
340 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
341 writeProperties(node);
342 node->ComposedNode::accept(this);
344 writeSimpleDataLinks(node);
345 writeSimpleStreamLinks(node);
346 _out << indent(depth) << "</switch>" << endl;
348 DEBTRACE("END visitSwitch " << _root->getChildName(node));
351 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
353 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
355 int depth = depthNode(node);
356 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
357 if (node->getState() == YACS::DISABLED)
358 _out << " state=\"disabled\">" << endl;
361 writeProperties(node);
362 node->ComposedNode::accept(this);
363 writeSimpleDataLinks(node);
364 writeSimpleStreamLinks(node);
365 _out << indent(depth) << "</while>" << endl;
367 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
371 void VisitorSaveSchema::writeProperties(Node *node)
373 int depth = depthNode(node)+1;
374 map<string,string> properties = getNodeProperties(node);
375 map<string,string>::const_iterator it;
376 for(it = properties.begin(); it != properties.end(); ++it)
378 _out << indent(depth) << "<property name=\"" << it->first
379 << "\" value=\"" << it->second << "\"/>" << endl;
383 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, set<string>& typeNames,map<string, TypeCode*>& typeMap,int depth)
385 DynType kind = type->kind();
386 string typeName = type->name();
387 if (typeNames.find(typeName) != typeNames.end())
391 case YACS::ENGINE::Double:
393 typeNames.insert(typeName);
394 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
397 case YACS::ENGINE::Int:
399 typeNames.insert(typeName);
400 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
403 case YACS::ENGINE::String:
405 typeNames.insert(typeName);
406 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
409 case YACS::ENGINE::Bool:
411 typeNames.insert(typeName);
412 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
415 case YACS::ENGINE::Objref:
417 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
418 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
419 //try to dump base classes
420 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
422 if (typeNames.find((*il)->name()) == typeNames.end())
423 dumpTypeCode((*il),typeNames,typeMap,depth);
426 typeNames.insert(typeName);
427 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
428 << objref->id() << "\"";
429 if (listOfBases.empty())
430 _out << "/>" << endl;
434 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
436 _out << indent(depth+1) << "<base>";
437 _out << (*il)->name();
438 _out << "</base>" << endl;
440 _out << indent(depth) << "</objref>" << endl;
444 case YACS::ENGINE::Sequence:
446 TypeCode* content = (TypeCode*)type->contentType();
447 if (typeNames.find(content->name()) == typeNames.end())
449 //content type not dumped
450 dumpTypeCode(content,typeNames,typeMap,depth);
452 typeNames.insert(typeName);
453 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
454 << content->name() << "\"/>" << endl;
457 case YACS::ENGINE::Array:
459 TypeCode* content = (TypeCode*)type->contentType();
460 if (typeNames.find(content->name()) == typeNames.end())
462 //content type not dumped
463 dumpTypeCode(content,typeNames,typeMap,depth);
465 typeNames.insert(typeName);
466 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
467 << content->name() << "\"/>" << endl;
470 case YACS::ENGINE::Struct:
472 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
474 int mbCnt = tcStruct->memberCount();
475 for (int i=0; i<mbCnt; i++)
477 TypeCode* member = tcStruct->memberType(i);
478 if (typeNames.find(member->name()) == typeNames.end())
480 //content type not dumped
481 dumpTypeCode(member,typeNames,typeMap,depth);
484 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
485 for (int i=0; i<mbCnt; i++)
487 TypeCode* member = tcStruct->memberType(i);
488 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
490 _out << indent(depth) << "</struct>" << endl;
495 string what = "wrong TypeCode: ";
496 throw Exception(what);
501 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
503 int depth = depthNode(proc)+1;
504 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
505 map<string, TypeCode*>::const_iterator it;
506 set<string> typeNames;
508 // --- force definition of simple types first
510 _out << indent(depth) << "<type name=\"Bool\" kind=\"bool\"/>" << endl;
511 _out << indent(depth) << "<type name=\"Double\" kind=\"double\"/>" << endl;
512 _out << indent(depth) << "<type name=\"Int\" kind=\"int\"/>" << endl;
513 _out << indent(depth) << "<type name=\"String\" kind=\"string\"/>" << endl;
514 typeNames.insert("Bool");
515 typeNames.insert("Double");
516 typeNames.insert("Int");
517 typeNames.insert("String");
519 for (it = typeMap.begin(); it != typeMap.end(); it++)
521 dumpTypeCode(it->second,typeNames,typeMap,depth);
525 void VisitorSaveSchema::writeContainers(Proc *proc)
527 int depth = depthNode(proc)+1;
528 _containerMap = getContainerMap(proc);
529 map<string, Container*>::const_iterator it;
530 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
532 string name = it->first;
533 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
534 map<string, string> properties = (it->second)->getProperties();
535 map<string, string>::iterator itm;
536 for(itm = properties.begin(); itm != properties.end(); ++itm)
537 _out << indent(depth+1) << "<property name=\"" << (*itm).first
538 << "\" value=\"" << (*itm).second << "\"/>" << endl;
539 _out << indent(depth) << "</container>" << endl;
544 void VisitorSaveSchema::writeInputPorts(Node *node)
546 int depth = depthNode(node)+1;
547 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
548 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
550 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
551 << (*it)->edGetType()->name() << "\"/>" << endl;
555 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
557 int depth = depthNode(node)+1;
558 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
559 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
561 std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
562 if ( aPropMap.empty() )
563 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
564 << (*it)->edGetType()->name() << "\"/>" << endl;
567 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
568 << (*it)->edGetType()->name() << "\">" << endl;
569 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
570 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
571 << (*itP).second << "\"/>" << endl;
572 _out << indent(depth) << "</instream>" << endl;
577 void VisitorSaveSchema::writeOutputPorts(Node *node)
579 int depth = depthNode(node)+1;
580 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
581 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
583 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
584 << (*it)->edGetType()->name() << "\"/>" << endl;
588 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
590 int depth = depthNode(node)+1;
591 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
592 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
594 std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
595 if ( aPropMap.empty() )
596 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
597 << (*it)->edGetType()->name() << "\"/>" << endl;
600 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
601 << (*it)->edGetType()->name() << "\">" << endl;
602 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
603 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
604 << (*itP).second << "\"/>" << endl;
605 _out << indent(depth) << "</outstream>" << endl;
610 void VisitorSaveSchema::writeControls(ComposedNode *node)
612 int depth = depthNode(node)+1;
613 list<Node*> setOfChildren = node->edGetDirectDescendants();
614 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
616 // --- Control links from direct descendant to nodes inside the bloc
617 set<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
618 for (set<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
620 Node *to = (*ig)->getNode();
621 if (node->isInMyDescendance(to))
624 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
625 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
628 // --- Control links from nodes inside the bloc to direct descendant
629 // avoid links between direct descendants (already done above)
630 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
631 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
633 Node *from = (*ig)->getNode();
634 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
637 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
638 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
645 * Write simple data links from and to direct children of node (grand children already done).
646 * First, for all output ports of direct children, write links where the input port is inside
647 * the node scope. Keep in memory the links where the input port is outside the node scope.
648 * Second, retreive links where the output port is inside the scope, using the links kept in memory
649 * and not yet written.
651 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
653 int depth = depthNode(node)+1;
654 list<Node*> setOfChildren = node->edGetDirectDescendants();
656 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
658 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
659 // add "splitter" node of ForEachLoop nodes to the set of children
660 if ( dynamic_cast<ForEachLoop*>( *ic ) )
662 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
663 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
664 setOfChildrenPlusSplitters.push_back(nodeToInsert);
667 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
669 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
672 list<OutputPort*> listOP = from->getLocalOutputPorts();
673 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
675 OutputPort* anOP = *io;
676 set<InPort*> setIP = anOP->edSetInPort();
677 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
680 Node* to = anIP->getNode();
681 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
682 << " to " << to->getName() << " inputPort " << anIP->getName() );
683 Node* child = node->isInMyDescendance(to);
684 if (child && (child->getNumId() != node->getNumId())
685 && (from->getNumId() != to->getNumId()))
687 DEBTRACE( "BINGO!" );
690 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
691 fromName = from->getFather()->getName();
693 fromName = node->getChildName(from);
696 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
697 childName = node->getChildName(to->getFather());
699 childName = node->getChildName(to);
700 _out << indent(depth) << "<datalink control=\"false\">" << endl;
701 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
702 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
703 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
704 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
705 _out << indent(depth) << "</datalink>" << endl;
708 { // --- store info to create the link later, given the input port
709 DEBTRACE( "For later" );
710 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
711 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
717 // --- second pass, retreive links where the output port is inside the scope.
719 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
721 std::multimap<int, DataLinkInfo>::iterator pos;
722 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
724 Node* to = (pos->second).to;
725 Node* child = node->isInMyDescendance(to);
726 if (child && (child->getNumId() != node->getNumId()))
728 InPort* anIP = (pos->second).inp;
729 int portId = anIP->getNumId();
730 Node* from = (pos->second).from;
731 child = node->isInMyDescendance(from);
732 if (child && (child->getNumId() != node->getNumId()))
733 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
735 string childName = node->getChildName(from);
736 OutPort *anOP = (pos->second).outp;
737 (pos->second).toDelete = true;
738 _out << indent(depth) << "<datalink control=\"false\">" << endl;
739 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
740 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
741 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
742 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
743 _out << indent(depth) << "</datalink>" << endl;
748 // --- remove the link written from the multimap
750 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
752 if ((pos->second).toDelete)
753 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
760 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
762 int depth = depthNode(node)+1;
763 list<Node*> setOfChildren = node->edGetDirectDescendants();
765 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
767 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
770 if ( dynamic_cast<ComposedNode*>(from) ) continue;
771 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
772 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
774 OutputDataStreamPort* anOP = *io;
775 set<InPort*> setIP = anOP->edSetInPort();
776 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
779 Node* to = anIP->getNode();
780 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
781 << " to " << to->getName() << " inputPort " << anIP->getName() );
782 Node* child = node->isInMyDescendance(to);
783 if (child && (child->getNumId() != node->getNumId())
784 && (from->getNumId() != to->getNumId()))
786 DEBTRACE( "BINGO!" );
787 string childName = node->getChildName(to);
788 _out << indent(depth) << "<stream>" << endl;
789 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
790 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
791 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
792 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
794 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
795 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
796 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
797 << (*itP).second << "\"/>" << endl;
799 _out << indent(depth) << "</stream>" << endl;
802 { // --- store info to create the link later, given the input port
803 DEBTRACE("For later" );
804 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
805 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
811 // --- second pass, retreive links where the output port is inside the scope.
813 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
815 std::multimap<int, StreamLinkInfo>::iterator pos;
816 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
818 Node* to = (pos->second).to;
819 Node* child = node->isInMyDescendance(to);
820 if (child && (child->getNumId() != node->getNumId()))
822 InPort* anIP = (pos->second).inp;
823 int portId = anIP->getNumId();
824 Node* from = (pos->second).from;
825 child = node->isInMyDescendance(from);
826 if (child && (child->getNumId() != node->getNumId()))
827 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
829 string childName = node->getChildName(from);
830 OutputDataStreamPort *anOP = (pos->second).outp;
831 (pos->second).toDelete = true;
832 _out << indent(depth) << "<stream>" << endl;
833 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
834 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
835 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
836 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
838 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
839 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
840 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
841 << (*itP).second << "\"/>" << endl;
843 _out << indent(depth) << "</stream>" << endl;
848 // --- remove the link written from the multimap
850 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
852 if ((pos->second).toDelete)
853 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
860 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
863 list< Node *> setOfNode = node->edGetDirectDescendants();
864 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
866 if ( dynamic_cast<ComposedNode*> (*iter) )
868 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
869 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
874 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
875 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
882 void VisitorSaveSchema::writeParameters(Proc *proc)
884 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
885 set<Node*> nodeSet = getAllNodes(proc);
886 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
888 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
890 // writeParametersNode(proc,node);
891 writeParametersNode(proc,(*iter));
895 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
898 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
899 if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
901 DEBTRACE("writeParametersNode foreach");
902 setOfInputPort.push_back( foreach->edGetSeqOfSamplesPort());
904 list<InputPort *>::iterator iter;
905 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
907 if (!(*iter)->isEmpty())
909 _out << indent(depth) << "<parameter>" << endl;
910 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
911 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
914 _out << indent(depth+1) << (*iter)->dump();
916 catch (YACS::Exception &e)
918 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
920 _out << indent(depth) << "</parameter>" << endl;
925 void VisitorSaveSchema::beginCase(Node* node)
927 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
930 int depth = depthNode(node) -1;
931 int myCase = myFather->getRankOfNode(node);
932 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
933 _out << indent(depth) << "<default>" << endl;
935 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
939 void VisitorSaveSchema::endCase(Node* node)
941 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
944 int depth = depthNode(node) -1;
945 int myCase = myFather->getRankOfNode(node);
946 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
947 _out << indent(depth) << "</default>" << endl;
949 _out << indent(depth) << "</case>" << endl;
953 int VisitorSaveSchema::depthNode(Node* node)
956 ComposedNode *father = node->getFather();
960 if (dynamic_cast<Switch*>(father)) depth +=1;
961 if (father->getNumId() == _root->getNumId()) break;
962 father = father->getFather();
967 SchemaSave::SchemaSave(Proc* proc): _p(proc)
972 void SchemaSave::save(std::string xmlSchemaFile)
974 VisitorSaveSchema vss(_p);
975 vss.openFileSchema(xmlSchemaFile);
977 vss.closeFileSchema();