+// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
#include "Proc.hxx"
#include "ElementaryNode.hxx"
#include "Runtime.hxx"
#include "Container.hxx"
+#include "ComponentInstance.hxx"
#include "InputPort.hxx"
#include "OutputPort.hxx"
#include "TypeCode.hxx"
#include "Logger.hxx"
#include "Visitor.hxx"
+#include "VisitorSaveSchema.hxx"
+#include "VisitorSaveState.hxx"
#include <sstream>
#include <set>
using namespace std;
using namespace YACS::ENGINE;
-Proc::Proc(const std::string& name):Bloc(name),_edition(false)
+/*! \class YACS::ENGINE::Proc
+ * \brief Base class for all schema objects.
+ *
+ * This is an abstract class that must be specialized in runtime.
+ * \ingroup Nodes
+ */
+
+Proc::Proc(const std::string& name):Bloc(name),_edition(false),_compoinstctr(0)
{
Runtime *theRuntime=getRuntime();
DEBTRACE("theRuntime->_tc_double->ref: " << theRuntime->_tc_double->getRefCnt());
for(pt=typeMap.begin();pt!=typeMap.end();pt++)
((*pt).second)->decrRef();
- //get rid of containers in container map
- std::map<std::string, Container*>::const_iterator it;
- for(it=containerMap.begin();it!=containerMap.end();it++)
- ((*it).second)->decrRef();
+ removeContainers();
//get rid of loggers in logger map
std::map<std::string, Logger*>::const_iterator lt;
os << "digraph " << getQualifiedName() << " {\n" ;
os << "node [ style=\"filled\" ];\n" ;
os << "compound=true;";
+ os << "states [label=< <TABLE> <TR> <TD BGCOLOR=\"pink\" > Ready</TD> <TD BGCOLOR=\"magenta\" > Toload</TD> </TR> <TR> <TD BGCOLOR=\"magenta\" > Loaded</TD> <TD BGCOLOR=\"purple\" > Toactivate</TD> </TR> <TR> <TD BGCOLOR=\"blue\" > Activated</TD> <TD BGCOLOR=\"green\" > Done</TD> </TR> <TR> <TD BGCOLOR=\"red\" > Error</TD> <TD BGCOLOR=\"orange\" > Failed</TD> </TR> <TR> <TD BGCOLOR=\"grey\" > Disabled</TD> <TD BGCOLOR=\"white\" > Pause</TD> </TR> </TABLE>> \n shape = plaintext \n style = invis \n ];\n";
+
Bloc::writeDot(os);
os << "}\n" ;
}
else
throw Exception("Unknown kind");
+ if(typeMap.count(name)!=0)
+ typeMap[name]->decrRef();
+ t->incrRef();
+ typeMap[name]=t;
t->incrRef();
return t;
}
+//! Create an object reference TypeCode
+/*!
+ * \param id: the TypeCode repository id
+ * \param name: the TypeCode name
+ * \param ltc: a liste of object reference TypeCode to use as base types for this type
+ * \return the created TypeCode
+ */
TypeCode *Proc::createInterfaceTc(const std::string& id, const std::string& name,
std::list<TypeCodeObjref *> ltc)
{
- return TypeCode::interfaceTc(id.c_str(),name.c_str(),ltc);
+ TypeCode* t = TypeCode::interfaceTc(id.c_str(),name.c_str(),ltc);
+ if(typeMap.count(name)!=0)
+ typeMap[name]->decrRef();
+ typeMap[name]=t;
+ t->incrRef();
+ return t;
}
+//! Create a sequence TypeCode
+/*!
+ * \param id: the TypeCode repository id ("" for normal use)
+ * \param name: the TypeCode name
+ * \param content: the element TypeCode
+ * \return the created TypeCode
+ */
TypeCode * Proc::createSequenceTc (const std::string& id, const std::string& name,
TypeCode *content)
{
- return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
+ TypeCode* t = TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
+ if(typeMap.count(name)!=0)
+ typeMap[name]->decrRef();
+ typeMap[name]=t;
+ t->incrRef();
+ return t;
}
TypeCode * Proc::createStructTc (const std::string& id, const std::string& name)
{
- return TypeCode::structTc(id.c_str(),name.c_str());
+ TypeCode* t = TypeCode::structTc(id.c_str(),name.c_str());
+ if(typeMap.count(name)!=0)
+ typeMap[name]->decrRef();
+ typeMap[name]=t;
+ t->incrRef();
+ return t;
}
TypeCode * Proc::getTypeCode (const std::string& name)
{
+ TypeCode* aTC=0;
if(typeMap.count(name)==0)
+ aTC=getRuntime()->getTypeCode(name);
+ else
+ aTC=typeMap[name];
+
+ if(!aTC)
{
std::stringstream msg;
msg << "Type " << name << " does not exist" ;
msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
throw Exception(msg.str());
}
- return typeMap[name];
+
+ return aTC;
}
void Proc::setTypeCode (const std::string& name,TypeCode *t)
if(typeMap.count(name)!=0)
typeMap[name]->decrRef();
typeMap[name]=t;
+ t->incrRef();
}
return state;
}
+std::string Proc::getNodeProgress(int numId)
+{
+ std::string progress = "0";
+ if(YACS::ENGINE::Node::idMap.count(numId) == 0)
+ {
+ cerr << "Unknown node id " << numId << endl;
+ }
+ else if (YACS::ENGINE::ComposedNode* node = dynamic_cast<YACS::ENGINE::ComposedNode*>(YACS::ENGINE::Node::idMap[numId]))
+ progress = node->getProgress();
+ return progress;
+}
+
+int Proc::getGlobalProgressPercent()
+{
+ list<pair <int,int> > weightList = getProgressWeight();
+ int weightDone = 0;
+ int weightTotal = 0;
+ int progressPercent = 0;
+ for(list<pair <int,int> >::const_iterator iter=weightList.begin();iter!=weightList.end();iter++)
+ {
+ weightDone += (*iter).first;
+ weightTotal += (*iter).second;
+ }
+ if (weightTotal > 0)
+ progressPercent = int(float(weightDone) / float(weightTotal) * 100);
+ return progressPercent;
+}
+
std::string Proc::getXMLState(int numId)
{
if(YACS::ENGINE::Node::idMap.count(numId) == 0)
{
YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
InputPort * inputPort = node->getInputPort(portName);
- return inputPort->dump();
+ return inputPort->getAsString();
}
catch(YACS::Exception& ex)
{
}
}
+std::string Proc::setInPortValue(std::string nodeName, std::string portName, std::string value)
+{
+ DEBTRACE("Proc::setInPortValue " << nodeName << " " << portName << " " << value);
+
+ try
+ {
+ YACS::ENGINE::Node* node = YACS::ENGINE::Proc::nodeMap[nodeName];
+ YACS::ENGINE::InputPort* inputPort = node->getInputPort(portName);
+
+ switch (inputPort->edGetType()->kind())
+ {
+ case Double:
+ {
+ double val = atof(value.c_str());
+ inputPort->edInit(val);
+ }
+ case Int:
+ {
+ int val = atoi(value.c_str());
+ inputPort->edInit(val);
+ }
+ case String:
+ inputPort->edInit(value.c_str());
+ case Bool:
+ {
+ bool val = (! value.compare("False") ) && (! value.compare("0") );
+ inputPort->edInit(val);
+ }
+ default:
+ DEBTRACE("Proc::setInPortValue: filtered type: " << inputPort->edGetType()->kind());
+ }
+ return value;
+ }
+ catch(YACS::Exception& ex)
+ {
+ DEBTRACE("Proc::setInPortValue " << ex.what());
+ stringstream msg;
+ msg << "<value><error>" << ex.what() << "</error></value>";
+ return msg.str();
+ }
+}
+
std::string Proc::getOutPortValue(int nodeNumId, std::string portName)
{
DEBTRACE("Proc::getOutPortValue " << nodeNumId << " " << portName);
{
YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
OutputPort * outputPort = node->getOutputPort(portName);
- return outputPort->dump();
+ return outputPort->getAsString();
}
catch(YACS::Exception& ex)
{
edUpdateState();
}
+//! Save Proc in XML schema file
+/*!
+ * \param xmlSchemaFile: the file name
+ */
+void Proc::saveSchema(const std::string& xmlSchemaFile)
+{
+ VisitorSaveSchema vss(this);
+ vss.openFileSchema(xmlSchemaFile);
+ accept(&vss);
+ vss.closeFileSchema();
+}
+
+//! Save Proc state in XML state file
+/*!
+ * \param xmlStateFile: the file name
+ */
+void Proc::saveState(const std::string& xmlStateFile)
+{
+ VisitorSaveState vst(this);
+ vst.openFileDump(xmlStateFile);
+ accept(&vst);
+ vst.closeFileDump();
+}
+
+void Proc::removeContainers()
+{
+ //get rid of containers in container map
+ std::map<std::string, Container*>::const_iterator it;
+ for(it=containerMap.begin();it!=containerMap.end();it++)
+ ((*it).second)->decrRef();
+ containerMap.clear();
+}
+
+//! Create a new Container and store it in containerMap
+/*!
+ * \param name: the container name and key in containerMap
+ * \param kind: the container kind (depends on runtime)
+ * \return the created Container
+ */
+Container *Proc::createContainer(const std::string& name, const std::string& kind)
+{
+ Container *co(getRuntime()->createContainer(kind));
+ co->setName(name);
+ if(containerMap.count(name)!=0)
+ containerMap[name]->decrRef();
+ containerMap[name]=co;
+ co->incrRef();
+ co->setProc(this);
+ return co;
+}
+
+//! Add a ComponentInstance into componentInstanceMap
+/*!
+ * If the name == "", the component instance is automatically named with a unique (in the Proc) name
+ *
+ * \param inst: the component instance
+ * \param name: the component instance name
+ * \param resetCtr: try to reuse instance number previously released, false by default
+ */
+void Proc::addComponentInstance(ComponentInstance* inst, const std::string& name, bool resetCtr)
+{
+ if(name != "")
+ {
+ inst->setName(name);
+ inst->setAnonymous(false);
+ if(componentInstanceMap.count(name)!=0)
+ componentInstanceMap[name]->decrRef();
+ componentInstanceMap[name]=inst;
+ inst->incrRef();
+ }
+ else
+ {
+ //automatic naming : componame_<_compoinstctr>
+ std::string instname;
+ std::string componame=inst->getCompoName();
+ if (resetCtr)
+ _compoinstctr = 0;
+ while(1)
+ {
+ std::ostringstream buffer;
+ buffer << ++_compoinstctr;
+ instname=componame+"_"+buffer.str();
+ if(componentInstanceMap.count(instname)==0)
+ {
+ inst->setName(instname);
+ componentInstanceMap[instname]=inst;
+ inst->incrRef();
+ break;
+ }
+ }
+ }
+}
+
+//! Remove a componentInstance from the componentInstanceMap
+/*!
+ * To be used for a componentInstance with no service nodes referenced.
+ *
+ * \param inst: the component instance
+ */
+void Proc::removeComponentInstance(ComponentInstance* inst)
+{
+ if (componentInstanceMap.count(inst->getInstanceName()))
+ {
+ componentInstanceMap.erase(inst->getInstanceName());
+ inst->decrRef();
+ }
+}
+
+//! Remove a container from the containerMap
+/*!
+ * To be used for a container with no componentInstance referenced.
+ *
+ * \param cont: the container
+ */
+void Proc::removeContainer(Container* cont)
+{
+ if (containerMap.count(cont->getName()))
+ {
+ containerMap.erase(cont->getName());
+ cont->decrRef();
+ }
+}
+
+//! Create a new ComponentInstance and add it into componentInstanceMap
+/*!
+ * If the name == "", the component instance is automatically named with a unique (in the Proc) name
+ *
+ * \param componame: the component name
+ * \param name: the component instance name
+ * \param kind: the component instance kind (depends on runtime)
+ * \return the created ComponentInstance
+ */
+ComponentInstance* Proc::createComponentInstance(const std::string& componame, const std::string& name,const std::string& kind)
+{
+ ComponentInstance* inst= getRuntime()->createComponentInstance(componame,kind);
+ addComponentInstance(inst,name);
+ return inst;
+}
+
+//! Return the proc (this)
+Proc* Proc::getProc()
+{
+ return this;
+}
+
+//! Return the proc (this)
+const Proc * Proc::getProc() const
+{
+ return this;
+}
+
+/*!
+ * This method is useful if this has been modified recursively and an update is needed between all the
+ * containers and components refered by children and little children and maps.
+ */
+void Proc::updateContainersAndComponents()
+{
+ std::map<std::string, Container*> myContainerMap;
+ std::map<std::string, ComponentInstance*> myComponentInstanceMap;
+ DeploymentTree treeToDup(getDeploymentTree());
+ vector<Container *> conts(treeToDup.getAllContainers());
+ for(vector<Container *>::const_iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
+ {
+ Container *tmp(*iterCt);
+ if(tmp)
+ {
+ if(myContainerMap.find(tmp->getName())!=myContainerMap.end())
+ {
+ std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one container instance with name \"" << tmp->getName() << "\" !";
+ throw YACS::Exception(oss.str());
+ }
+ myContainerMap[tmp->getName()]=tmp;
+ tmp->incrRef();
+ }
+ vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
+ for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
+ {
+ ComponentInstance *tmp2(*iterCp);
+ if(tmp2)
+ {
+ if(myComponentInstanceMap.find(tmp2->getCompoName())!=myComponentInstanceMap.end())
+ {
+ std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one component instance with name \"" << tmp2->getCompoName() << "\" !";
+ throw YACS::Exception(oss.str());
+ }
+ }
+ myComponentInstanceMap[tmp2->getCompoName()]=tmp2;
+ tmp2->incrRef();
+ }
+ }
+ removeContainers();
+ containerMap=myContainerMap;
+ componentInstanceMap=myComponentInstanceMap;
+}