1 // Copyright (C) 2006-2014 CEA/DEN, EDF 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, or (at your option) any later version.
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
21 #include "guiObservers.hxx"
22 #include "commandsProc.hxx"
24 #include "ComposedNode.hxx"
27 #include "ElementaryNode.hxx"
28 #include "InlineNode.hxx"
29 #include "ServiceNode.hxx"
30 #include "PythonNode.hxx"
31 #include "CORBANode.hxx"
32 #include "CppNode.hxx"
33 #include "XMLNode.hxx"
34 #include "SalomePythonNode.hxx"
35 #include "DataNode.hxx"
36 #include "PresetNode.hxx"
37 #include "OutNode.hxx"
38 #include "StudyNodes.hxx"
39 #include "ForLoop.hxx"
40 #include "ForEachLoop.hxx"
41 #include "WhileLoop.hxx"
43 #include "OptimizerLoop.hxx"
44 #include "InputPort.hxx"
45 #include "OutputPort.hxx"
46 #include "InputDataStreamPort.hxx"
47 #include "OutputDataStreamPort.hxx"
48 #include "SalomeContainer.hxx"
49 #include "SalomeComponent.hxx"
50 #include "ComponentDefinition.hxx"
51 #include "TypeCode.hxx"
52 #include "RuntimeSALOME.hxx"
54 #include "guiContext.hxx"
61 #include "YacsTrace.hxx"
66 using namespace YACS::HMI;
67 using namespace YACS::ENGINE;
69 std::map<int, std::string> GuiObserver::_eventNameMap;
71 // ----------------------------------------------------------------------------
73 void Subject::erase(Subject* sub, Command *command, bool post)
75 Subject* parent =sub->getParent();
78 if (!post) // --- avoid recursion in erase, see cleanPostErase
79 GuiContext::getCurrent()->getSubjectProc()->cleanPostErase();
82 // ----------------------------------------------------------------------------
84 Subject::Subject(Subject *parent) : _parent(parent)
87 _askRegisterUndo = false;
91 * Destructor must only be called by Subject::erase to clean
92 * completely the context (detach observers), before the delete
93 * process itself. Some actions involving dynamic_cast can't be done
98 DEBTRACE("Subject::~Subject " << this << " "<< getName());
102 * Clean process prior to delete is redefined in derived classes: a local clean
103 * treatment relative to the derived class, then a call to the parent class clean
106 void Subject::clean(Command *command)
112 * the local clean method of base class of subjects take care of Observers.
113 * Remaining Observers in the list are detached, if an observer has no more
114 * Subject to observe, it can be deleted.
116 void Subject::localclean(Command *command)
118 DEBTRACE("Subject::localClean ");
119 set<GuiObserver*>::iterator it;
120 while (int nbObs = _setObs.size())
122 DEBTRACE("--- " << this << " nbObs " << nbObs);
123 set<GuiObserver*> copySet = _setObs;
124 for (it = copySet.begin(); it != copySet.end(); ++it)
126 GuiObserver* anObs = (*it);
128 int nbsub = anObs->getNbSubjects();
129 DEBTRACE("nbSubjects=" << nbsub << " obs=" << anObs);
130 if (nbsub <= 0 && anObs->isDestructible())
133 break; // --- each delete may induce remove of other observers
140 void Subject::registerUndoDestroy()
142 DEBTRACE("Subject::registerUndoDestroy");
145 void Subject::attach(GuiObserver *obs)
147 DEBTRACE("Subject::attach " << obs);
149 obs->incrementSubjects(this);
152 void Subject::detach(GuiObserver *obs)
154 DEBTRACE("Subject::detach " << obs);
155 obs->decrementSubjects(this);
159 std::string Subject::getName()
164 bool Subject::setName(std::string name)
169 std::map<std::string, std::string> Subject::getProperties()
171 std::map<std::string, std::string> empty;
175 bool Subject::setProperties(std::map<std::string, std::string> properties)
180 std::vector<std::string> Subject::knownProperties()
182 std::vector<std::string> empty;
186 void Subject::select(bool isSelected)
188 DEBTRACE("Subject::select " << isSelected << " " << this);
189 set<GuiObserver*> copySet = _setObs;
190 for (set<GuiObserver *>::iterator it = copySet.begin(); it != copySet.end(); ++it)
192 GuiObserver* currOb = *it;
193 currOb->select(isSelected);
197 void Subject::update(GuiEvent event,int type, Subject* son)
199 //DEBTRACE("Subject::update " << type << "," << GuiObserver::eventName(event) << "," << son);
200 set<GuiObserver*> copySet = _setObs;
201 for (set<GuiObserver *>::iterator it = copySet.begin(); it != copySet.end(); ++it)
203 //DEBTRACE("Subject::update " << *it);
206 (*it)->update(event, type, son);
210 std::cerr << "Internal error in Subject::update: " << ex.what() << std::endl;
214 std::cerr << "Internal error in Subject::update: " << std::endl;
219 Subject* Subject::getParent()
224 void Subject::setParent(Subject* son)
229 //! From user action in Ihm, destroy an object
231 * Called from GuiEditor::DeleteSubject(parent, toRemove).
232 * The subject (this) is the parent of the subject (son) to remove.
233 * Son must represent a Node, a DataPort, a Link or a ControlLink.
234 * All other objects can only be destroyed automatically, not via an user command.
235 * Only the destruction originated from user, using this method, are registered for undo-redo.
237 bool Subject::destroy(Subject *son)
239 string toDestroy = son->getName();
240 DEBTRACE("Subject::destroy " << toDestroy);
241 Proc *proc = GuiContext::getCurrent()->getProc();
242 string startnode = "";
244 string startport = "";
246 TypeOfElem startportType = UNKNOWN;
247 TypeOfElem endportType = UNKNOWN;
249 if (dynamic_cast<SubjectProc*>(son))
250 startnode = proc->getName();
253 if (SubjectNode *subNode = dynamic_cast<SubjectNode*>(son))
255 if (subNode->getNode()->getFather() )
256 startnode = proc->getChildName(subNode->getNode());
258 else if (dynamic_cast<SubjectDataPort*>(son))
260 SubjectNode *subNodep = dynamic_cast<SubjectNode*>(son->getParent());
261 startnode = proc->getChildName(subNodep->getNode());
262 startport = son->getName();
263 startportType = son->getType();
265 else if (SubjectLink* slink = dynamic_cast<SubjectLink*>(son))
267 startnode = proc->getChildName(slink->getSubjectOutNode()->getNode());
268 endnode = proc->getChildName(slink->getSubjectInNode()->getNode());
269 startport = slink->getSubjectOutPort()->getName();
270 endport = slink->getSubjectInPort()->getName();
271 startportType = slink->getSubjectOutPort()->getType();
272 endportType = slink->getSubjectInPort()->getType();
274 else if (SubjectControlLink* sclink = dynamic_cast<SubjectControlLink*>(son))
276 startnode = proc->getChildName(sclink->getSubjectOutNode()->getNode());
277 endnode = proc->getChildName(sclink->getSubjectInNode()->getNode());
279 else if (SubjectContainer* scont = dynamic_cast<SubjectContainer*>(son))
281 if(scont->getName() == "DefaultContainer")
283 GuiContext::getCurrent()->_lastErrorMessage = "You can't delete the default container";
288 GuiContext::getCurrent()->_lastErrorMessage = "You can't delete a container that contains components";
291 startnode = scont->getName();
295 GuiContext::getCurrent()->_lastErrorMessage = "No command Destroy for that type";
299 if (son->isDestructible())
301 CommandDestroy* command = new CommandDestroy(son->getType(), startnode, startport, startportType, endnode, endport, endportType);
302 if (command->execute())
304 DEBTRACE("Destruction done: " << toDestroy);
305 GuiContext::getCurrent()->getInvoc()->add(command);
313 void Subject::loadChildren()
317 void Subject::loadLinks()
321 void Subject::addSubjectReference(Subject *ref)
323 DEBTRACE("Subject::addSubjectReference " << getName() << " " << ref->getName());
324 SubjectReference *son = new SubjectReference(ref, this);
325 update(ADDREF, 0, son);
328 void Subject::setProgress( std::string newProgress )
330 _progress = newProgress;
333 // ----------------------------------------------------------------------------
335 GuiObserver::GuiObserver()
336 : _destructible(true)
338 //DEBTRACE("GuiObserver::GuiObserver " << this);
342 GuiObserver::~GuiObserver()
344 DEBTRACE("GuiObserver::~GuiObserver " << this);
345 set<Subject*> subsetcpy = _subjectSet;
346 set<Subject*>::iterator it= subsetcpy.begin();
347 for (; it != subsetcpy.end(); ++it)
351 void GuiObserver::select(bool isSelected)
353 DEBTRACE("GuiObserver::select() " << isSelected);
356 void GuiObserver::update(GuiEvent event, int type, Subject* son)
358 //DEBTRACE("GuiObserver::update, event not handled " << eventName(event) << " " << type );
362 * only called by subject when attach to subject.
363 * @see Subject::attach
365 void GuiObserver::incrementSubjects(Subject *subject)
367 if (_subjectSet.count(subject))
368 DEBTRACE("subject " << subject << " is already a subject of observer " << this << "---------------------------");
369 _subjectSet.insert(subject);
370 //DEBTRACE(this << " " << _subjectSet.size());
374 * only called by subject when detach from subject.
375 * @see Subject::detach
377 void GuiObserver::decrementSubjects(Subject *subject)
379 if (_subjectSet.count(subject))
380 _subjectSet.erase(subject);
382 DEBTRACE("subject " << subject << " is not a subject of observer " << this << "---------------------------");
383 //DEBTRACE(this << " " << _subjectSet.size());
387 * Gets the number of subjects observed.
388 * used by subject. When the subject is erased (Subject::erase),
389 * remaining observers are detached from subjects. If an observer has no
390 * more subject, it can be deleted.
391 * @see Subject::erase Subject::localClean
393 int GuiObserver::getNbSubjects()
395 return _subjectSet.size();
398 void GuiObserver::setEventMap()
400 _eventNameMap.clear();
401 _eventNameMap[ADD] = "ADD";
402 _eventNameMap[REMOVE] = "REMOVE";
403 _eventNameMap[CUT] = "CUT";
404 _eventNameMap[PASTE] = "PASTE";
405 _eventNameMap[ORDER] = "ORDER";
406 _eventNameMap[EDIT] = "EDIT";
407 _eventNameMap[UPDATE] = "UPDATE";
408 _eventNameMap[UPDATEPROGRESS] = "UPDATEPROGRESS";
409 _eventNameMap[SYNCHRO] = "SYNCHRO";
410 _eventNameMap[UP] = "UP";
411 _eventNameMap[DOWN] = "DOWN";
412 _eventNameMap[RENAME] = "RENAME";
413 _eventNameMap[NEWROOT] = "NEWROOT";
414 _eventNameMap[ENDLOAD] = "ENDLOAD";
415 _eventNameMap[ADDLINK] = "ADDLINK";
416 _eventNameMap[ADDCONTROLLINK] = "ADDCONTROLLINK";
417 _eventNameMap[ADDREF] = "ADDREF";
418 _eventNameMap[ADDCHILDREF] = "ADDCHILDREF";
419 _eventNameMap[REMOVECHILDREF] = "REMOVECHILDREF";
420 _eventNameMap[ASSOCIATE] = "ASSOCIATE";
421 _eventNameMap[SETVALUE] = "SETVALUE";
422 _eventNameMap[SETCASE] = "SETCASE";
423 _eventNameMap[SETSELECT] = "SETSELECT";
424 _eventNameMap[GEOMETRY] = "GEOMETRY";
427 std::string GuiObserver::eventName(GuiEvent event)
429 if (_eventNameMap.count(event))
430 return _eventNameMap[event];
431 else return "Unknown Event";
434 // ----------------------------------------------------------------------------
436 SubjectObserver::SubjectObserver(Subject* ref):_reference(ref)
439 SubjectObserver::~SubjectObserver()
442 void SubjectObserver::select(bool isSelected)
444 DEBTRACE("SubjectObserver::select " << isSelected);
447 void SubjectObserver::update(GuiEvent event, int type, Subject* son)
449 DEBTRACE("SubjectObserver::update " << type << "," << eventName(event) << "," << son);
450 //propagate only RENAME events
452 _reference->update(event,type,son);
455 SubjectReference::SubjectReference(Subject* ref, Subject *parent)
456 : Subject(parent), _reference(ref)
458 _sobs=new SubjectObserver(this);
462 SubjectReference::~SubjectReference()
467 void SubjectReference::clean(Command *command)
469 if (_askRegisterUndo)
471 _askRegisterUndo = false;
472 registerUndoDestroy();
475 Subject::clean(command);
478 void SubjectReference::localclean(Command *command)
480 DEBTRACE("SubjectReference::localClean ");
483 std::string SubjectReference::getName()
485 std::stringstream name;
486 name << "ref-->" << _reference->getName();
490 Subject* SubjectReference::getReference() const
495 void SubjectReference::reparent(Subject *parent)
500 // ----------------------------------------------------------------------------
502 SubjectNode::SubjectNode(YACS::ENGINE::Node *node, Subject *parent)
503 : Subject(parent), _node(node)
505 _listSubjectInputPort.clear();
506 _listSubjectOutputPort.clear();
507 _listSubjectIDSPort.clear();
508 _listSubjectODSPort.clear();
509 _listSubjectLink.clear();
510 _listSubjectControlLink.clear();
511 _execState = YACS::UNDEFINED;
512 Dispatcher* d=Dispatcher::getDispatcher();
513 d->addObserver(this,node,"status");
517 * all destruction is done in generic class SubjectNode
519 SubjectNode::~SubjectNode()
521 DEBTRACE("SubjectNode::~SubjectNode " << getName());
522 Dispatcher::getDispatcher()->removeObserver(this,_node,"status");
524 ComposedNode* father = _node->getFather();
525 GuiContext::getCurrent()->_mapOfSubjectNode.erase(_node);
529 // Remove child except if it's the splitter node of a ForEachLoop
530 if (dynamic_cast<ForEachLoop*>(father) == NULL ||
531 getName() != ForEachLoop::NAME_OF_SPLITTERNODE)
533 father->edRemoveChild(_node);
536 catch (YACS::Exception &e)
538 DEBTRACE("------------------------------------------------------------------------------");
539 DEBTRACE("SubjectNode::localClean: father->edRemoveChild: YACS exception " << e.what());
540 DEBTRACE("------------------------------------------------------------------------------");
544 void SubjectNode::clean(Command *command)
546 if (_askRegisterUndo)
548 _askRegisterUndo = false;
549 registerUndoDestroy();
552 Subject::clean(command);
555 void SubjectNode::localclean(Command *command)
557 DEBTRACE("SubjectNode::localClean ");
558 removeExternalLinks();
560 list<SubjectLink*>::iterator its;
561 list<SubjectLink*> cpll = _listSubjectLink;
562 for (its = cpll.begin(); its != cpll.end(); ++its)
566 list<SubjectControlLink*>::iterator its;
567 list<SubjectControlLink*> cplcl = _listSubjectControlLink;
568 for (its = cplcl.begin(); its != cplcl.end(); ++its)
572 list<SubjectInputPort*>::iterator iti;
573 list<SubjectInputPort*> cpli = _listSubjectInputPort;
574 for(iti = cpli.begin(); iti != cpli.end(); ++iti)
578 list<SubjectOutputPort*>::iterator ito;
579 list<SubjectOutputPort*> cplo = _listSubjectOutputPort;
580 for(ito = cplo.begin(); ito != cplo.end(); ++ito)
584 list<SubjectInputDataStreamPort*>::iterator itid;
585 list<SubjectInputDataStreamPort*> cplid = _listSubjectIDSPort;
586 for(itid = cplid.begin(); itid != cplid.end(); ++itid)
590 list<SubjectOutputDataStreamPort*>::iterator itod;
591 list<SubjectOutputDataStreamPort*> cplod = _listSubjectODSPort;
592 for(itod = cplod.begin(); itod != cplod.end(); ++itod)
597 if( SubjectBloc* sb = dynamic_cast<SubjectBloc*>(_parent) )
598 sb->removeNode(this);
599 else if( SubjectForLoop* sfl = dynamic_cast<SubjectForLoop*>(_parent) )
600 sfl->completeChildrenSubjectList( 0 );
601 else if( SubjectWhileLoop* swl = dynamic_cast<SubjectWhileLoop*>(_parent) )
602 swl->completeChildrenSubjectList( 0 );
603 else if( SubjectDynParaLoop* sdpl = dynamic_cast<SubjectDynParaLoop*>(_parent) )
604 sdpl->removeNode(this);
605 else if( SubjectSwitch* ss = dynamic_cast<SubjectSwitch*>(_parent) )
606 ss->removeNode(this);
610 void SubjectNode::registerUndoDestroy()
612 DEBTRACE("SubjectNode::registerUndoDestroy " << getName());
614 Proc *undoProc = GuiContext::getCurrent()->getInvoc()->getUndoProc();
615 ComposedNode *oldFather = _node->getFather();
617 // --- clone the node in undoProc
619 ostringstream blocName;
620 blocName << "undoBloc_" << Invocator::_ctr++;
621 Bloc *undoBloc = new Bloc(blocName.str());
622 undoProc->edAddChild(undoBloc);
623 ComposedNode *newFather = undoBloc;
624 Node *clone = _node->clone(0);
625 newFather->edAddChild(clone);
627 // --- register a CommandCopyNode from undoProc
629 Proc *proc = GuiContext::getCurrent()->getProc();
630 string position = proc->getName();
631 if (proc != dynamic_cast<Proc*>(_node->getFather())) position = proc->getChildName(_node->getFather());
634 if (Switch* aswitch = dynamic_cast<Switch*>(_node->getFather()))
636 //the node is in a switch, save the case
637 swCase=aswitch->getRankOfNode(_node);
640 CommandCopyNode *command = new CommandCopyNode(undoProc,
641 undoProc->getChildName(clone),
643 GuiContext::getCurrent()->getInvoc()->add(command);
645 // --- identify all the children service node
647 list<ServiceNode*> serviceList;
649 ServiceNode *service = 0;
650 ComposedNode *cnode = 0;
651 if (service = dynamic_cast<ServiceNode*>(_node))
652 serviceList.push_back(service);
654 cnode = dynamic_cast<ComposedNode*>(_node);
657 list<Node*> children = cnode->getAllRecursiveNodes();
658 list<Node*>::iterator it = children.begin();
659 for (; it != children.end(); ++it)
660 if (service = dynamic_cast<ServiceNode*>(*it))
661 serviceList.push_back(service);
664 // --- for all the children service node, find the componentInstance,
665 // see if the componentInstance has other services that will stay alive after the destroy
666 // if not, register a CommandAddComponentInstance
669 list<ServiceNode*>::const_iterator ita = serviceList.begin();
670 for (; ita != serviceList.end(); ++ita)
672 bool instanceUsedOutside = false;
674 ComponentInstance *compo = service->getComponent();
676 YASSERT(GuiContext::getCurrent()->_mapOfSubjectComponent.count(compo));
677 SubjectComponent *scomp = GuiContext::getCurrent()->_mapOfSubjectComponent[compo];
678 //list<ServiceNode*> compServiceSet;
679 set<SubjectServiceNode*>::const_iterator itset = scomp->_subServiceSet.begin();
680 for (; itset != scomp->_subServiceSet.end(); ++itset)
682 ServiceNode *sn = dynamic_cast<ServiceNode*>((*itset)->getNode());
683 if (sn && (sn != service))
685 //compServiceSet.push_back(sn);
686 instanceUsedOutside = true;
687 list<ServiceNode*>::const_iterator itb = serviceList.begin();
688 for (; itb != serviceList.end(); ++itb)
692 instanceUsedOutside = false;
696 if (instanceUsedOutside)
701 string instanceName = compo->getInstanceName();
702 if (!instanceUsedOutside)
704 string compoName = compo->getCompoName();
705 string containerName = compo->getContainer()->getName();
706 CommandAddComponentInstance *comaci = new CommandAddComponentInstance(compoName, containerName, instanceName);
707 GuiContext::getCurrent()->getInvoc()->add(comaci);
710 string servicePos = proc->getChildName(service);
711 CommandAssociateServiceToComponent *comastc = new CommandAssociateServiceToComponent(servicePos,
713 GuiContext::getCurrent()->getInvoc()->add(comastc);
716 // --- explore all the external links and register commands for recreation
718 vector<pair<OutPort *, InPort *> > listLeaving = getNode()->getSetOfLinksLeavingCurrentScope();
719 vector<pair<InPort *, OutPort *> > listIncoming = getNode()->getSetOfLinksComingInCurrentScope();
720 vector<pair<OutPort *, InPort *> > globalList = listLeaving;
721 vector<pair<InPort *, OutPort *> >::iterator it1;
722 for (it1 = listIncoming.begin(); it1 != listIncoming.end(); ++it1)
724 pair<OutPort *, InPort *> outin = pair<OutPort *, InPort *>((*it1).second, (*it1).first);
725 globalList.push_back(outin);
727 vector<pair<OutPort *, InPort *> >::iterator it2;
728 for (it2 = globalList.begin(); it2 != globalList.end(); ++it2)
730 SubjectLink* subject = 0;
731 if (GuiContext::getCurrent()->_mapOfSubjectLink.count(*it2))
733 subject = GuiContext::getCurrent()->_mapOfSubjectLink[*it2];
735 DEBTRACE("register undo destroy link " << subject->getName());
736 subject->registerUndoDestroy();
740 // --- explore all the external control links and register commands for recreation
742 list<SubjectControlLink*> cplcl = getSubjectControlLinks();
743 list<SubjectControlLink*>::iterator its;
744 Node* node = getNode();
745 for (its = cplcl.begin(); its != cplcl.end(); ++its)
748 Node *nout = (*its)->getSubjectOutNode()->getNode();
749 Node *nin = (*its)->getSubjectInNode()->getNode();
750 inside = inside && (node == nout);
751 inside = inside && (node == nin);
754 (*its)->registerUndoDestroy();
759 bool SubjectNode::reparent(Subject* parent)
761 DEBTRACE("SubjectNode::reparent");
762 Subject *sub = getParent(); // --- old parent subject
763 SubjectComposedNode *sop = dynamic_cast<SubjectComposedNode*>(sub);
765 SubjectComposedNode *snp = dynamic_cast<SubjectComposedNode*>(parent); // --- new parent subject
768 GuiContext::getCurrent()->_lastErrorMessage = "new parent must be a composed node";
769 DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
772 ComposedNode *cnp = dynamic_cast<ComposedNode*>(snp->getNode());
774 Proc *proc = GuiContext::getCurrent()->getProc();
775 Proc *fromproc=_node->getProc();
778 GuiContext::getCurrent()->_lastErrorMessage = "cut is not yet possible across procs";
779 DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
783 string position = "";
784 if (proc != dynamic_cast<Proc*>(_node))
785 position = proc->getChildName(_node);
787 position = _node->getName();
789 string newParent = "";
790 if (proc != dynamic_cast<Proc*>(cnp))
791 newParent = proc->getChildName(cnp);
793 newParent = cnp->getName();
795 CommandReparentNode *command = new CommandReparentNode(position, newParent);
796 if (command->execute())
798 GuiContext::getCurrent()->getInvoc()->add(command);
802 DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
806 void SubjectNode::recursiveUpdate(GuiEvent event, int type, Subject* son)
808 update(event, type, son);
811 bool SubjectNode::copy(Subject* parent)
813 DEBTRACE("SubjectNode::copy");
814 Subject *sop = getParent(); // --- old parent subject
815 SubjectComposedNode *snp = dynamic_cast<SubjectComposedNode*>(parent); // --- new parent subject
818 GuiContext::getCurrent()->_lastErrorMessage = "new parent must be a composed node";
819 DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
822 ComposedNode *cnp = dynamic_cast<ComposedNode*>(snp->getNode());
824 Proc *proc = GuiContext::getCurrent()->getProc();
825 Proc *fromproc=_node->getProc();
827 string position = "";
828 if (fromproc != dynamic_cast<Proc*>(_node))
829 position = fromproc->getChildName(_node);
831 position = _node->getName();
833 string newParent = "";
834 if (proc != dynamic_cast<Proc*>(cnp))
835 newParent = proc->getChildName(cnp);
837 newParent = cnp->getName();
839 CommandCopyNode *command = new CommandCopyNode(fromproc, position, newParent);
840 if (command->execute())
842 GuiContext::getCurrent()->getInvoc()->add(command);
846 DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
851 std::string SubjectNode::getName()
853 return _node->getName();
856 YACS::ENGINE::Node* SubjectNode::getNode()
861 int SubjectNode::isValid()
863 return _node->isValid();
866 bool SubjectNode::setName(std::string name)
868 DEBTRACE("SubjectNode::setName " << name);
869 Proc *proc = GuiContext::getCurrent()->getProc();
870 string position = "";
871 if (proc != dynamic_cast<Proc*>(_node))
872 position = proc->getChildName(_node);
874 position = _node->getName();
875 CommandRenameNode* command = new CommandRenameNode(position, name);
876 if (command->execute())
878 GuiContext::getCurrent()->getInvoc()->add(command);
885 void SubjectNode::notifyObserver(Node* object,const std::string& event)
887 DEBTRACE("SubjectNode::notifyObserver " << object->getName() << " " << event);
888 TypeOfElem ntyp = ProcInvoc::getTypeOfNode(object);
889 update(UPDATE, ntyp , 0 );
892 void SubjectNode::saveLinks()
894 DEBTRACE("SubjectNode::saveLinks");
895 loutgate= _node->getInGate()->getBackLinks();
896 singate= _node->getOutGate()->edSetInGate();
897 std::list<OutGate *>::const_iterator ito;
898 for(ito=loutgate.begin();ito != loutgate.end();ito++)
900 Node* n1=(*ito)->getNode();
902 DEBTRACE(n1->getName()<< " " << n2->getName());
904 std::set<InGate *>::const_iterator iti;
905 for(iti=singate.begin();iti != singate.end();iti++)
908 Node* n2=(*iti)->getNode();
909 DEBTRACE(n1->getName()<< " " << n2->getName());
913 dataflowLinks.clear();
915 std::vector< std::pair<OutPort *, InPort *> > listLeaving = getNode()->getSetOfLinksLeavingCurrentScope();
916 std::vector< std::pair<OutPort *, InPort *> >::iterator it3;
917 for (it3 = listLeaving.begin(); it3 != listLeaving.end(); ++it3)
919 OutPort* p1=(*it3).first;
920 InPort* p2=(*it3).second;
921 Node* n1=p1->getNode();
922 Node* n2=p2->getNode();
923 //are nodes in sequence (control link direct or indirect) ?
924 ComposedNode* fath= ComposedNode::getLowestCommonAncestor(n1,n2);
925 if(n1 == fath ||n2 == fath)
927 //consider it as a data only link
928 DEBTRACE("It's a data link: " << n1->getName() << "." << p1->getName() << " -> "<< n2->getName() << "." << p2->getName());
929 dataLinks.push_back(std::pair<OutPort *, InPort *>(p1,p2));
932 while(n1->getFather() != fath) n1=n1->getFather();
933 while(n2->getFather() != fath) n2=n2->getFather();
934 OutGate* outg=n1->getOutGate();
935 if(!outg->isAlreadyInSet(n2->getInGate()))
937 DEBTRACE("It's a data link: "<<p1->getNode()->getName()<<"."<<p1->getName()<<" -> "<< p2->getNode()->getName()<<"."<<p2->getName());
938 dataLinks.push_back(std::pair<OutPort *, InPort *>(p1,p2));
942 DEBTRACE("It's a dataflow link: "<<p1->getNode()->getName()<<"."<<p1->getName()<<" -> "<< p2->getNode()->getName()<<"."<<p2->getName());
943 dataflowLinks.push_back(std::pair<OutPort *, InPort *>(p1,p2));
947 std::vector< std::pair<InPort *, OutPort *> > listIncoming = getNode()->getSetOfLinksComingInCurrentScope();
948 std::vector< std::pair<InPort *, OutPort *> >::iterator it4;
949 for (it4 = listIncoming.begin(); it4 != listIncoming.end(); ++it4)
951 OutPort* p1=(*it4).second;
952 InPort* p2=(*it4).first;
953 Node* n1=p1->getNode();
954 Node* n2=p2->getNode();
955 //are nodes in sequence (control link direct or indirect) ?
956 ComposedNode* fath= ComposedNode::getLowestCommonAncestor(n1,n2);
957 if(n1 == fath ||n2 == fath)
959 //consider it as a data only link
960 DEBTRACE("It's a data link: " << n1->getName() << "." << p1->getName() << " -> "<< n2->getName() << "." << p2->getName());
961 dataLinks.push_back(std::pair<OutPort *, InPort *>(p1,p2));
964 while(n1->getFather() != fath) n1=n1->getFather();
965 while(n2->getFather() != fath) n2=n2->getFather();
966 OutGate* outg=n1->getOutGate();
967 if(!outg->isAlreadyInSet(n2->getInGate()))
969 DEBTRACE("It's a data link: "<<p1->getNode()->getName()<<"."<<p1->getName()<<" -> "<< p2->getNode()->getName()<<"."<<p2->getName());
970 dataLinks.push_back(std::pair<OutPort *, InPort *>(p1,p2));
974 DEBTRACE("It's a dataflow link: "<<p1->getNode()->getName()<<"."<<p1->getName()<<" -> "<< p2->getNode()->getName()<<"."<<p2->getName());
975 dataflowLinks.push_back(std::pair<OutPort *, InPort *>(p1,p2));
980 void SubjectNode::restoreLinks()
982 DEBTRACE("SubjectNode::restoreLinks");
983 //restore simple data links
984 std::vector< std::pair<OutPort *, InPort *> >::iterator it3;
985 for (it3 = dataLinks.begin(); it3 != dataLinks.end(); ++it3)
987 OutPort* p1=(*it3).first;
988 InPort* p2=(*it3).second;
989 Node* n1=p1->getNode();
990 Node* n2=p2->getNode();
991 ComposedNode* fath= ComposedNode::getLowestCommonAncestor(n1,n2);
994 fath->edAddLink(p1,p2);
998 // if a link can't be restored ignore it. It's possible when a node is reparented to a foreachloop
1001 SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(GuiContext::getCurrent()->_mapOfSubjectNode[fath]);
1002 SubjectNode *sno = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(n1)];
1003 SubjectNode *sni = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(n2)];
1004 SubjectDataPort *spo = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(p1)];
1005 SubjectDataPort *spi = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(p2)];
1006 scla->addSubjectLink(sno,spo,sni,spi);
1008 //restore dataflow links
1009 for (it3 = dataflowLinks.begin(); it3 != dataflowLinks.end(); ++it3)
1011 OutPort* p1=(*it3).first;
1012 InPort* p2=(*it3).second;
1013 Node* n1=p1->getNode();
1014 Node* n2=p2->getNode();
1015 ComposedNode* fath= ComposedNode::getLowestCommonAncestor(n1,n2);
1018 fath->edAddDFLink(p1,p2);
1020 catch(Exception& ex)
1022 // if a link can't be restored ignore it. It's possible when a node is reparented to a foreachloop
1025 SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(GuiContext::getCurrent()->_mapOfSubjectNode[fath]);
1026 SubjectNode *sno = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(n1)];
1027 SubjectNode *sni = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(n2)];
1028 SubjectDataPort *spo = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(p1)];
1029 SubjectDataPort *spi = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(p2)];
1030 scla->addSubjectLink(sno,spo,sni,spi);
1031 if(n1==fath || n2==fath) continue;
1032 while(n1->getFather() != fath) n1=n1->getFather();
1033 while(n2->getFather() != fath) n2=n2->getFather();
1034 OutGate *ogate = n1->getOutGate();
1035 InGate *igate = n2->getInGate();
1036 if (ogate->isAlreadyInSet(igate))
1038 pair<Node*,Node*> keyLink(n1,n2);
1039 if (!GuiContext::getCurrent()->_mapOfSubjectControlLink.count(keyLink))
1041 SubjectNode *sfno = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(n1)];
1042 SubjectNode *sfni = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(n2)];
1043 scla->addSubjectControlLink(sfno, sfni);
1048 //reconnect control links
1049 // links from another node to this node
1050 std::list<OutGate *>::const_iterator it;
1051 for(it=loutgate.begin();it != loutgate.end();it++)
1053 Node* n1=(*it)->getNode();
1055 if(GuiContext::getCurrent()->_mapOfSubjectNode.count(n1)==0)
1057 //It's an internal node or a destroyed one : don't treat it
1060 ComposedNode* fath= ComposedNode::getLowestCommonAncestor(n1,n2);
1061 if(n1 == fath)continue;
1062 if(n2 == fath)continue;
1063 //add a control link only if nodes are not in the same descendance
1064 while(n1->getFather() != fath) n1=n1->getFather();
1065 while(n2->getFather() != fath) n2=n2->getFather();
1066 OutGate *ogate = n1->getOutGate();
1067 InGate *igate = n2->getInGate();
1068 if (!ogate->isAlreadyInSet(igate))
1070 fath->edAddCFLink(n1,n2);
1071 SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(GuiContext::getCurrent()->_mapOfSubjectNode[fath]);
1072 SubjectNode * subOutNode = GuiContext::getCurrent()->_mapOfSubjectNode[n1];
1073 SubjectNode * subInNode = GuiContext::getCurrent()->_mapOfSubjectNode[n2];
1074 scla->addSubjectControlLink(subOutNode,subInNode);
1078 std::set<InGate *>::const_iterator it2;
1079 for(it2=singate.begin();it2 != singate.end();it2++)
1082 Node* n2=(*it2)->getNode();
1083 if(GuiContext::getCurrent()->_mapOfSubjectNode.count(n2)==0)
1085 //It's an internal node or a destroyed one : don't treat it
1088 ComposedNode* fath= ComposedNode::getLowestCommonAncestor(n1,n2);
1089 if(n1 == fath)continue;
1090 if(n2 == fath)continue;
1091 //add a control link only if nodes are not in the same descendance
1092 while(n1->getFather() != fath) n1=n1->getFather();
1093 while(n2->getFather() != fath) n2=n2->getFather();
1094 OutGate *ogate = n1->getOutGate();
1095 InGate *igate = n2->getInGate();
1096 if (!ogate->isAlreadyInSet(igate))
1098 fath->edAddCFLink(n1,n2);
1099 SubjectComposedNode *scla = dynamic_cast<SubjectComposedNode*>(GuiContext::getCurrent()->_mapOfSubjectNode[fath]);
1100 SubjectNode * subOutNode = GuiContext::getCurrent()->_mapOfSubjectNode[n1];
1101 SubjectNode * subInNode = GuiContext::getCurrent()->_mapOfSubjectNode[n2];
1102 scla->addSubjectControlLink(subOutNode,subInNode);
1107 bool SubjectNode::putInComposedNode(std::string name,std::string type, bool toSaveRestoreLinks)
1109 Proc *proc = GuiContext::getCurrent()->getProc();
1110 string position = "";
1111 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1113 CommandPutInComposedNode *command = new CommandPutInComposedNode(position, name, type, toSaveRestoreLinks);
1114 if (command->execute())
1116 GuiContext::getCurrent()->getInvoc()->add(command);
1119 else delete command;
1120 DEBTRACE(GuiContext::getCurrent()->_lastErrorMessage);
1124 SubjectInputPort* SubjectNode::addSubjectInputPort(YACS::ENGINE::InputPort *port,
1127 string theName = name;
1128 if (name.empty()) theName =port->getName();
1129 DEBTRACE("SubjectNode::addSubjectInputPort "<< theName);
1130 SubjectInputPort *son = new SubjectInputPort(port, this);
1131 GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
1132 _listSubjectInputPort.push_back(son);
1133 if (!name.empty()) son->setName(name);
1134 update(ADD, INPUTPORT ,son);
1135 YACS::ENGINE::TypeCode *typcod = port->edGetType();
1136 if (!GuiContext::getCurrent()->getSubjectProc()->addComSubjectDataType(typcod, typcod->name()))
1137 GuiContext::getCurrent()->getSubjectProc()->addSubjectDataType(typcod, typcod->name()); // --- new type of forEachLoop
1141 void SubjectNode::update( GuiEvent event, int type, Subject* son )
1143 Subject::update( event, type, son );
1145 // remove subject data type if necessary
1146 YACS::HMI::SubjectDataPort* aSPort = dynamic_cast< YACS::HMI::SubjectDataPort* >( son );
1147 // if ( aSPort && event == REMOVE )
1149 // YACS::ENGINE::DataPort* aEPort = aSPort->getPort();
1152 // YACS::ENGINE::TypeCode* aTypeCode = aEPort->edGetType();
1154 // GuiContext::getCurrent()->getSubjectProc()->removeSubjectDataType( aTypeCode );
1159 void SubjectNode::setExecState(int execState)
1161 _execState = execState;
1162 update(YACS::HMI::UPDATEPROGRESS, _execState, this);
1165 SubjectOutputPort* SubjectNode::addSubjectOutputPort(YACS::ENGINE::OutputPort *port,
1168 string theName = name;
1169 if (name.empty()) theName =port->getName();
1170 DEBTRACE("SubjectNode::addSubjectOutputPort "<< theName);
1171 SubjectOutputPort *son = new SubjectOutputPort(port, this);
1172 GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
1173 _listSubjectOutputPort.push_back(son);
1174 if (!name.empty()) son->setName(name);
1175 update(ADD, OUTPUTPORT ,son);
1176 YACS::ENGINE::TypeCode *typcod = port->edGetType();
1177 GuiContext::getCurrent()->getSubjectProc()->addComSubjectDataType(typcod, typcod->name());
1181 SubjectInputDataStreamPort* SubjectNode::addSubjectIDSPort(YACS::ENGINE::InputDataStreamPort *port,
1184 string theName = name;
1185 if (name.empty()) theName =port->getName();
1186 DEBTRACE("SubjectNode::addSubjectIDSPort "<< theName);
1187 SubjectInputDataStreamPort *son = new SubjectInputDataStreamPort(port, this);
1188 GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
1189 _listSubjectIDSPort.push_back(son);
1190 if (!name.empty()) son->setName(name);
1191 update(ADD, INPUTDATASTREAMPORT ,son);
1192 YACS::ENGINE::TypeCode *typcod = port->edGetType();
1193 GuiContext::getCurrent()->getSubjectProc()->addComSubjectDataType(typcod, typcod->name());
1198 SubjectOutputDataStreamPort* SubjectNode::addSubjectODSPort(YACS::ENGINE::OutputDataStreamPort *port,
1201 string theName = name;
1202 if (name.empty()) theName =port->getName();
1203 DEBTRACE("SubjectNode::addSubjectODSPort "<< theName);
1204 SubjectOutputDataStreamPort *son = new SubjectOutputDataStreamPort(port, this);
1205 GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(port)] = son;
1206 _listSubjectODSPort.push_back(son);
1207 if (!name.empty()) son->setName(name);
1208 update(ADD, OUTPUTDATASTREAMPORT ,son);
1209 YACS::ENGINE::TypeCode *typcod = port->edGetType();
1210 GuiContext::getCurrent()->getSubjectProc()->addComSubjectDataType(typcod, typcod->name());
1214 bool SubjectNode::tryCreateLink(SubjectNode *subOutNode, SubjectNode *subInNode)
1216 DEBTRACE("SubjectNode::tryCreateLink " << subOutNode->getName() << " " << subInNode->getName());
1217 Proc *proc = GuiContext::getCurrent()->getProc();
1218 Node *outNode = subOutNode->getNode();
1219 string outNodePos = proc->getChildName(outNode);
1220 Node *inNode = subInNode->getNode();
1221 string inNodePos = proc->getChildName(inNode);
1222 CommandAddControlLink *command = new CommandAddControlLink(outNodePos, inNodePos);
1223 if (command->execute())
1225 GuiContext::getCurrent()->getInvoc()->add(command);
1235 void SubjectNode::removeExternalLinks()
1237 DEBTRACE("SubjectNode::removeExternalLinks " << getName());
1238 std::vector< std::pair<OutPort *, InPort *> > listLeaving = getNode()->getSetOfLinksLeavingCurrentScope();
1239 std::vector< std::pair<InPort *, OutPort *> > listIncoming = getNode()->getSetOfLinksComingInCurrentScope();
1240 std::vector< std::pair<OutPort *, InPort *> > globalList = listLeaving;
1241 std::vector< std::pair<InPort *, OutPort *> >::iterator it1;
1242 for (it1 = listIncoming.begin(); it1 != listIncoming.end(); ++it1)
1244 std::pair<OutPort *, InPort *> outin = std::pair<OutPort *, InPort *>((*it1).second, (*it1).first);
1245 globalList.push_back(outin);
1247 std::vector< std::pair<OutPort *, InPort *> >::iterator it2;
1248 for (it2 = globalList.begin(); it2 != globalList.end(); ++it2)
1250 SubjectLink* subject = 0;
1251 if (GuiContext::getCurrent()->_mapOfSubjectLink.count(*it2))
1253 subject = GuiContext::getCurrent()->_mapOfSubjectLink[*it2];
1255 DEBTRACE("link to remove " << subject->getName());
1257 GuiContext::getCurrent()->_mapOfSubjectLink.erase(*it2);
1261 DEBTRACE("------------------------------------------------------------------------------");
1262 DEBTRACE("SubjectNode::removeExternalLinks(): an external link not in map...");
1263 DEBTRACE("------------------------------------------------------------------------------");
1268 void SubjectNode::removeExternalControlLinks()
1270 DEBTRACE("SubjectNode::removeExternalControlLinks " << getName());
1271 list<SubjectControlLink*> cplcl = getSubjectControlLinks();
1272 list<SubjectControlLink*>::iterator its;
1273 Node* node = getNode();
1274 for (its = cplcl.begin(); its != cplcl.end(); ++its)
1277 Node *nout = (*its)->getSubjectOutNode()->getNode();
1278 Node *nin = (*its)->getSubjectInNode()->getNode();
1279 inside = inside && (node == nout);
1280 inside = inside && (node == nin);
1282 Subject::erase(*its);
1286 std::map<std::string, std::string> SubjectNode::getProperties()
1288 return _node->getPropertyMap();
1291 bool SubjectNode::setProperties(std::map<std::string, std::string> properties)
1293 Proc *proc = GuiContext::getCurrent()->getProc();
1294 string position = "";
1295 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1297 CommandSetNodeProperties *command = new CommandSetNodeProperties(position, properties);
1298 if (command->execute())
1300 GuiContext::getCurrent()->getInvoc()->add(command);
1303 else delete command;
1307 // ----------------------------------------------------------------------------
1309 SubjectComposedNode::SubjectComposedNode(YACS::ENGINE::ComposedNode *composedNode,
1311 : SubjectNode(composedNode, parent), _composedNode(composedNode)
1316 * all generic destruction is done in generic class SubjectNode
1318 SubjectComposedNode::~SubjectComposedNode()
1320 DEBTRACE("SubjectComposedNode::~SubjectComposedNode " << getName());
1323 void SubjectComposedNode::clean(Command *command)
1325 if (_askRegisterUndo)
1327 _askRegisterUndo = false;
1328 registerUndoDestroy();
1330 localclean(command);
1331 SubjectNode::clean(command);
1334 void SubjectComposedNode::localclean(Command *command)
1336 DEBTRACE("SubjectComposedNode::localClean ");
1339 SubjectNode* SubjectComposedNode::addNode(YACS::ENGINE::Catalog *catalog,
1345 DEBTRACE("SubjectComposedNode::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<")");
1346 SubjectNode* body = 0;
1347 GuiContext::getCurrent()->_lastErrorMessage = "YACS Internal Error: SubjectComposedNode::addNode";
1351 SubjectNode *SubjectComposedNode::createNode(YACS::ENGINE::Catalog *catalog,
1358 Proc *proc = GuiContext::getCurrent()->getProc();
1359 string position = "";
1360 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
1361 CommandAddNodeFromCatalog *command = new CommandAddNodeFromCatalog(catalog,
1368 if (command->execute())
1370 GuiContext::getCurrent()->getInvoc()->add(command);
1371 Node * node = command->getNode();
1372 return command->getSubjectNode();
1374 else delete command;
1378 SubjectNode *SubjectComposedNode::addSubjectNode(YACS::ENGINE::Node * node,
1380 YACS::ENGINE::Catalog *catalog,
1384 string theName = name;
1385 if (name.empty()) theName =node->getName();
1386 DEBTRACE("SubjectComposedNode::addSubjectNode "<< theName);
1387 TypeOfElem ntyp = ProcInvoc::getTypeOfNode(node);
1388 DEBTRACE("TypeOfNode: " << ntyp);
1389 SubjectNode *son = 0;
1393 son = new SubjectBloc(dynamic_cast<YACS::ENGINE::Bloc*>(node), this);
1396 son = new SubjectPythonNode(dynamic_cast<YACS::ENGINE::PythonNode*>(node), this);
1399 son = new SubjectPyFuncNode(dynamic_cast<YACS::ENGINE::PyFuncNode*>(node), this);
1402 son = new SubjectCORBANode(dynamic_cast<YACS::ENGINE::CORBANode*>(node), this);
1405 son = new SubjectCppNode(dynamic_cast<YACS::ENGINE::CppNode*>(node), this);
1408 son = new SubjectSalomeNode(dynamic_cast<YACS::ENGINE::SalomeNode*>(node), this);
1410 case SALOMEPYTHONNODE:
1411 son = new SubjectSalomePythonNode(dynamic_cast<YACS::ENGINE::SalomePythonNode*>(node), this);
1414 son = new SubjectXmlNode(dynamic_cast<YACS::ENGINE::XmlNode*>(node), this);
1417 son = new SubjectSplitterNode(dynamic_cast<YACS::ENGINE::SplitterNode*>(node), this);
1420 son = new SubjectPresetNode(dynamic_cast<YACS::ENGINE::PresetNode*>(node), this);
1423 son = new SubjectOutNode(dynamic_cast<YACS::ENGINE::OutNode*>(node), this);
1426 son = new SubjectStudyInNode(dynamic_cast<YACS::ENGINE::StudyInNode*>(node), this);
1429 son = new SubjectStudyOutNode(dynamic_cast<YACS::ENGINE::StudyOutNode*>(node), this);
1432 son = new SubjectForLoop(dynamic_cast<YACS::ENGINE::ForLoop*>(node), this);
1435 son = new SubjectWhileLoop(dynamic_cast<YACS::ENGINE::WhileLoop*>(node), this);
1438 son = new SubjectSwitch(dynamic_cast<YACS::ENGINE::Switch*>(node), this);
1441 son = new SubjectForEachLoop(dynamic_cast<YACS::ENGINE::ForEachLoop*>(node), this);
1444 son = new SubjectOptimizerLoop(dynamic_cast<YACS::ENGINE::OptimizerLoop*>(node), this);
1447 throw YACS::Exception("Not implemented");
1451 GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(node)] = son;
1452 GuiContext::getCurrent()->_mapOfExecSubjectNode[node->getNumId()] = son;
1453 if (!name.empty()) son->setName(name);
1454 completeChildrenSubjectList(son);
1455 update(ADD, ntyp ,son);
1456 if (SubjectServiceNode *service = dynamic_cast<SubjectServiceNode*>(son))
1457 if (catalog && !compo.empty() && !type.empty()) // --- clone from catalog: set component
1458 service->setComponentFromCatalog(catalog,compo,type);
1460 service->setComponent();
1464 void SubjectComposedNode::completeChildrenSubjectList(SubjectNode *son)
1468 void SubjectComposedNode::loadChildren()
1470 list<Node *> setOfNode= _composedNode->edGetDirectDescendants();
1471 if (ForEachLoop *feloop = dynamic_cast<ForEachLoop*>(_composedNode))
1473 Node *node2Insert=feloop->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
1474 if(find(setOfNode.begin(),setOfNode.end(),node2Insert)==setOfNode.end())
1475 setOfNode.push_back(node2Insert);
1477 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1481 SubjectNode * son = addSubjectNode(*iter);
1482 son->loadChildren();
1484 catch(YACS::Exception& ex)
1486 std::cerr << "Unknown type of node" << std::endl;
1489 list<InputPort*> listInputPorts = _composedNode->getLocalInputPorts();
1490 list<OutputPort*> listOutputPorts = _composedNode->getLocalOutputPorts();
1491 list<InputDataStreamPort*> listIDSPorts = _composedNode->getSetOfInputDataStreamPort();
1492 list<OutputDataStreamPort*> listODSPorts = _composedNode->getSetOfOutputDataStreamPort();
1493 list<InputPort*>::const_iterator iti;
1494 for (iti = listInputPorts.begin(); iti != listInputPorts.end(); ++iti)
1495 addSubjectInputPort(*iti);
1496 list<OutputPort*>::const_iterator ito;
1497 for (ito = listOutputPorts.begin(); ito != listOutputPorts.end(); ++ito)
1498 addSubjectOutputPort(*ito);
1501 SubjectLink* SubjectComposedNode::addSubjectLink(SubjectNode *sno,
1502 SubjectDataPort *spo,
1504 SubjectDataPort *spi)
1506 DEBTRACE("SubjectComposedNode::addSubjectLink");
1507 OutPort *outp = dynamic_cast<OutPort*>(spo->getPort());
1508 InPort *inp = dynamic_cast<InPort*>(spi->getPort());
1509 pair<OutPort*,InPort*> keyLink(outp,inp);
1510 //Don't create a new subject if it already exists
1511 if(GuiContext::getCurrent()->_mapOfSubjectLink.count(keyLink)!=0)
1512 return GuiContext::getCurrent()->_mapOfSubjectLink[keyLink];
1514 SubjectLink *son = new SubjectLink(sno, spo, sni, spi, this);
1515 GuiContext::getCurrent()->_mapOfSubjectLink[keyLink] = son;
1516 _listSubjectLink.push_back(son);
1517 spo->addSubjectLink(son);
1518 spi->addSubjectLink(son);
1519 update(ADDLINK, DATALINK, son);
1520 spi->update(UPDATE, DATALINK, spo);
1521 spo->update(UPDATE, DATALINK, spi);
1522 DEBTRACE("addSubjectLink: " << getName() << " " << son->getName());
1526 void SubjectComposedNode::removeLink(SubjectLink* link)
1528 DEBTRACE("removeLink: " << link->getName());
1530 OutPort *outp = dynamic_cast<OutPort*>(link->getSubjectOutPort()->getPort());
1531 InPort *inp = dynamic_cast<InPort*>(link->getSubjectInPort()->getPort());
1532 pair<OutPort*,InPort*> keyLink(outp,inp);
1533 if (GuiContext::getCurrent()->_mapOfSubjectLink.count(keyLink))
1535 DEBTRACE(outp->getName() << " " << inp->getName());
1536 GuiContext::getCurrent()->_mapOfSubjectLink.erase(keyLink);
1539 link->getSubjectOutPort()->removeSubjectLink(link);
1540 link->getSubjectInPort()->removeSubjectLink(link);
1541 _listSubjectLink.remove(link);
1544 SubjectControlLink* SubjectComposedNode::addSubjectControlLink(SubjectNode *sno,
1547 Node *outn = sno->getNode();
1548 Node *inn = sni->getNode();
1549 pair<Node*,Node*> keyLink(outn,inn);
1550 //Don't create a new subject if it already exists
1551 if(GuiContext::getCurrent()->_mapOfSubjectControlLink.count(keyLink)!=0)
1552 return GuiContext::getCurrent()->_mapOfSubjectControlLink[keyLink];
1554 SubjectControlLink *son = new SubjectControlLink(sno, sni, this);
1555 GuiContext::getCurrent()->_mapOfSubjectControlLink[keyLink] = son;
1556 _listSubjectControlLink.push_back(son);
1557 sno->addSubjectControlLink(son);
1558 sni->addSubjectControlLink(son);
1559 update(ADDCONTROLLINK, CONTROLLINK, son);
1560 DEBTRACE("addSubjectControlLink: " << getName() << " " << son->getName());
1564 void SubjectComposedNode::removeControlLink(SubjectControlLink* link)
1566 DEBTRACE("removeSubjectControlLink: " << getName());
1568 Node *outn = link->getSubjectOutNode()->getNode();
1569 Node *inn = link->getSubjectInNode()->getNode();
1570 pair<Node*,Node*> keyLink(outn,inn);
1571 if (GuiContext::getCurrent()->_mapOfSubjectControlLink.count(keyLink))
1573 DEBTRACE(outn->getName() << " " << inn->getName());
1574 GuiContext::getCurrent()->_mapOfSubjectControlLink.erase(keyLink);
1577 link->getSubjectOutNode()->removeSubjectControlLink(link);
1578 link->getSubjectInNode()->removeSubjectControlLink(link);
1579 _listSubjectControlLink.remove(link);
1582 void SubjectComposedNode::removeExternalControlLinks()
1584 DEBTRACE("SubjectComposedNode::removeExternalControlLinks " << getName());
1585 list<SubjectControlLink*> cplcl = getSubjectControlLinks();
1586 list<SubjectControlLink*>::iterator its;
1587 ComposedNode *cnode = dynamic_cast<ComposedNode*>(getNode());
1588 for (its = cplcl.begin(); its != cplcl.end(); ++its)
1591 Node *nout = (*its)->getSubjectOutNode()->getNode();
1592 Node *nin = (*its)->getSubjectInNode()->getNode();
1593 inside = inside && cnode->isInMyDescendance(nout); // --- 0 if nout is outside
1594 inside = inside && cnode->isInMyDescendance(nin); // --- 0 if nin is outside
1596 Subject::erase(*its);
1600 void SubjectComposedNode::houseKeepingAfterCutPaste(bool isCut, SubjectNode *son)
1605 * loadLinks is used when an existing scheme has been loaded in memory, to create gui representation.
1606 * Gui representation of links is done after node representation (loadChildren).
1607 * Proc is explored recursively to find the composedNodes and create the corresponding links
1608 * representation, from bottom to top.
1609 * For each composedNode, data links representation are created first and stored in a map to avoid
1610 * double representation. Then control links representation are created.
1612 void SubjectComposedNode::loadLinks()
1614 list<Node *> setOfNode= _composedNode->edGetDirectDescendants();
1615 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1617 ComposedNode *cnSon = dynamic_cast<ComposedNode*>(*iter);
1620 SubjectNode *subSon = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(*iter)];
1622 SubjectComposedNode *subCnSon = dynamic_cast<SubjectComposedNode*>(subSon);
1624 subCnSon->loadLinks();
1628 std::vector<std::pair<OutPort*,InPort*> > setOfLinks = _composedNode->getSetOfInternalLinks();
1629 std::vector<std::pair<OutPort*,InPort*> >::iterator itp;
1630 for (itp = setOfLinks.begin(); itp != setOfLinks.end(); ++itp)
1631 if (!GuiContext::getCurrent()->_mapOfSubjectLink.count(*itp))
1633 OutPort *outp = (*itp).first;
1634 InPort *inp = (*itp).second;
1635 Node *outn = outp->getNode();
1636 Node *inn = inp->getNode();
1637 DEBTRACE(outn->getName()<<"."<<outp->getName()<<"->"<<inn->getName()<<"."<<inp->getName());
1638 SubjectNode *sno = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(outn)];
1639 SubjectNode *sni = GuiContext::getCurrent()->_mapOfSubjectNode[static_cast<Node*>(inn)];
1640 SubjectDataPort *spo = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(outp)];
1641 SubjectDataPort *spi = GuiContext::getCurrent()->_mapOfSubjectDataPort[static_cast<DataPort*>(inp)];
1642 addSubjectLink(sno,spo,sni,spi);
1645 std::list<Node*> setOfNodes = _composedNode->edGetDirectDescendants();
1646 std::list<Node*>::const_iterator itn;
1647 for(itn = setOfNodes.begin(); itn != setOfNodes.end(); ++itn)
1649 SubjectNode* sno = GuiContext::getCurrent()->_mapOfSubjectNode[*itn];
1650 OutGate* outgate = (*itn)->getOutGate();
1651 std::set<InGate*> setIngate = outgate->edSetInGate();
1652 std::set<InGate*>::const_iterator itg;
1653 for(itg = setIngate.begin(); itg != setIngate.end(); ++itg)
1655 Node* inNode = (*itg)->getNode();
1656 SubjectNode* sni = GuiContext::getCurrent()->_mapOfSubjectNode[inNode];
1658 addSubjectControlLink(sno,sni);
1663 //! Retrieves the lowest common ancestor of 2 nodes
1666 * \note Retrieves the lowest common ancestor of 'node1' AND 'node2'.
1667 * If 'node1' or 'node2' are both or indiscriminately instances of ComposedNode and that
1668 * 'node1' is in descendance of 'node2' (resp. 'node2' in descendance of 'node1')
1669 * 'node2' is returned (resp. 'node1').
1670 * \exception Exception : if 'node1' and 'node2' do not share the same genealogy.
1671 * \return The lowest common ancestor if it exists.
1674 SubjectComposedNode* SubjectComposedNode::getLowestCommonAncestor(SubjectNode* snode1, SubjectNode* snode2)
1676 Node* node1 = snode1->getNode();
1677 Node* node2 = snode2->getNode();
1679 ComposedNode *node = ComposedNode::getLowestCommonAncestor(node1->getFather(), node2->getFather());
1680 SubjectComposedNode* snode = dynamic_cast<SubjectComposedNode*>( GuiContext::getCurrent()->_mapOfSubjectNode[node] );
1684 /*! used in derived classes using a counter, a selector, or a condition:
1685 * ForLoop, ForEachLoop, Switch, WhileLoop.
1687 bool SubjectComposedNode::hasValue()
1692 /*! used in derived classes using a counter, a selector, or a condition:
1693 * ForLoop, ForEachLoop, Switch, WhileLoop.
1695 std::string SubjectComposedNode::getValue()
1701 // ----------------------------------------------------------------------------
1703 SubjectBloc::SubjectBloc(YACS::ENGINE::Bloc *bloc, Subject *parent)
1704 : SubjectComposedNode(bloc, parent), _bloc(bloc)
1710 * all generic destruction is done in generic class SubjectNode
1712 SubjectBloc::~SubjectBloc()
1714 DEBTRACE("SubjectBloc::~SubjectBloc " << getName());
1717 void SubjectBloc::clean(Command *command)
1719 if (_askRegisterUndo)
1721 _askRegisterUndo = false;
1722 registerUndoDestroy();
1724 localclean(command);
1725 SubjectComposedNode::clean(command);
1728 void SubjectBloc::localclean(Command *command)
1730 DEBTRACE("SubjectBloc::localClean ");
1731 set<SubjectNode*>::iterator it;
1732 set<SubjectNode*> copyChildren = _children;
1733 for (it = copyChildren.begin(); it !=copyChildren.end(); ++it)
1737 SubjectNode* SubjectBloc::addNode(YACS::ENGINE::Catalog *catalog,
1743 DEBTRACE("SubjectBloc::addNode( " << catalog << ", " << compo << ", " << type << ", " << name << " )");
1744 SubjectNode* child = createNode(catalog, compo, type, name, newCompoInst);
1748 void SubjectBloc::houseKeepingAfterCutPaste(bool isCut, SubjectNode *son)
1753 completeChildrenSubjectList(son);
1756 void SubjectBloc::completeChildrenSubjectList(SubjectNode *son)
1758 _children.insert(son);
1761 void SubjectBloc::removeNode(SubjectNode* child)
1763 _children.erase(child);
1766 SubjectNode* SubjectBloc::getChild(YACS::ENGINE::Node* node) const
1768 SubjectNode* aChild = 0;
1772 set<SubjectNode*>::const_iterator it = _children.begin();
1773 for ( ; it != _children.end(); it++ )
1774 if ( (*it)->getNode() == node )
1784 void SubjectBloc::recursiveUpdate(GuiEvent event, int type, Subject* son)
1786 update(event, type, son);
1787 set<SubjectNode*>::iterator it = _children.begin();
1788 for (; it != _children.end(); ++it)
1789 (*it)->recursiveUpdate(event, type, son);
1793 // ----------------------------------------------------------------------------
1795 SubjectProc::SubjectProc(YACS::ENGINE::Proc *proc, Subject *parent)
1796 : SubjectBloc(proc, parent), _proc(proc)
1798 _postEraseList.clear();
1801 SubjectProc::~SubjectProc()
1803 DEBTRACE("SubjectProc::~SubjectProc " << getName());
1806 void SubjectProc::clean(Command *command)
1808 if (_askRegisterUndo)
1810 _askRegisterUndo = false;
1811 registerUndoDestroy();
1813 localclean(command);
1814 SubjectBloc::clean(command);
1817 void SubjectProc::localclean(Command *command)
1819 DEBTRACE("SubjectProc::localClean ");
1822 void SubjectProc::cleanPostErase()
1824 DEBTRACE("SubjectProc::cleanPostErase");
1825 for (int i=0; i<_postEraseList.size(); i++)
1827 DEBTRACE("cleanPostErase " << _postEraseList[i]->getName());
1828 erase(_postEraseList[i],0, true); // --- true: do not call recursively erase
1830 _postEraseList.clear();
1833 void SubjectProc::loadProc()
1835 DEBTRACE("SubjectProc::loadProc " << getName());
1843 //! Load types for a SubjectProc
1845 * This method loads (on import or on creation) all types of the builtin catalog and all types defined in the Proc
1847 void SubjectProc::loadTypes()
1849 Catalog* builtinCatalog = getSALOMERuntime()->getBuiltinCatalog();
1850 std::map<std::string, TypeCode *>::iterator pt;
1851 for(pt=builtinCatalog->_typeMap.begin();pt!=builtinCatalog->_typeMap.end();pt++)
1853 addSubjectDataType((*pt).second , (*pt).first);
1855 for(pt=_proc->typeMap.begin();pt!=_proc->typeMap.end();pt++)
1857 addSubjectDataType((*pt).second , (*pt).first);
1862 * loadComponents is used when an existing scheme has been loaded in memory,
1863 * to create subjects for components stored in the schema file, but are not
1864 * associated with any service nodes. Note, that if such component is associated
1865 * to any container, the subject for this container is also created, if it is not
1868 void SubjectProc::loadComponents()
1870 Proc* aProc = GuiContext::getCurrent()->getProc();
1871 for (map<string, ComponentInstance*>::const_iterator itComp = aProc->componentInstanceMap.begin();
1872 itComp != aProc->componentInstanceMap.end(); ++itComp)
1874 GuiContext::getCurrent()->_mapOfLastComponentInstance[itComp->second->getCompoName()]=itComp->second;
1876 if ( GuiContext::getCurrent()->_mapOfSubjectComponent.find((*itComp).second)
1878 GuiContext::getCurrent()->_mapOfSubjectComponent.end() )
1879 { // engine object for component already exists => add only a subject for it
1880 addSubjectComponent((*itComp).second);
1886 * loadContainers is used when an existing scheme has been loaded in memory,
1887 * to create subjects for containers stored in the schema file, but are not
1888 * associated with components.
1890 void SubjectProc::loadContainers()
1892 Proc* aProc = GuiContext::getCurrent()->getProc();
1893 for (map<string, Container*>::const_iterator itCont = aProc->containerMap.begin();
1894 itCont != aProc->containerMap.end(); ++itCont)
1895 if ( GuiContext::getCurrent()->_mapOfSubjectContainer.find((*itCont).second)
1897 GuiContext::getCurrent()->_mapOfSubjectContainer.end() )
1898 // engine object for container already exists => add only a subject for it
1899 addSubjectContainer((*itCont).second, (*itCont).second->getName());
1902 SubjectComponent* SubjectProc::addComponent(std::string compoName, std::string containerName)
1904 DEBTRACE("SubjectProc::addComponent " << compoName << " " << containerName);
1905 CommandAddComponentInstance *command = new CommandAddComponentInstance(compoName, containerName);
1906 if (command->execute())
1908 GuiContext::getCurrent()->getInvoc()->add(command);
1909 return command->getSubjectComponent();
1911 else delete command;
1915 SubjectContainer* SubjectProc::addContainer(std::string name, std::string ref)
1917 DEBTRACE("SubjectProc::addContainer " << name << " " << ref);
1918 if (! GuiContext::getCurrent()->getProc()->containerMap.count(name))
1920 CommandAddContainer *command = new CommandAddContainer(name,ref);
1921 if (command->execute())
1923 GuiContext::getCurrent()->getInvoc()->add(command);
1924 return command->getSubjectContainer();
1929 else GuiContext::getCurrent()->_lastErrorMessage = "There is already a container with that name";
1933 bool SubjectProc::addDataType(YACS::ENGINE::Catalog* catalog, std::string typeName)
1935 DEBTRACE("SubjectProc::addDataType " << typeName);
1936 CommandAddDataTypeFromCatalog *command = new CommandAddDataTypeFromCatalog(catalog, typeName);
1937 if (command->execute())
1939 DEBTRACE("new datatype " << typeName);
1940 GuiContext::getCurrent()->getInvoc()->add(command);
1943 else delete command;
1947 SubjectComponent* SubjectProc::addSubjectComponent(YACS::ENGINE::ComponentInstance* compo)
1949 DEBTRACE("SubjectProc::addSubjectComponent " << compo->getInstanceName());
1950 SubjectComponent *son = new SubjectComponent(compo, this);
1951 GuiContext::getCurrent()->_mapOfSubjectComponent[compo] = son;
1952 update(ADD, COMPONENT, son);
1953 //son->setContainer();
1957 SubjectContainer* SubjectProc::addSubjectContainer(YACS::ENGINE::Container* cont,
1960 DEBTRACE("SubjectProc::addSubjectContainer " << name);
1961 SubjectContainer *son = new SubjectContainer(cont, this);
1962 // In edition mode do not clone containers
1963 cont->attachOnCloning();
1964 GuiContext::getCurrent()->_mapOfSubjectContainer[cont] = son;
1965 update(ADD, CONTAINER, son);
1969 /*! register a sub command when importing a node from catalog with new data types
1972 SubjectDataType* SubjectProc::addComSubjectDataType(YACS::ENGINE::TypeCode *type, std::string alias)
1974 string typeName = type->name();
1975 DEBTRACE("SubjectProc::addComSubjectDataType " << typeName);
1976 SubjectDataType* son = 0;
1977 if (GuiContext::getCurrent()->isLoading())
1978 son = addSubjectDataType(type,alias); // no sub command registration
1981 Catalog *catalog = GuiContext::getCurrent()->getCurrentCatalog();
1982 CommandAddDataTypeFromCatalog *command = new CommandAddDataTypeFromCatalog(catalog,
1984 if (command->execute())
1985 GuiContext::getCurrent()->getInvoc()->add(command);
1986 else delete command;
1992 SubjectDataType* SubjectProc::addSubjectDataType(YACS::ENGINE::TypeCode *type, std::string alias)
1994 string typeName = type->name();
1995 DEBTRACE("SubjectProc::addSubjectDataType " << typeName);
1996 Proc* proc = GuiContext::getCurrent()->getProc();
1997 SubjectDataType* son = 0;
1998 if (! proc->typeMap.count(typeName))
1999 proc->typeMap[ typeName ] = type->clone();
2001 proc->typeMap[ typeName ]->incrRef();
2002 if (! GuiContext::getCurrent()->_mapOfSubjectDataType.count(typeName))
2004 son = new SubjectDataType(type, this, alias);
2005 GuiContext::getCurrent()->_mapOfSubjectDataType[typeName] = son;
2006 update(ADD, DATATYPE, son);
2009 GuiContext::getCurrent()->_lastErrorMessage = "Typecode " + typeName + " was already added in proc";
2013 void SubjectProc::removeSubjectDataType(std::string typeName)
2015 Proc* proc = GuiContext::getCurrent()->getProc();
2016 YASSERT(proc->typeMap.count(typeName));
2017 YASSERT(GuiContext::getCurrent()->_mapOfSubjectDataType.count(typeName));
2018 TypeCode* aTypeCode = proc->typeMap[typeName];
2019 SubjectDataType* aSDataType = GuiContext::getCurrent()->_mapOfSubjectDataType[typeName];
2020 unsigned int aRefCnt = aTypeCode->getRefCnt();
2021 DEBTRACE("SubjectProc::removeSubjectDataType: " << typeName << " " << aRefCnt);
2022 GuiContext::getCurrent()->_mapOfSubjectDataType.erase(typeName);
2023 proc->typeMap.erase(typeName);
2024 erase(aSDataType); // do all the necessary updates
2025 aTypeCode->decrRef();
2028 void SubjectProc::removeSubjectContainer(SubjectContainer* scont)
2030 YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(scont->getContainer()));
2031 erase(scont); // do all the necessary updates
2035 // ----------------------------------------------------------------------------
2037 SubjectElementaryNode::SubjectElementaryNode(YACS::ENGINE::ElementaryNode *elementaryNode,
2039 : SubjectNode(elementaryNode, parent), _elementaryNode(elementaryNode)
2044 * all generic destruction is done in generic class SubjectNode
2046 SubjectElementaryNode::~SubjectElementaryNode()
2048 DEBTRACE("SubjectElementaryNode::~SubjectElementaryNode " << getName());
2051 void SubjectElementaryNode::clean(Command *command)
2053 if (_askRegisterUndo)
2055 _askRegisterUndo = false;
2056 registerUndoDestroy();
2058 localclean(command);
2059 SubjectNode::clean(command);
2062 void SubjectElementaryNode::localclean(Command *command)
2064 DEBTRACE("SubjectElementaryNode::localClean ");
2067 void SubjectElementaryNode::recursiveUpdate(GuiEvent event, int type, Subject* son)
2069 update(event, type, son);
2072 SubjectDataPort* SubjectElementaryNode::addInputPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
2074 DEBTRACE("SubjectElementaryNode::addInputPort( " << catalog << ", " << type << ", " << name << " )");
2075 Proc *proc = GuiContext::getCurrent()->getProc();
2076 string position = "";
2077 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
2079 CommandAddInputPortFromCatalog *command = new CommandAddInputPortFromCatalog(catalog,
2083 if (command->execute())
2085 GuiContext::getCurrent()->getInvoc()->add(command);
2086 SubjectInputPort *son = command->getSubjectInputPort();
2089 else delete command;
2093 SubjectDataPort* SubjectElementaryNode::addOutputPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
2095 DEBTRACE("SubjectElementaryNode::addOutputPort( " << catalog << ", " << type << ", " << name << " )");
2096 Proc *proc = GuiContext::getCurrent()->getProc();
2097 string position = "";
2098 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
2100 CommandAddOutputPortFromCatalog *command = new CommandAddOutputPortFromCatalog(catalog,
2104 if (command->execute())
2106 GuiContext::getCurrent()->getInvoc()->add(command);
2107 SubjectOutputPort *son = command->getSubjectOutputPort();
2110 else delete command;
2114 SubjectDataPort* SubjectElementaryNode::addIDSPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
2116 DEBTRACE("SubjectElementaryNode::addIDSPort( " << catalog << ", " << type << ", " << name << " )");
2117 Proc *proc = GuiContext::getCurrent()->getProc();
2118 string position = "";
2119 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
2121 CommandAddIDSPortFromCatalog *command = new CommandAddIDSPortFromCatalog(catalog,
2125 if (command->execute())
2127 GuiContext::getCurrent()->getInvoc()->add(command);
2128 SubjectInputDataStreamPort *son = command->getSubjectIDSPort();
2131 else delete command;
2135 SubjectDataPort* SubjectElementaryNode::addODSPort(YACS::ENGINE::Catalog *catalog, std::string type, std::string name)
2137 DEBTRACE("SubjectElementaryNode::addODSPort( " << catalog << ", " << type << ", " << name << " )");
2138 Proc *proc = GuiContext::getCurrent()->getProc();
2139 string position = "";
2140 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
2142 CommandAddODSPortFromCatalog *command = new CommandAddODSPortFromCatalog(catalog,
2146 if (command->execute())
2148 GuiContext::getCurrent()->getInvoc()->add(command);
2149 SubjectOutputDataStreamPort *son = command->getSubjectODSPort();
2152 else delete command;
2156 bool SubjectElementaryNode::OrderDataPorts(SubjectDataPort* portToMove, int isUp)
2158 DEBTRACE("SubjectElementaryNode::OrderDataPorts");
2159 Proc *proc = GuiContext::getCurrent()->getProc();
2160 string position = "";
2161 if (proc != dynamic_cast<Proc*>(_node)) position = proc->getChildName(_node);
2164 if (!portToMove) return false;
2165 string nameToMove = portToMove->getName();
2167 Command *command = 0;
2168 bool isInput = dynamic_cast<SubjectInputPort*>(portToMove);
2170 command = new CommandOrderInputPorts(position, nameToMove, isUp);
2172 command = new CommandOrderOutputPorts(position, nameToMove, isUp);
2174 if (command->execute())
2176 GuiContext::getCurrent()->getInvoc()->add(command);
2182 void SubjectElementaryNode::removePort(SubjectDataPort* port)
2184 DEBTRACE("SubjectElementaryNode::removePort " << port->getName());
2185 if (SubjectInputPort* inp = dynamic_cast<SubjectInputPort*>(port))
2188 _listSubjectInputPort.remove(inp);
2190 else if(SubjectOutputPort* outp = dynamic_cast<SubjectOutputPort*>(port))
2193 _listSubjectOutputPort.remove(outp);
2195 if (SubjectInputDataStreamPort* idsp = dynamic_cast<SubjectInputDataStreamPort*>(port))
2198 _listSubjectIDSPort.remove(idsp);
2200 else if(SubjectOutputDataStreamPort* odsp = dynamic_cast<SubjectOutputDataStreamPort*>(port))
2203 _listSubjectODSPort.remove(odsp);
2207 void SubjectElementaryNode::loadChildren()
2209 list<InputPort*> listInputPorts = _elementaryNode->getLocalInputPorts();
2210 list<OutputPort*> listOutputPorts = _elementaryNode->getLocalOutputPorts();
2211 list<InputDataStreamPort*> listIDSPorts = _elementaryNode->getSetOfInputDataStreamPort();
2212 list<OutputDataStreamPort*> listODSPorts = _elementaryNode->getSetOfOutputDataStreamPort();
2213 if (SplitterNode *splitterNode = dynamic_cast<SplitterNode*>(_elementaryNode))
2214 listInputPorts.push_back(splitterNode->getFather()->getInputPort("SmplsCollection"));
2215 list<InputPort*>::const_iterator iti;
2216 for (iti = listInputPorts.begin(); iti != listInputPorts.end(); ++iti)
2217 addSubjectInputPort(*iti);
2218 list<OutputPort*>::const_iterator ito;
2219 for (ito = listOutputPorts.begin(); ito != listOutputPorts.end(); ++ito)
2220 addSubjectOutputPort(*ito);
2221 list<InputDataStreamPort*>::const_iterator itids;
2222 for (itids = listIDSPorts.begin(); itids != listIDSPorts.end(); ++itids)
2223 addSubjectIDSPort(*itids);
2224 list<OutputDataStreamPort*>::const_iterator itods;
2225 for (itods = listODSPorts.begin(); itods != listODSPorts.end(); ++itods)
2226 addSubjectODSPort(*itods);
2229 void SubjectElementaryNode::saveLinks()
2231 SubjectNode::saveLinks();
2234 void SubjectElementaryNode::restoreLinks()
2236 SubjectNode::restoreLinks();
2240 // ----------------------------------------------------------------------------
2243 SubjectInlineNode::SubjectInlineNode(YACS::ENGINE::InlineNode *inlineNode, Subject *parent)
2244 : SubjectElementaryNode(inlineNode, parent), _inlineNode(inlineNode)
2248 SubjectInlineNode::~SubjectInlineNode()
2250 DEBTRACE("SubjectInlineNode::~SubjectInlineNode " << getName());
2253 bool SubjectInlineNode::setScript(std::string script)
2255 Proc *proc = GuiContext::getCurrent()->getProc();
2256 CommandSetInlineNodeScript *command =
2257 new CommandSetInlineNodeScript(proc->getChildName(_node), script);
2258 if (command->execute())
2260 GuiContext::getCurrent()->getInvoc()->add(command);
2263 else delete command;
2267 std::string SubjectInlineNode::getScript()
2269 return _inlineNode->getScript();
2272 void SubjectInlineNode::clean(Command *command)
2274 if (_askRegisterUndo)
2276 _askRegisterUndo = false;
2277 registerUndoDestroy();
2279 localclean(command);
2280 SubjectElementaryNode::clean(command);
2283 void SubjectInlineNode::localclean(Command *command)
2285 DEBTRACE("SubjectInlineNode::localClean ");
2288 bool SubjectInlineNode::setExecutionMode(const std::string& mode)
2290 DEBTRACE("SubjectInlineNode::setExecutionMode ");
2291 Proc *proc = GuiContext::getCurrent()->getProc();
2293 CommandSetExecutionMode *command = new CommandSetExecutionMode(proc->getChildName(_node), mode);
2294 if (command->execute())
2296 if (!GuiContext::getCurrent()->isLoading()) // do not register command when loading a schema
2297 GuiContext::getCurrent()->getInvoc()->add(command);
2298 else delete command;
2301 else delete command;
2305 bool SubjectInlineNode::setContainer(SubjectContainer* scont)
2307 DEBTRACE("SubjectInlineNode::setContainer ");
2308 Proc *proc = GuiContext::getCurrent()->getProc();
2310 CommandSetContainer *command = new CommandSetContainer(proc->getChildName(_node), scont->getName());
2311 if (command->execute())
2313 if (!GuiContext::getCurrent()->isLoading()) // do not register command when loading a schema
2314 GuiContext::getCurrent()->getInvoc()->add(command);
2315 else delete command;
2318 else delete command;
2323 // ----------------------------------------------------------------------------
2325 SubjectServiceNode::SubjectServiceNode(YACS::ENGINE::ServiceNode *serviceNode, Subject *parent)
2326 : SubjectElementaryNode(serviceNode, parent), _serviceNode(serviceNode)
2328 _subjectReference = 0;
2329 _subRefComponent = 0;
2332 SubjectServiceNode::~SubjectServiceNode()
2334 DEBTRACE("SubjectServiceNode::~SubjectServiceNode " << getName());
2335 ComponentInstance *instance = _serviceNode->getComponent();
2336 if (!instance) return;
2337 if (GuiContext::getCurrent()->_mapOfSubjectComponent.count(instance))
2339 SubjectComponent *scomp = GuiContext::getCurrent()->_mapOfSubjectComponent[instance];
2340 if (!scomp->hasServices())
2341 GuiContext::getCurrent()->getSubjectProc()->addPostErase(scomp);
2345 void SubjectServiceNode::clean(Command *command)
2347 if (_askRegisterUndo)
2349 _askRegisterUndo = false;
2350 registerUndoDestroy();
2352 localclean(command);
2353 SubjectElementaryNode::clean(command);
2356 void SubjectServiceNode::localclean(Command *command)
2358 DEBTRACE("SubjectServiceNode::localClean ");
2359 if (_subRefComponent)
2361 SubjectComponent *scomp = dynamic_cast<SubjectComponent*>(_subRefComponent->getParent());
2363 scomp->removeSubServiceFromSet(this);
2365 if (_subjectReference)
2367 // update( REMOVE, REFERENCE, _subjectReference );
2368 erase(_subjectReference);
2369 _subjectReference = 0;
2371 if (_subRefComponent)
2373 erase(_subRefComponent);
2374 _subRefComponent = 0;
2380 * When cloning a service node from a catalog, create the component associated to the node,
2381 * if not already existing, and create the corresponding subject.
2383 void SubjectServiceNode::setComponentFromCatalog(YACS::ENGINE::Catalog *catalog,
2385 std::string service)
2387 DEBTRACE("SubjectServiceNode::setComponentFromCatalog " << compo);
2389 Proc* proc = GuiContext::getCurrent()->getProc();
2390 string position = proc->getChildName(_node);
2391 CommandAddComponentFromCatalog* command =
2392 new CommandAddComponentFromCatalog(catalog,
2396 if (command->execute())
2397 GuiContext::getCurrent()->getInvoc()->add(command);
2398 else delete command;
2403 * When loading scheme from file, get the component associated to the node, if any,
2404 * and create the corresponding subject.
2406 void SubjectServiceNode::setComponent()
2408 DEBTRACE("SubjectServiceNode::setComponent");
2409 ComponentInstance *instance = _serviceNode->getComponent();
2412 Proc* proc = GuiContext::getCurrent()->getProc();
2413 string compo = instance->getCompoName();
2414 SubjectComponent* subCompo = 0;
2415 if (! GuiContext::getCurrent()->_mapOfSubjectComponent.count(instance))
2417 DEBTRACE("SubjectServiceNode::setComponent : create subject for compo = " << compo.c_str());
2418 if(proc->componentInstanceMap.count(instance->getInstanceName())==0)
2420 std::cerr << "PROBLEM : ComponentInstance should be registered in proc, add it " << instance->getInstanceName() << std::endl;
2421 proc->componentInstanceMap[instance->getInstanceName()] = instance;
2422 Container* cont=instance->getContainer();
2423 //check if the associated container is consistent with containerMap
2425 if (proc->containerMap.count(cont->getName()) == 0)
2427 //container exists but is not in containerMap. Clone it, it's probably the result of copy paste from outside the proc
2428 Container* newcont(cont->cloneAlways());
2429 proc->containerMap[cont->getName()]=newcont;
2430 instance->setContainer(newcont);
2431 GuiContext::getCurrent()->getSubjectProc()->addSubjectContainer(newcont, newcont->getName());
2435 if(cont != proc->containerMap[cont->getName()])
2437 //the associated container is not the same as the one in containerMap: use the containerMap one
2438 instance->setContainer(proc->containerMap[cont->getName()]);
2442 subCompo = GuiContext::getCurrent()->getSubjectProc()->addSubjectComponent(instance);
2446 DEBTRACE("SubjectServiceNode::setComponent : get already created subject for compo = " <<compo.c_str());
2447 subCompo = GuiContext::getCurrent()->_mapOfSubjectComponent[instance];
2450 addSubjectReference(subCompo);
2451 if (_subRefComponent)
2452 subCompo->moveService(_subRefComponent);
2454 _subRefComponent = subCompo->attachService(this);
2458 bool SubjectServiceNode::associateToComponent(SubjectComponent *subcomp)
2460 DEBTRACE("SubjectServiceNode::associateToComponent " << getName() << " " << subcomp->getName());
2461 SubjectReference* oldSReference = _subjectReference;
2462 string aName = GuiContext::getCurrent()->getProc()->getChildName(_serviceNode);
2463 CommandAssociateServiceToComponent *command =
2464 new CommandAssociateServiceToComponent(aName, subcomp->getName());
2465 if (command->execute())
2467 GuiContext::getCurrent()->getInvoc()->add(command);
2470 else delete command;
2474 void SubjectServiceNode::addSubjectReference(Subject *ref)
2476 DEBTRACE("Subject::addSubjectReference " << getName() << " " << ref->getName());
2477 SubjectReference *son = new SubjectReference(ref, this);
2478 _subjectReference = son;
2479 update(ADDREF, 0, son);
2482 SubjectReference* SubjectServiceNode::getSubjectReference()
2484 return _subjectReference;
2487 // ----------------------------------------------------------------------------
2489 SubjectPythonNode::SubjectPythonNode(YACS::ENGINE::PythonNode *pythonNode, Subject *parent)
2490 : SubjectInlineNode(pythonNode, parent), _pythonNode(pythonNode)
2494 SubjectPythonNode::~SubjectPythonNode()
2496 DEBTRACE("SubjectPythonNode::~SubjectPythonNode " << getName());
2499 void SubjectPythonNode::clean(Command *command)
2501 if (_askRegisterUndo)
2503 _askRegisterUndo = false;
2504 registerUndoDestroy();
2506 localclean(command);
2507 SubjectInlineNode::clean(command);
2510 void SubjectPythonNode::localclean(Command *command)
2512 DEBTRACE("SubjectPythonNode::localClean ");
2516 // ----------------------------------------------------------------------------
2518 SubjectPyFuncNode::SubjectPyFuncNode(YACS::ENGINE::PyFuncNode *pyFuncNode, Subject *parent)
2519 : SubjectInlineNode(pyFuncNode, parent), _pyFuncNode(pyFuncNode)
2523 SubjectPyFuncNode::~SubjectPyFuncNode()
2525 DEBTRACE("SubjectPyFuncNode::~SubjectPyFuncNode " << getName());
2528 bool SubjectPyFuncNode::setFunctionName(std::string funcName)
2530 Proc *proc = GuiContext::getCurrent()->getProc();
2531 CommandSetFuncNodeFunctionName *command =
2532 new CommandSetFuncNodeFunctionName(proc->getChildName(_node), funcName);
2533 if (command->execute())
2535 GuiContext::getCurrent()->getInvoc()->add(command);
2538 else delete command;
2542 void SubjectPyFuncNode::clean(Command *command)
2544 if (_askRegisterUndo)
2546 _askRegisterUndo = false;
2547 registerUndoDestroy();
2549 localclean(command);
2550 SubjectInlineNode::clean(command);
2553 void SubjectPyFuncNode::localclean(Command *command)
2555 DEBTRACE("SubjectPyFuncNode::localClean ");
2558 // ----------------------------------------------------------------------------
2560 SubjectCORBANode::SubjectCORBANode(YACS::ENGINE::CORBANode *corbaNode, Subject *parent)
2561 : SubjectServiceNode(corbaNode, parent), _corbaNode(corbaNode)
2565 SubjectCORBANode::~SubjectCORBANode()
2567 DEBTRACE("SubjectCORBANode::~SubjectCORBANode " << getName());
2570 void SubjectCORBANode::clean(Command *command)
2572 if (_askRegisterUndo)
2574 _askRegisterUndo = false;
2575 registerUndoDestroy();
2577 localclean(command);
2578 SubjectServiceNode::clean(command);
2581 void SubjectCORBANode::localclean(Command *command)
2583 DEBTRACE("SubjectCORBANode::localClean ");
2587 // ----------------------------------------------------------------------------
2589 SubjectCppNode::SubjectCppNode(YACS::ENGINE::CppNode *cppNode, Subject *parent)
2590 : SubjectServiceNode(cppNode, parent), _cppNode(cppNode)
2594 SubjectCppNode::~SubjectCppNode()
2596 DEBTRACE("SubjectCppNode::~SubjectCppNode " << getName());
2599 void SubjectCppNode::clean(Command *command)
2601 if (_askRegisterUndo)
2603 _askRegisterUndo = false;
2604 registerUndoDestroy();
2606 localclean(command);
2607 SubjectServiceNode::clean(command);
2610 void SubjectCppNode::localclean(Command *command)
2612 DEBTRACE("SubjectCppNode::localClean ");
2616 // ----------------------------------------------------------------------------
2618 SubjectSalomeNode::SubjectSalomeNode(YACS::ENGINE::SalomeNode *salomeNode, Subject *parent)
2619 : SubjectServiceNode(salomeNode, parent), _salomeNode(salomeNode)
2623 SubjectSalomeNode::~SubjectSalomeNode()
2625 DEBTRACE("SubjectSalomeNode::~SubjectSalomeNode " << getName());
2628 void SubjectSalomeNode::clean(Command *command)
2630 if (_askRegisterUndo)
2632 _askRegisterUndo = false;
2633 registerUndoDestroy();
2635 localclean(command);
2636 SubjectServiceNode::clean(command);
2639 void SubjectSalomeNode::localclean(Command *command)
2641 DEBTRACE("SubjectSalomeNode::localClean ");
2645 // ----------------------------------------------------------------------------
2647 SubjectSalomePythonNode::SubjectSalomePythonNode(YACS::ENGINE::SalomePythonNode *salomePythonNode,
2649 : SubjectServiceNode(salomePythonNode, parent), _salomePythonNode(salomePythonNode)
2653 SubjectSalomePythonNode::~SubjectSalomePythonNode()
2655 DEBTRACE("SubjectSalomePythonNode::~SubjectSalomePythonNode " << getName());
2658 void SubjectSalomePythonNode::clean(Command *command)
2660 if (_askRegisterUndo)
2662 _askRegisterUndo = false;
2663 registerUndoDestroy();
2665 localclean(command);
2666 SubjectServiceNode::clean(command);
2669 void SubjectSalomePythonNode::localclean(Command *command)
2671 DEBTRACE("SubjectSalomePythonNode::localClean ");
2675 // ----------------------------------------------------------------------------
2677 SubjectXmlNode::SubjectXmlNode(YACS::ENGINE::XmlNode *xmlNode, Subject *parent)
2678 : SubjectServiceNode(xmlNode, parent), _xmlNode(xmlNode)
2682 SubjectXmlNode::~SubjectXmlNode()
2684 DEBTRACE("SubjectXmlNode::~SubjectXmlNode " << getName());
2687 void SubjectXmlNode::clean(Command *command)
2689 if (_askRegisterUndo)
2691 _askRegisterUndo = false;
2692 registerUndoDestroy();
2694 localclean(command);
2695 SubjectServiceNode::clean(command);
2698 void SubjectXmlNode::localclean(Command *command)
2700 DEBTRACE("SubjectXmlNode::localClean ");
2704 // ----------------------------------------------------------------------------
2706 SubjectSplitterNode::SubjectSplitterNode(YACS::ENGINE::SplitterNode *splitterNode, Subject *parent)
2707 : SubjectElementaryNode(splitterNode, parent), _splitterNode(splitterNode)
2709 _destructible = false;
2712 SubjectSplitterNode::~SubjectSplitterNode()
2714 DEBTRACE("SubjectSplitterNode::~SubjectSplitterNode " << getName());
2717 void SubjectSplitterNode::clean(Command *command)
2719 if (_askRegisterUndo)
2721 _askRegisterUndo = false;
2722 registerUndoDestroy();
2724 localclean(command);
2725 SubjectElementaryNode::clean(command);
2728 void SubjectSplitterNode::localclean(Command *command)
2730 DEBTRACE("SubjectSplitterNode::localClean ");
2734 std::string SubjectSplitterNode::getName()
2739 // ----------------------------------------------------------------------------
2741 SubjectDataNode::SubjectDataNode(YACS::ENGINE::DataNode *dataNode, Subject *parent)
2742 : SubjectElementaryNode(dataNode, parent), _dataNode(dataNode)
2744 _destructible = true;
2747 SubjectDataNode::~SubjectDataNode()
2749 DEBTRACE("SubjectDataNode::~SubjectDataNode " << getName());
2752 void SubjectDataNode::clean(Command *command)
2754 if (_askRegisterUndo)
2756 _askRegisterUndo = false;
2757 registerUndoDestroy();
2759 localclean(command);
2760 SubjectElementaryNode::clean(command);
2763 void SubjectDataNode::localclean(Command *command)
2765 DEBTRACE("SubjectDataNode::localClean ");
2768 // ----------------------------------------------------------------------------
2770 SubjectPresetNode::SubjectPresetNode(YACS::ENGINE::PresetNode *presetNode, Subject *parent)
2771 : SubjectDataNode(presetNode, parent), _presetNode(presetNode)
2773 _destructible = true;
2776 SubjectPresetNode::~SubjectPresetNode()
2778 DEBTRACE("SubjectPresetNode::~SubjectPresetNode " << getName());
2781 void SubjectPresetNode::clean(Command *command)
2783 if (_askRegisterUndo)
2785 _askRegisterUndo = false;
2786 registerUndoDestroy();
2788 localclean(command);
2789 SubjectDataNode::clean(command);
2792 void SubjectPresetNode::localclean(Command *command)
2794 DEBTRACE("SubjectPresetNode::localClean ");
2797 // ----------------------------------------------------------------------------
2799 SubjectOutNode::SubjectOutNode(YACS::ENGINE::OutNode *outNode, Subject *parent)
2800 : SubjectDataNode(outNode, parent), _outNode(outNode)
2802 _destructible = true;
2805 SubjectOutNode::~SubjectOutNode()
2807 DEBTRACE("SubjectOutNode::~SubjectOutNode " << getName());
2810 void SubjectOutNode::clean(Command *command)
2812 if (_askRegisterUndo)
2814 _askRegisterUndo = false;
2815 registerUndoDestroy();
2817 localclean(command);
2818 SubjectDataNode::clean(command);
2821 void SubjectOutNode::localclean(Command *command)
2823 DEBTRACE("SubjectOutNode::localClean ");
2826 // ----------------------------------------------------------------------------
2828 SubjectStudyInNode::SubjectStudyInNode(YACS::ENGINE::StudyInNode *studyInNode, Subject *parent)
2829 : SubjectDataNode(studyInNode, parent), _studyInNode(studyInNode)
2831 _destructible = true;
2834 SubjectStudyInNode::~SubjectStudyInNode()
2836 DEBTRACE("SubjectStudyInNode::~SubjectStudyInNode " << getName());
2839 void SubjectStudyInNode::clean(Command *command)
2841 if (_askRegisterUndo)
2843 _askRegisterUndo = false;
2844 registerUndoDestroy();
2846 localclean(command);
2847 SubjectDataNode::clean(command);
2850 void SubjectStudyInNode::localclean(Command *command)
2852 DEBTRACE("SubjectStudyInNode::localClean ");
2855 // ----------------------------------------------------------------------------
2857 SubjectStudyOutNode::SubjectStudyOutNode(YACS::ENGINE::StudyOutNode *studyOutNode, Subject *parent)
2858 : SubjectDataNode(studyOutNode, parent), _studyOutNode(studyOutNode)
2860 _destructible = true;
2863 SubjectStudyOutNode::~SubjectStudyOutNode()
2865 DEBTRACE("SubjectStudyOutNode::~SubjectStudyOutNode " << getName());
2868 void SubjectStudyOutNode::clean(Command *command)
2870 if (_askRegisterUndo)
2872 _askRegisterUndo = false;
2873 registerUndoDestroy();
2875 localclean(command);
2876 SubjectDataNode::clean(command);
2879 void SubjectStudyOutNode::localclean(Command *command)
2881 DEBTRACE("SubjectStudyOutNode::localClean ");
2884 // ----------------------------------------------------------------------------
2886 SubjectForLoop::SubjectForLoop(YACS::ENGINE::ForLoop *forLoop, Subject *parent)
2887 : SubjectComposedNode(forLoop, parent), _forLoop(forLoop)
2892 SubjectForLoop::~SubjectForLoop()
2894 DEBTRACE("SubjectForLoop::~SubjectForLoop " << getName());
2897 void SubjectForLoop::clean(Command *command)
2899 if (_askRegisterUndo)
2901 _askRegisterUndo = false;
2902 registerUndoDestroy();
2904 localclean(command);
2905 SubjectComposedNode::clean(command);
2908 void SubjectForLoop::localclean(Command *command)
2910 DEBTRACE("SubjectForLoop::localClean ");
2915 void SubjectForLoop::recursiveUpdate(GuiEvent event, int type, Subject* son)
2917 update(event, type, son);
2919 _body->recursiveUpdate(event, type, son);
2922 SubjectNode* SubjectForLoop::addNode(YACS::ENGINE::Catalog *catalog,
2928 DEBTRACE("SubjectForLoop::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<")");
2929 SubjectNode* body = 0;
2932 GuiContext::getCurrent()->_lastErrorMessage = "If you need several nodes in a loop, put the nodes in a bloc";
2935 body = createNode(catalog, compo, type, name, newCompoInst);
2939 void SubjectForLoop::houseKeepingAfterCutPaste(bool isCut, SubjectNode *son)
2947 void SubjectForLoop::completeChildrenSubjectList(SubjectNode *son)
2952 bool SubjectForLoop::setNbSteps(std::string nbSteps)
2954 DEBTRACE("SubjectForLoop::setNbSteps " << nbSteps);
2955 Proc *proc = GuiContext::getCurrent()->getProc();
2956 CommandSetForLoopSteps *command =
2957 new CommandSetForLoopSteps(proc->getChildName(getNode()), nbSteps);
2958 if (command->execute())
2960 GuiContext::getCurrent()->getInvoc()->add(command);
2963 else delete command;
2966 bool SubjectForLoop::hasValue()
2971 std::string SubjectForLoop::getValue()
2973 return _forLoop->edGetNbOfTimesInputPort()->getAsString();
2976 // ----------------------------------------------------------------------------
2978 SubjectWhileLoop::SubjectWhileLoop(YACS::ENGINE::WhileLoop *whileLoop, Subject *parent)
2979 : SubjectComposedNode(whileLoop, parent), _whileLoop(whileLoop)
2984 SubjectWhileLoop::~SubjectWhileLoop()
2986 DEBTRACE("SubjectWhileLoop::~SubjectWhileLoop " << getName());
2989 void SubjectWhileLoop::clean(Command *command)
2991 if (_askRegisterUndo)
2993 _askRegisterUndo = false;
2994 registerUndoDestroy();
2996 localclean(command);
2997 SubjectComposedNode::clean(command);
3000 void SubjectWhileLoop::localclean(Command *command)
3002 DEBTRACE("SubjectWhileLoop::localClean ");
3007 void SubjectWhileLoop::recursiveUpdate(GuiEvent event, int type, Subject* son)
3009 update(event, type, son);
3011 _body->recursiveUpdate(event, type, son);
3014 SubjectNode* SubjectWhileLoop::addNode(YACS::ENGINE::Catalog *catalog,
3020 DEBTRACE("SubjectWhileLoop::addNode(catalog, compo, type, name)");
3021 SubjectNode* body = 0;
3024 GuiContext::getCurrent()->_lastErrorMessage = "If you need several nodes in a loop, put the nodes in a bloc";
3027 body = createNode(catalog, compo, type, name, newCompoInst);
3031 void SubjectWhileLoop::houseKeepingAfterCutPaste(bool isCut, SubjectNode *son)
3039 void SubjectWhileLoop::completeChildrenSubjectList(SubjectNode *son)
3044 bool SubjectWhileLoop::setCondition(std::string condition)
3046 DEBTRACE("SubjectWhileLoop::setCondition " << condition);
3047 Proc *proc = GuiContext::getCurrent()->getProc();
3048 CommandSetWhileCondition *command =
3049 new CommandSetWhileCondition(proc->getChildName(getNode()), condition);
3050 if (command->execute())
3052 GuiContext::getCurrent()->getInvoc()->add(command);
3055 else delete command;
3059 bool SubjectWhileLoop::hasValue()
3064 std::string SubjectWhileLoop::getValue()
3066 return _whileLoop->edGetConditionPort()->getAsString();
3069 // ----------------------------------------------------------------------------
3071 SubjectSwitch::SubjectSwitch(YACS::ENGINE::Switch *aSwitch, Subject *parent)
3072 : SubjectComposedNode(aSwitch, parent), _switch(aSwitch)
3077 SubjectSwitch::~SubjectSwitch()
3079 DEBTRACE("SubjectSwitch::~SubjectSwitch " << getName());
3082 void SubjectSwitch::clean(Command *command)
3084 if (_askRegisterUndo)
3086 _askRegisterUndo = false;
3087 registerUndoDestroy();
3089 localclean(command);
3090 SubjectComposedNode::clean(command);
3093 void SubjectSwitch::localclean(Command *command)
3095 DEBTRACE("SubjectSwitch::localClean ");
3096 map<int, SubjectNode*>::iterator it;
3097 map<int, SubjectNode*> bodyMapCpy = _bodyMap;
3098 for (it = bodyMapCpy.begin(); it != bodyMapCpy.end(); ++it)
3099 erase((*it).second);
3102 void SubjectSwitch::recursiveUpdate(GuiEvent event, int type, Subject* son)
3104 update(event, type, son);
3105 map<int, SubjectNode*>::iterator it = _bodyMap.begin();
3106 for (; it != _bodyMap.end(); ++it)
3107 (*it).second->recursiveUpdate(event, type, son);
3110 SubjectNode* SubjectSwitch::addNode(YACS::ENGINE::Catalog *catalog,
3118 DEBTRACE("SubjectSwitch::addNode("<<catalog<<","<<compo<<","<<type<<","<<name<<","<<swCase<<","<<(int)replace<<")");
3119 SubjectNode* body = 0;
3120 if (!replace && _bodyMap.count(swCase))
3122 GuiContext::getCurrent()->_lastErrorMessage = "If you need several nodes in a switch case, put the nodes in a bloc";
3125 body = createNode(catalog, compo, type, name, newCompoInst, swCase);
3129 void SubjectSwitch::removeNode(SubjectNode* son)
3131 DEBTRACE("SubjectSwitch::removeNode("<<son->getName()<<")");
3135 bool isFound = false;
3136 map<int, SubjectNode*>::const_iterator it;
3137 for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
3139 if ( (*it).second == son )
3148 DEBTRACE("id = "<<id);
3154 std::map<int, SubjectNode*> SubjectSwitch::getBodyMap()
3159 void SubjectSwitch::houseKeepingAfterCutPaste(bool isCut, SubjectNode *son)
3161 DEBTRACE("SubjectSwitch::houseKeepingAfterCutPaste");
3163 _bodyMap.erase(_switch->getRankOfNode(son->getNode()));
3165 _bodyMap[_switch->getRankOfNode(son->getNode())] = son;
3169 void SubjectSwitch::completeChildrenSubjectList(SubjectNode *son)
3171 DEBTRACE("SubjectSwitch::completeChildrenSubjectList");
3172 _bodyMap[_switch->getRankOfNode(son->getNode())] = son;
3175 SubjectNode* SubjectSwitch::getChild(YACS::ENGINE::Node* node) const
3177 SubjectNode* aChild = 0;
3181 map<int, SubjectNode*>::const_iterator it;
3182 for (it = _bodyMap.begin(); it != _bodyMap.end(); ++it)
3183 if ( (*it).second->getNode() == node )
3185 aChild = (*it).second;
3193 bool SubjectSwitch::setSelect(std::string select)
3195 DEBTRACE("SubjectSwitch::setSelect " << select);
3196 Proc *proc = GuiContext::getCurrent()->getProc();
3197 CommandSetSwitchSelect *command =
3198 new CommandSetSwitchSelect(proc->getChildName(getNode()), select);
3199 if (command->execute())
3201 GuiContext::getCurrent()->getInvoc()->add(command);
3204 else delete command;
3208 bool SubjectSwitch::setCase(std::string caseId, SubjectNode* snode)
3210 DEBTRACE("SubjectSwitch::setCase " << caseId);
3211 Proc *proc = GuiContext::getCurrent()->getProc();
3213 Switch* aSwitch = dynamic_cast<Switch*>(getNode());
3214 Node* node =snode->getNode();
3215 int previousRank = aSwitch->getRankOfNode(node);
3216 int newRank = atoi(caseId.c_str());
3217 if (previousRank == newRank) return true; // nothing to do.
3219 CommandSetSwitchCase *command =
3220 new CommandSetSwitchCase(proc->getChildName(getNode()),
3221 proc->getChildName(snode->getNode()),
3223 if (command->execute())
3225 GuiContext::getCurrent()->getInvoc()->add(command);
3228 else delete command;
3232 bool SubjectSwitch::hasValue()
3237 std::string SubjectSwitch::getValue()
3239 return _switch->edGetConditionPort()->getAsString();
3242 // ----------------------------------------------------------------------------
3244 SubjectDynParaLoop::SubjectDynParaLoop(YACS::ENGINE::DynParaLoop * dynParaLoop, Subject * parent)
3245 : SubjectComposedNode(dynParaLoop, parent), _dynParaLoop(dynParaLoop)
3247 _subjectExecNode = NULL;
3248 _subjectInitNode = NULL;
3249 _subjectFinalizeNode = NULL;
3252 SubjectDynParaLoop::~SubjectDynParaLoop()
3254 DEBTRACE("SubjectDynParaLoop::~SubjectDynParaLoop " << getName());
3257 void SubjectDynParaLoop::recursiveUpdate(GuiEvent event, int type, Subject * son)
3259 update(event, type, son);
3260 if (_subjectExecNode)
3261 _subjectExecNode->recursiveUpdate(event, type, son);
3262 if (_subjectInitNode)
3263 _subjectInitNode->recursiveUpdate(event, type, son);
3264 if (_subjectFinalizeNode)
3265 _subjectFinalizeNode->recursiveUpdate(event, type, son);
3268 SubjectNode * SubjectDynParaLoop::addNode(YACS::ENGINE::Catalog * catalog,
3274 DEBTRACE("SubjectDynParaLoop::addNode(catalog, compo, type, name)");
3275 if (_subjectExecNode)
3277 GuiContext::getCurrent()->_lastErrorMessage = "If you need several nodes in a loop, "
3278 "put the nodes in a bloc";
3281 return createNode(catalog, compo, type, name, newCompoInst);
3284 void SubjectDynParaLoop::houseKeepingAfterCutPaste(bool isCut, SubjectNode * son)
3289 _subjectExecNode = son;
3292 void SubjectDynParaLoop::clean(Command * command)
3294 if (_askRegisterUndo)
3296 _askRegisterUndo = false;
3297 registerUndoDestroy();
3299 localclean(command);
3300 SubjectComposedNode::clean(command);
3303 void SubjectDynParaLoop::localclean(Command * command)
3305 DEBTRACE("SubjectDynParaLoop::localClean ");
3306 if (_subjectExecNode)
3308 DEBTRACE(_subjectExecNode->getName());
3309 erase(_subjectExecNode);
3311 if (_subjectInitNode)
3313 DEBTRACE(_subjectInitNode->getName());
3314 erase(_subjectInitNode);
3316 if (_subjectFinalizeNode)
3318 DEBTRACE(_subjectFinalizeNode->getName());
3319 erase(_subjectFinalizeNode);
3323 void SubjectDynParaLoop::completeChildrenSubjectList(SubjectNode * son)
3326 if (son->getNode() == _dynParaLoop->getExecNode())
3327 _subjectExecNode = son;
3328 else if (son->getNode() == _dynParaLoop->getInitNode())
3329 _subjectInitNode = son;
3330 else if (son->getNode() == _dynParaLoop->getFinalizeNode())
3331 _subjectFinalizeNode = son;
3336 void SubjectDynParaLoop::removeNode(SubjectNode * child)
3339 if (child == _subjectExecNode)
3340 _subjectExecNode = NULL;
3341 else if (child == _subjectInitNode)
3342 _subjectInitNode = NULL;
3343 else if (child == _subjectFinalizeNode)
3344 _subjectFinalizeNode = NULL;
3349 SubjectNode * SubjectDynParaLoop::getChild(YACS::ENGINE::Node * node) const
3351 return _subjectExecNode;
3354 bool SubjectDynParaLoop::setNbBranches(std::string nbBranches)
3356 DEBTRACE("SubjectDynParaLoop::setNbBranches " << nbBranches);
3357 Proc * proc = GuiContext::getCurrent()->getProc();
3358 CommandSetForEachBranch * command =
3359 new CommandSetForEachBranch(proc->getChildName(getNode()), nbBranches);
3360 if (command->execute())
3362 GuiContext::getCurrent()->getInvoc()->add(command);
3365 else delete command;
3369 bool SubjectDynParaLoop::hasValue()
3374 std::string SubjectDynParaLoop::getValue()
3376 return _dynParaLoop->edGetNbOfBranchesPort()->getAsString();
3379 // ----------------------------------------------------------------------------
3381 SubjectForEachLoop::SubjectForEachLoop(YACS::ENGINE::ForEachLoop *forEachLoop, Subject *parent)
3382 : SubjectDynParaLoop(forEachLoop, parent), _forEachLoop(forEachLoop)
3387 SubjectForEachLoop::~SubjectForEachLoop()
3389 DEBTRACE("SubjectForEachLoop::~SubjectForEachLoop " << getName());
3392 void SubjectForEachLoop::clean(Command *command)
3394 if (_askRegisterUndo)
3396 _askRegisterUndo = false;
3397 registerUndoDestroy();
3399 Node* aSplitterEngine = 0;
3400 if (_splitter) aSplitterEngine = _splitter->getNode();
3402 localclean(command);
3403 SubjectDynParaLoop::clean(command);
3405 if (_forEachLoop && aSplitterEngine)
3407 DEBTRACE("SubjectForEachLoop::clean: remove for each loop splitter");
3408 _forEachLoop->edRemoveChild(aSplitterEngine);
3412 void SubjectForEachLoop::localclean(Command *command)
3414 DEBTRACE("SubjectForEachLoop::localClean ");
3417 DEBTRACE(_splitter->getName());
3422 void SubjectForEachLoop::completeChildrenSubjectList(SubjectNode *son)
3424 if (son && son->getName() == ForEachLoop::NAME_OF_SPLITTERNODE)
3427 SubjectDynParaLoop::completeChildrenSubjectList(son);
3430 void SubjectForEachLoop::removeNode(SubjectNode * child)
3433 if (child->getName() == ForEachLoop::NAME_OF_SPLITTERNODE)
3436 SubjectDynParaLoop::removeNode(child);
3440 // ----------------------------------------------------------------------------
3442 SubjectOptimizerLoop::SubjectOptimizerLoop(YACS::ENGINE::OptimizerLoop *optimizerLoop,
3444 : SubjectDynParaLoop(optimizerLoop, parent), _optimizerLoop(optimizerLoop)
3448 SubjectOptimizerLoop::~SubjectOptimizerLoop()
3450 DEBTRACE("SubjectOptimizerLoop::~SubjectOptimizerLoop " << getName());
3453 void SubjectOptimizerLoop::clean(Command *command)
3455 if (_askRegisterUndo)
3457 _askRegisterUndo = false;
3458 registerUndoDestroy();
3460 localclean(command);
3461 SubjectDynParaLoop::clean(command);
3464 void SubjectOptimizerLoop::localclean(Command *command)
3466 DEBTRACE("SubjectOptimizerLoop::localClean ");
3469 bool SubjectOptimizerLoop::setAlgorithm(const std::string& alglib,const std::string& symbol)
3471 DEBTRACE("SubjectOptimizerLoop::setAlgorithm " << alglib << " " << symbol);
3472 Proc *proc = GuiContext::getCurrent()->getProc();
3473 CommandSetAlgo *command = new CommandSetAlgo(proc->getChildName(getNode()), alglib, symbol);
3474 if (command->execute())
3476 GuiContext::getCurrent()->getInvoc()->add(command);
3479 else delete command;
3483 // ----------------------------------------------------------------------------
3485 SubjectDataPort::SubjectDataPort(YACS::ENGINE::DataPort* port, Subject *parent)
3486 : Subject(parent), _dataPort(port)
3488 _listSubjectLink.clear();
3492 SubjectDataPort::~SubjectDataPort()
3494 DEBTRACE("SubjectDataPort::~SubjectDataPort " << getName());
3495 if (isDestructible())
3497 Node* node = _dataPort->getNode();
3499 ElementaryNode * father = dynamic_cast<ElementaryNode*>(node);
3502 DEBTRACE("father->edRemovePort(_dataPort)");
3505 father->edRemovePort(_dataPort);
3507 catch (YACS::Exception &e)
3509 DEBTRACE("------------------------------------------------------------------------------");
3510 DEBTRACE("SubjectDataPort::~SubjectDataPort: father->edRemovePort: YACS exception " << e.what());
3511 DEBTRACE("------------------------------------------------------------------------------");
3517 void SubjectDataPort::clean(Command *command)
3519 if (_askRegisterUndo)
3521 _askRegisterUndo = false;
3522 registerUndoDestroy();
3524 localclean(command);
3525 Subject::clean(command);
3528 void SubjectDataPort::localclean(Command *command)
3530 DEBTRACE("SubjectDataPort::localClean ");
3531 list<SubjectLink*> lsl = getListOfSubjectLink();
3532 for (list<SubjectLink*>::iterator it = lsl.begin(); it != lsl.end(); ++it)
3536 std::string SubjectDataPort::getName()
3538 return _dataPort->getName();
3541 bool SubjectDataPort::setName(std::string name)
3543 DEBTRACE("SubjectDataPort::setName " << name);
3544 Proc *proc = GuiContext::getCurrent()->getProc();
3545 string position = "";
3546 Node *node = getPort()->getNode();
3547 if (proc != dynamic_cast<Proc*>(node))
3548 position = proc->getChildName(node);
3550 position = node->getName();
3552 Command *command = 0;
3553 bool isIn = dynamic_cast<InPort*>(_dataPort);
3555 command = new CommandRenameInDataPort(position, _dataPort->getName(),name, getType());
3557 command = new CommandRenameOutDataPort(position, _dataPort->getName(),name, getType());
3559 if (command->execute())
3561 GuiContext::getCurrent()->getInvoc()->add(command);
3564 else delete command;
3568 YACS::ENGINE::DataPort* SubjectDataPort::getPort()
3573 bool SubjectDataPort::tryCreateLink(SubjectDataPort *subOutport, SubjectDataPort *subInport,bool control)
3575 DEBTRACE("SubjectDataPort::tryCreateLink");
3577 InPort *inp = dynamic_cast<InPort*>(subInport->getPort());
3578 OutPort *outp = dynamic_cast<OutPort*>(subOutport->getPort());
3579 if (outp && outp->isAlreadyLinkedWith(inp))
3581 DEBTRACE("isAlreadyLinkedWith");
3582 GuiContext::getCurrent()->_lastErrorMessage = "Ports are already linked";
3586 Proc *proc = GuiContext::getCurrent()->getProc();
3588 string outNodePos = "";
3589 SubjectNode *sno = dynamic_cast<SubjectNode*>(subOutport->getParent());
3591 Node *outNode = sno->getNode();
3592 outNodePos = proc->getChildName(outNode);
3593 string outportName = subOutport->getName();
3595 string inNodePos = "";
3596 SubjectNode *sni = dynamic_cast<SubjectNode*>(subInport->getParent());
3598 Node *inNode = sni->getNode();
3599 inNodePos = proc->getChildName(inNode);
3600 string inportName = subInport->getName();
3602 CommandAddLink *command = new CommandAddLink(outNodePos, outportName, subOutport->getType(),
3603 inNodePos, inportName, subInport->getType(), control);
3604 if (command->execute())
3606 GuiContext::getCurrent()->getInvoc()->add(command);
3616 /*! Generic method do nothing.
3617 * Implementation in SubjectInputPort and SubjectOutputPort.
3619 bool SubjectDataPort::setValue(std::string value)
3624 void SubjectDataPort::setExecValue(std::string value)
3629 std::string SubjectDataPort::getExecValue()
3634 void SubjectDataPort::registerUndoDestroy()
3636 DEBTRACE("SubjectDataPort::registerUndoDestroy");
3637 Proc *proc = GuiContext::getCurrent()->getProc();
3638 SubjectNode *sno = dynamic_cast<SubjectNode*>(getParent());
3640 Node *node = sno->getNode();
3641 string nodeName = proc->getChildName(node);
3642 string portName = getName();
3643 ElementaryNode* father = dynamic_cast<ElementaryNode*>(node);
3646 DataPort *port = getPort();
3647 TypeCode *dtyp = port->edGetType();
3648 string typeName = dtyp->name();
3649 Catalog *undoCata = GuiContext::getCurrent()->getInvoc()->getUndoCata();
3650 undoCata->_typeMap[typeName] = dtyp;
3652 Command *command = 0;
3654 TypeOfElem elemType = getType();
3658 command = new CommandAddInputPortFromCatalog(undoCata, typeName, nodeName, portName);
3662 list<InputPort*> plist = father->getSetOfInputPort();
3663 list<InputPort*>::iterator pos = plist.begin();
3664 for (; (*pos) != port; pos++)
3666 nbUp = plist.size() -rang;
3668 comm2 = new CommandOrderInputPorts(nodeName, portName, nbUp);
3672 command = new CommandAddOutputPortFromCatalog(undoCata, typeName, nodeName, portName);
3676 list<OutputPort*> plist = father->getSetOfOutputPort();
3677 list<OutputPort*>::iterator pos = plist.begin();
3678 for (; (*pos) != port; pos++)
3680 nbUp = plist.size() -rang;
3682 comm2 = new CommandOrderOutputPorts(nodeName, portName, nbUp);
3685 case INPUTDATASTREAMPORT:
3686 command = new CommandAddIDSPortFromCatalog(undoCata, typeName, nodeName, portName);
3688 case OUTPUTDATASTREAMPORT:
3689 command = new CommandAddODSPortFromCatalog(undoCata, typeName, nodeName, portName);
3693 GuiContext::getCurrent()->getInvoc()->add(command);
3695 GuiContext::getCurrent()->getInvoc()->add(comm2);
3697 list<SubjectLink*> lsl = getListOfSubjectLink();
3698 for (list<SubjectLink*>::iterator it = lsl.begin(); it != lsl.end(); ++it)
3700 (*it)->registerUndoDestroy();
3705 // ----------------------------------------------------------------------------
3707 SubjectInputPort::SubjectInputPort(YACS::ENGINE::InputPort *port, Subject *parent)
3708 : SubjectDataPort(port, parent), _inputPort(port)
3710 Node *node = _inputPort->getNode();
3711 if (ForLoop* forloop = dynamic_cast<ForLoop*>(node))
3713 if (_inputPort->getName() == "nsteps") _destructible = false;
3715 else if (WhileLoop* whileloop = dynamic_cast<WhileLoop*>(node))
3717 if (_inputPort->getName() == "condition") _destructible = false;
3719 else if (Switch* aSwitch = dynamic_cast<Switch*>(node))
3721 if (_inputPort->getName() == "select") _destructible = false;
3723 else if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
3725 if (_inputPort->getName() == "nbBranches") _destructible = false;
3727 else if (OptimizerLoop* optil = dynamic_cast<OptimizerLoop*>(node))
3729 if (_inputPort->getName() == "nbBranches") _destructible = false;
3731 else if (SplitterNode* split = dynamic_cast<SplitterNode*>(node))
3733 if (_inputPort->getName() == "SmplsCollection") _destructible = false;
3738 SubjectInputPort::~SubjectInputPort()
3740 DEBTRACE("SubjectInputPort::~SubjectInputPort " << getName());
3743 void SubjectInputPort::clean(Command *command)
3745 if (_askRegisterUndo)
3747 _askRegisterUndo = false;
3748 registerUndoDestroy();
3750 localclean(command);
3751 SubjectDataPort::clean(command);
3754 void SubjectInputPort::localclean(Command *command)
3756 DEBTRACE("SubjectInputPort::localClean ");
3759 SubjectElementaryNode* elem = dynamic_cast<SubjectElementaryNode*>(_parent);
3760 if (elem) elem->removePort(this);
3764 bool SubjectInputPort::setValue(std::string value)
3766 DEBTRACE("SubjectInputPort::setValue " << value);
3767 Proc *proc = GuiContext::getCurrent()->getProc();
3768 CommandSetInPortValue *command =
3769 new CommandSetInPortValue(proc->getChildName(getPort()->getNode()), getName(), value);
3770 if (command->execute())
3772 GuiContext::getCurrent()->getInvoc()->add(command);
3775 else delete command;
3779 // ----------------------------------------------------------------------------
3781 SubjectOutputPort::SubjectOutputPort(YACS::ENGINE::OutputPort *port, Subject *parent)
3782 : SubjectDataPort(port, parent), _outputPort(port)
3784 if (DynParaLoop* dynloop = dynamic_cast<DynParaLoop*>(_outputPort->getNode()))
3786 if (_outputPort == dynloop->edGetSamplePort()) _destructible = false;
3790 SubjectOutputPort::~SubjectOutputPort()
3792 DEBTRACE("SubjectOutputPort::~SubjectOutputPort " << getName());
3795 void SubjectOutputPort::clean(Command *command)
3797 if (_askRegisterUndo)
3799 _askRegisterUndo = false;
3800 registerUndoDestroy();
3802 localclean(command);
3803 SubjectDataPort::clean(command);
3806 void SubjectOutputPort::localclean(Command *command)
3808 DEBTRACE("SubjectOutputPort::localClean ");
3811 SubjectElementaryNode* elem = dynamic_cast<SubjectElementaryNode*>(_parent);
3812 if (elem) elem->removePort(this);
3816 bool SubjectOutputPort::setValue(std::string value)
3818 DEBTRACE("SubjectOutputPort::setValue " << value);
3819 Proc *proc = GuiContext::getCurrent()->getProc();
3820 CommandSetOutPortValue *command =
3821 new CommandSetOutPortValue(proc->getChildName(getPort()->getNode()), getName(), value);
3822 if (command->execute())
3824 GuiContext::getCurrent()->getInvoc()->add(command);
3827 else delete command;
3831 // ----------------------------------------------------------------------------
3833 SubjectInputDataStreamPort::SubjectInputDataStreamPort(YACS::ENGINE::InputDataStreamPort *port,
3835 : SubjectDataPort(port, parent), _inputDataStreamPort(port)
3839 SubjectInputDataStreamPort::~SubjectInputDataStreamPort()
3841 DEBTRACE("SubjectInputDataStreamPort::~SubjectInputDataStreamPort " << getName());
3844 std::map<std::string, std::string> SubjectInputDataStreamPort::getProperties()
3846 return _inputDataStreamPort->getProperties();
3849 std::vector<std::string> SubjectInputDataStreamPort::knownProperties()
3851 std::vector<std::string> props;
3852 props.push_back("StorageLevel");
3853 //props.push_back("DependencyType");
3854 props.push_back("DateCalSchem");
3855 props.push_back("Alpha");
3856 props.push_back("DeltaT");
3857 props.push_back("InterpolationSchem");
3858 props.push_back("ExtrapolationSchem");
3862 bool SubjectInputDataStreamPort::setProperties(std::map<std::string, std::string> properties)
3864 Proc *proc = GuiContext::getCurrent()->getProc();
3865 CommandSetDSPortProperties *command =
3866 new CommandSetDSPortProperties(proc->getChildName(getPort()->getNode()), getName(), true, properties);
3867 if (command->execute())
3869 GuiContext::getCurrent()->getInvoc()->add(command);
3872 else delete command;
3876 void SubjectInputDataStreamPort::clean(Command *command)
3878 if (_askRegisterUndo)
3880 _askRegisterUndo = false;
3881 registerUndoDestroy();
3883 localclean(command);
3884 SubjectDataPort::clean(command);
3887 void SubjectInputDataStreamPort::localclean(Command *command)
3889 DEBTRACE("SubjectInputDataStreamPort::localClean ");
3892 void SubjectInputDataStreamPort::registerUndoDestroy()
3894 DEBTRACE("SubjectInputDataStreamPort::registerUndoDestroy");
3895 SubjectDataPort::registerUndoDestroy();
3896 map<string,string> properties = getProperties();
3897 if (properties.empty())
3899 Proc *proc = GuiContext::getCurrent()->getProc();
3900 SubjectNode *sno = dynamic_cast<SubjectNode*>(getParent());
3902 Node *node = sno->getNode();
3903 string nodeName = proc->getChildName(node);
3904 string portName = getName();
3905 Command *command = new CommandSetDSPortProperties(nodeName, portName, true, properties);
3906 GuiContext::getCurrent()->getInvoc()->add(command);
3909 // ----------------------------------------------------------------------------
3911 SubjectOutputDataStreamPort::SubjectOutputDataStreamPort(YACS::ENGINE::OutputDataStreamPort *port,
3913 : SubjectDataPort(port, parent), _outputDataStreamPort(port)
3917 SubjectOutputDataStreamPort::~SubjectOutputDataStreamPort()
3919 DEBTRACE("SubjectOutputDataStreamPort::~SubjectOutputDataStreamPort " << getName());
3922 std::map<std::string, std::string> SubjectOutputDataStreamPort::getProperties()
3924 return _outputDataStreamPort->getProperties();
3927 bool SubjectOutputDataStreamPort::setProperties(std::map<std::string, std::string> properties)
3929 Proc *proc = GuiContext::getCurrent()->getProc();
3930 CommandSetDSPortProperties *command =
3931 new CommandSetDSPortProperties(proc->getChildName(getPort()->getNode()), getName(), false, properties);
3932 if (command->execute())
3934 GuiContext::getCurrent()->getInvoc()->add(command);
3937 else delete command;
3941 void SubjectOutputDataStreamPort::clean(Command *command)
3943 if (_askRegisterUndo)
3945 _askRegisterUndo = false;
3946 registerUndoDestroy();
3948 localclean(command);
3949 SubjectDataPort::clean(command);
3952 void SubjectOutputDataStreamPort::localclean(Command *command)
3954 DEBTRACE("SubjectOutputDataStreamPort::localClean ");
3957 void SubjectOutputDataStreamPort::registerUndoDestroy()
3959 DEBTRACE("SubjectOutputDataStreamPort::registerUndoDestroy");
3960 SubjectDataPort::registerUndoDestroy();
3961 map<string,string> properties = getProperties();
3962 if (properties.empty())
3964 Proc *proc = GuiContext::getCurrent()->getProc();
3965 SubjectNode *sno = dynamic_cast<SubjectNode*>(getParent());
3967 Node *node = sno->getNode();
3968 string nodeName = proc->getChildName(node);
3969 string portName = getName();
3970 Command *command = new CommandSetDSPortProperties(nodeName, portName, false, properties);
3971 GuiContext::getCurrent()->getInvoc()->add(command);
3974 // ----------------------------------------------------------------------------
3976 SubjectLink::SubjectLink(SubjectNode* subOutNode,
3977 SubjectDataPort* outPort,
3978 SubjectNode* subInNode,
3979 SubjectDataPort* inPort,
3982 _subOutNode(subOutNode), _outPort(outPort), _subInNode(subInNode), _inPort(inPort)
3985 ComposedNode *cla = ComposedNode::getLowestCommonAncestor(_subOutNode->getNode()->getFather(),
3986 _subInNode->getNode()->getFather());
3987 DEBTRACE(_subOutNode->getName() << "." << _outPort->getName());
3988 DEBTRACE(_subInNode->getName() << "." << _inPort->getName());
3989 DEBTRACE(cla->getName());
3990 _name += cla->getChildName(_subOutNode->getNode());
3991 _name += "." + _outPort->getName();
3993 _name += cla->getChildName(_subInNode->getNode());
3994 _name += "." + _inPort->getName();
3995 DEBTRACE("SubjectLink::SubjectLink " << _name);
3998 SubjectLink::~SubjectLink()
4000 DEBTRACE("SubjectLink::~SubjectLink " << getName());
4001 _inPort->update(UPDATE,DATALINK,_outPort);
4002 _outPort->update(UPDATE,DATALINK,_inPort);
4005 void SubjectLink::clean(Command *command)
4007 if (_askRegisterUndo)
4009 _askRegisterUndo = false;
4010 registerUndoDestroy();
4012 localclean(command);
4013 Subject::clean(command);
4016 void SubjectLink::localclean(Command *command)
4018 DEBTRACE("SubjectLink::localClean ");
4021 DEBTRACE("clean link: " << _parent->getName() << " " << getName());
4022 SubjectComposedNode* father = dynamic_cast<SubjectComposedNode*>(_parent);
4024 father->removeLink(this); // --- clean subjects first
4025 _cla = dynamic_cast<ComposedNode*>(father->getNode());
4027 _outp = dynamic_cast<OutPort*>(_outPort->getPort());
4029 _inp = dynamic_cast<InPort*>(_inPort->getPort());
4031 if (isDestructible())
4032 _cla->edRemoveLink(_outp, _inp);
4036 std::string SubjectLink::getName()
4041 std::map<std::string, std::string> SubjectLink::getProperties()
4043 return getSubjectInPort()->getProperties();
4046 std::vector<std::string> SubjectLink::knownProperties()
4048 return getSubjectInPort()->knownProperties();
4051 bool SubjectLink::setProperties(std::map<std::string, std::string> properties)
4053 Proc *proc = GuiContext::getCurrent()->getProc();
4054 CommandSetLinkProperties *command =
4055 new CommandSetLinkProperties(proc->getChildName(getSubjectOutPort()->getPort()->getNode()), getSubjectOutPort()->getName(),
4056 proc->getChildName(getSubjectInPort()->getPort()->getNode()), getSubjectInPort()->getName(),
4058 if (command->execute())
4060 GuiContext::getCurrent()->getInvoc()->add(command);
4063 else delete command;
4067 void SubjectLink::registerUndoDestroy()
4069 DEBTRACE("SubjectLink::registerUndoDestroy");
4070 Proc *proc = GuiContext::getCurrent()->getProc();
4071 Node *outn = getSubjectOutNode()->getNode();
4072 Node *inn = getSubjectInNode()->getNode();
4073 DataPort *outp = getSubjectOutPort()->getPort();
4074 DataPort *inp = getSubjectInPort()->getPort();
4075 CommandAddLink *command = new CommandAddLink(proc->getChildName(outn),
4077 getSubjectOutPort()->getType(),
4078 proc->getChildName(inn),
4080 getSubjectInPort()->getType(),
4082 GuiContext::getCurrent()->getInvoc()->add(command);
4084 map<string, string> properties = getProperties();
4085 if (properties.empty())
4088 CommandSetLinkProperties *command2 = new CommandSetLinkProperties(proc->getChildName(outn),
4090 proc->getChildName(inn),
4093 GuiContext::getCurrent()->getInvoc()->add(command2);
4096 // ----------------------------------------------------------------------------
4098 SubjectControlLink::SubjectControlLink(SubjectNode* subOutNode,
4099 SubjectNode* subInNode,
4102 _subOutNode(subOutNode), _subInNode(subInNode)
4105 ComposedNode *cla = ComposedNode::getLowestCommonAncestor(_subOutNode->getNode()->getFather(),
4106 _subInNode->getNode()->getFather());
4107 DEBTRACE(_subOutNode->getName());
4108 DEBTRACE(_subInNode->getName());
4109 DEBTRACE(cla->getName());
4110 _name += cla->getChildName(_subOutNode->getNode());
4112 _name += cla->getChildName(_subInNode->getNode());
4113 DEBTRACE("SubjectControlLink::SubjectControlLink " << _name);
4116 SubjectControlLink::~SubjectControlLink()
4118 DEBTRACE("SubjectControlLink::~SubjectControlLink " << getName());
4119 if (isDestructible())
4124 _cla->edRemoveCFLink(_subOutNode->getNode(), _subInNode->getNode());
4126 catch (YACS::Exception &e)
4128 DEBTRACE("------------------------------------------------------------------------------");
4129 DEBTRACE("SubjectControlLink::~SubjectControlLink: edRemoveLink YACS exception " << e.what());
4130 DEBTRACE("------------------------------------------------------------------------------");
4135 void SubjectControlLink::clean(Command *command)
4137 if (_askRegisterUndo)
4139 _askRegisterUndo = false;
4140 registerUndoDestroy();
4142 localclean(command);
4143 Subject::clean(command);
4146 void SubjectControlLink::localclean(Command *command)
4148 DEBTRACE("SubjectControlLink::localClean ");
4151 DEBTRACE("clean control link: " << _parent->getName() << " " << getName());
4152 SubjectComposedNode* father = dynamic_cast<SubjectComposedNode*>(_parent);
4154 father->removeControlLink(this); // --- clean subjects first
4155 _cla = dynamic_cast<ComposedNode*>(father->getNode());
4160 std::string SubjectControlLink::getName()
4165 void SubjectControlLink::registerUndoDestroy()
4167 DEBTRACE("SubjectControlLink::registerUndoDestroy");
4168 Proc *proc = GuiContext::getCurrent()->getProc();
4169 Node *outn = getSubjectOutNode()->getNode();
4170 Node *inn = getSubjectInNode()->getNode();
4171 CommandAddControlLink *command = new CommandAddControlLink(proc->getChildName(outn),
4172 proc->getChildName(inn));
4173 GuiContext::getCurrent()->getInvoc()->add(command);
4176 // ----------------------------------------------------------------------------
4178 SubjectComponent::SubjectComponent(YACS::ENGINE::ComponentInstance* component, Subject *parent)
4179 : Subject(parent), _compoInst(component)
4181 _compoInst->incrRef();
4182 _subRefContainer = 0;
4183 _subServiceSet.clear();
4184 _subReferenceMap.clear();
4187 SubjectComponent::~SubjectComponent()
4189 Proc* aProc = GuiContext::getCurrent()->getProc();
4192 aProc->componentInstanceMap.erase(_compoInst->getInstanceName());
4193 GuiContext::getCurrent()->_mapOfSubjectComponent.erase(_compoInst);
4195 _compoInst->decrRef();
4198 void SubjectComponent::clean(Command *command)
4200 if (_askRegisterUndo)
4202 _askRegisterUndo = false;
4203 registerUndoDestroy();
4205 localclean(command);
4206 Subject::clean(command);
4209 void SubjectComponent::localclean(Command *command)
4211 DEBTRACE("SubjectComponent::localClean " << this);
4212 Proc* aProc = GuiContext::getCurrent()->getProc();
4215 std::map<Node*, SubjectNode*>::iterator it = GuiContext::getCurrent()->_mapOfSubjectNode.begin();
4216 std::list<SubjectNode*> services;
4217 for ( ; it!=GuiContext::getCurrent()->_mapOfSubjectNode.end(); it++ )
4219 if(ServiceNode* service=dynamic_cast<ServiceNode*>((*it).first))
4221 if ( service->getComponent() == _compoInst )
4223 services.push_back((*it).second);
4227 while(!services.empty())
4229 SubjectNode* son=services.front();
4230 services.pop_front();
4231 Subject* parent=son->getParent();
4232 // parent->update(REMOVE,son->getType(),son);
4234 parent->update(REMOVE,0,0);
4237 Container* container = _compoInst->getContainer();
4238 if (!container) return;
4239 SubjectContainer *subContainer;
4240 YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(container));
4241 subContainer = GuiContext::getCurrent()->_mapOfSubjectContainer[container];
4242 subContainer->removeSubComponentFromSet(this);
4246 std::string SubjectComponent::getName()
4248 return _compoInst->getInstanceName();
4251 std::pair<std::string, int> SubjectComponent::getKey()
4253 std::pair<std::string, int> key = std::pair<std::string, int>(_compoInst->getCompoName(), _compoInst->getNumId());
4257 YACS::ENGINE::ComponentInstance* SubjectComponent::getComponent() const
4263 * When loading scheme from file, get the container associated to the component, if any,
4264 * and create the corresponding subject.
4266 void SubjectComponent::setContainer()
4268 DEBTRACE("SubjectComponent::setContainer " << getName());
4269 Container* container = _compoInst->getContainer();
4272 SubjectContainer *subContainer;
4273 if (GuiContext::getCurrent()->_mapOfSubjectContainer.count(container))
4274 subContainer = GuiContext::getCurrent()->_mapOfSubjectContainer[container];
4277 GuiContext::getCurrent()->getSubjectProc()->addSubjectContainer(container, container->getName());
4278 addSubjectReference(subContainer);
4279 if (_subRefContainer)
4280 subContainer->moveComponent(_subRefContainer);
4282 _subRefContainer = subContainer->attachComponent(this);
4283 notifyServicesChange(ASSOCIATE, CONTAINER, subContainer);
4287 bool SubjectComponent::associateToContainer(SubjectContainer* subcont)
4289 DEBTRACE("SubjectComponent::associateToContainer " << getName() << " " << subcont->getName());
4290 CommandAssociateComponentToContainer *command =
4291 new CommandAssociateComponentToContainer(_compoInst->getInstanceName(), subcont->getName());
4292 if (command->execute())
4294 if (!GuiContext::getCurrent()->isLoading()) // do not register command when loading a schema
4295 GuiContext::getCurrent()->getInvoc()->add(command);
4296 else delete command;
4299 else delete command;
4303 SubjectReference* SubjectComponent::attachService(SubjectServiceNode* service)
4305 DEBTRACE("SubjectComponent::attachService");
4306 SubjectReference *son = new SubjectReference(service, this);
4307 _subServiceSet.insert(service);
4308 _subReferenceMap[service] = son;
4309 update(ADDCHILDREF, SALOMENODE, son);
4313 void SubjectComponent::detachService(SubjectServiceNode* service)
4315 DEBTRACE("SubjectComponent::detachService");
4316 YASSERT(_subReferenceMap.count(service));
4317 SubjectReference *reference = _subReferenceMap[service];
4318 update(REMOVECHILDREF, SALOMENODE, reference);
4319 _subServiceSet.erase(service);
4320 _subReferenceMap.erase(service);
4321 service->removeSubRefComponent();
4325 void SubjectComponent::moveService(SubjectReference* reference)
4327 DEBTRACE("SubjectComponent::moveService");
4328 SubjectComponent* oldcomp = dynamic_cast<SubjectComponent*>(reference->getParent());
4331 SubjectServiceNode* service = dynamic_cast<SubjectServiceNode*>(reference->getReference());
4332 oldcomp->removeSubServiceFromSet(service);
4333 _subServiceSet.insert(service);
4334 _subReferenceMap[service] = reference;
4335 oldcomp->update(CUT, SALOMENODE, reference);
4336 reference->reparent(this);
4337 update(PASTE, SALOMENODE, reference);
4338 if (!oldcomp->hasServices())
4339 Subject::erase(oldcomp);
4342 void SubjectComponent::removeSubServiceFromSet(SubjectServiceNode *service)
4344 DEBTRACE("SubjectComponent::removeSubServiceFromSet " << getName() << " " << service->getName());
4345 _subServiceSet.erase(service);
4346 _subReferenceMap.erase(service);
4349 void SubjectComponent::notifyServicesChange(GuiEvent event, int type, Subject* son)
4351 DEBTRACE("SubjectComponent::notifyServicesChange");
4352 set<SubjectServiceNode*>::iterator it = _subServiceSet.begin();
4353 for(; it != _subServiceSet.end(); ++it)
4355 (*it)->update(event, type, son);
4359 bool SubjectComponent::setProperties(std::map<std::string, std::string> properties)
4361 CommandSetComponentInstanceProperties *command = new CommandSetComponentInstanceProperties(getName(), properties);
4362 if (command->execute())
4364 GuiContext::getCurrent()->getInvoc()->add(command);
4367 else delete command;
4371 std::map<std::string, std::string> SubjectComponent::getProperties()
4373 return _compoInst->getProperties();
4376 // ----------------------------------------------------------------------------
4378 SubjectContainer::SubjectContainer(YACS::ENGINE::Container* container, Subject *parent)
4379 : Subject(parent), _container(container)
4381 _subComponentSet.clear();
4382 _subReferenceMap.clear();
4385 SubjectContainer::~SubjectContainer()
4387 DEBTRACE("SubjectContainer::~SubjectContainer");
4388 Proc* aProc = GuiContext::getCurrent()->getProc();
4391 map<ComponentInstance*,SubjectComponent*> mapOfSubjectComponentCpy
4392 = GuiContext::getCurrent()->_mapOfSubjectComponent;
4393 map<ComponentInstance*,SubjectComponent*>::iterator it = mapOfSubjectComponentCpy.begin();
4394 for ( ; it!=mapOfSubjectComponentCpy.end(); it++ )
4395 if ( (*it).first && (*it).first->getContainer() == _container )
4397 (*it).first->setContainer(0);
4398 GuiContext::getCurrent()->getSubjectProc()->destroy((*it).second);
4401 GuiContext::getCurrent()->_mapOfSubjectContainer.erase(_container);
4402 aProc->removeContainer(_container);
4406 std::map<std::string, std::string> SubjectContainer::getProperties()
4408 return _container->getProperties();
4411 bool SubjectContainer::setProperties(std::map<std::string, std::string> properties)
4413 CommandSetContainerProperties *command = new CommandSetContainerProperties(getName(), properties);
4414 if (command->execute())
4416 GuiContext::getCurrent()->getInvoc()->add(command);
4419 else delete command;
4423 bool SubjectContainer::setName(std::string name)
4425 DEBTRACE("SubjectContainer::setName " << name);
4426 if (name == getName())
4428 CommandRenameContainer* command = new CommandRenameContainer(getName(), name);
4429 if (command->execute())
4431 GuiContext::getCurrent()->getInvoc()->add(command);
4434 else delete command;
4438 SubjectReference* SubjectContainer::attachComponent(SubjectComponent* component)
4440 DEBTRACE("SubjectContainer::attachComponent");
4441 SubjectReference *son = new SubjectReference(component, this);
4442 _subComponentSet.insert(component);
4443 _subReferenceMap[component] = son;
4444 update(ADDCHILDREF, COMPONENT, son);
4448 void SubjectContainer::detachComponent(SubjectComponent* component)
4450 DEBTRACE("SubjectContainer::detachComponent");
4451 YASSERT(_subReferenceMap.count(component));
4452 SubjectReference *reference = _subReferenceMap[component];
4453 update(REMOVECHILDREF, COMPONENT, reference);
4454 _subComponentSet.erase(component);
4455 _subReferenceMap.erase(component);
4459 void SubjectContainer::moveComponent(SubjectReference* reference)
4461 DEBTRACE("SubjectContainer::moveComponent");
4462 SubjectContainer* oldcont = dynamic_cast<SubjectContainer*>(reference->getParent());
4464 SubjectComponent* component = dynamic_cast<SubjectComponent*>(reference->getReference());
4465 _subComponentSet.insert(component);
4466 _subReferenceMap[component] = reference;
4467 oldcont->removeSubComponentFromSet(component);
4468 oldcont->update(CUT, COMPONENT, reference);
4469 reference->reparent(this);
4470 update(PASTE, COMPONENT, reference);
4473 void SubjectContainer::removeSubComponentFromSet(SubjectComponent *component)
4475 DEBTRACE("SubjectContainer::removeSubComponentFromSet");
4476 _subComponentSet.erase(component);
4477 _subReferenceMap.erase(component);
4480 void SubjectContainer::notifyComponentsChange(GuiEvent event, int type, Subject* son)
4482 DEBTRACE("SubjectContainer::notifyComponentsChange");
4483 set<SubjectComponent*>::iterator it = _subComponentSet.begin();
4484 for(; it != _subComponentSet.end(); ++it)
4486 (*it)->update(event, type, son);
4487 (*it)->notifyServicesChange(event, type, son);
4492 void SubjectContainer::clean(Command *command)
4494 if (_askRegisterUndo)
4496 _askRegisterUndo = false;
4497 registerUndoDestroy();
4499 localclean(command);
4500 Subject::clean(command);
4503 void SubjectContainer::localclean(Command *command)
4505 DEBTRACE("SubjectContainer::localClean ");
4506 Proc* aProc = GuiContext::getCurrent()->getProc();
4509 SubjectComponent* compo;
4510 map<ComponentInstance*,SubjectComponent*>::iterator it = GuiContext::getCurrent()->_mapOfSubjectComponent.begin();
4511 std::list<SubjectComponent*> compos;
4512 for ( ; it!=GuiContext::getCurrent()->_mapOfSubjectComponent.end(); it++ )
4513 if ( (*it).first && (*it).first->getContainer() == _container )
4516 (*it).first->setContainer(0);
4517 compos.push_back((*it).second);
4519 while(!compos.empty())
4521 compo=compos.front();
4523 GuiContext::getCurrent()->getSubjectProc()->update(REMOVE,compo->getType(),compo);
4524 GuiContext::getCurrent()->getSubjectProc()->erase(compo);
4529 std::string SubjectContainer::getName()
4531 return _container->getName();
4534 YACS::ENGINE::Container* SubjectContainer::getContainer() const
4539 void SubjectContainer::registerUndoDestroy()
4541 DEBTRACE("SubjectContainer::registerUndoDestroy");
4542 Command *command = new CommandAddContainer(getName(),"");
4543 GuiContext::getCurrent()->getInvoc()->add(command);
4546 // ----------------------------------------------------------------------------
4548 SubjectDataType::SubjectDataType(YACS::ENGINE::TypeCode *typeCode, Subject *parent, std::string alias)
4549 : Subject(parent), _typeCode(typeCode), _alias(alias)
4553 SubjectDataType::~SubjectDataType()
4557 void SubjectDataType::clean(Command *command)
4559 if (_askRegisterUndo)
4561 _askRegisterUndo = false;
4562 registerUndoDestroy();
4564 localclean(command);
4565 Subject::clean(command);
4568 void SubjectDataType::localclean(Command *command)
4570 DEBTRACE("SubjectDataType::localClean ");
4573 std::string SubjectDataType::getName()
4575 return _typeCode->name();
4578 std::string SubjectDataType::getAlias()
4583 YACS::ENGINE::TypeCode* SubjectDataType::getTypeCode()
4588 // ----------------------------------------------------------------------------