X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fengine%2FProc.cxx;h=4cb7429557d682721059287de61881aa0e0fe619;hb=b1d9aaddeca3d5779537741601e7ef93e50ea71b;hp=9ccc9415d27747392a3ecdcf763a74e2dd43820a;hpb=313a04631c63078d01c2f643a53500ec549d034e;p=modules%2Fyacs.git diff --git a/src/engine/Proc.cxx b/src/engine/Proc.cxx index 9ccc9415d..4cb742955 100644 --- a/src/engine/Proc.cxx +++ b/src/engine/Proc.cxx @@ -1,12 +1,34 @@ +// 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 #include @@ -16,7 +38,14 @@ 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()); @@ -46,10 +75,7 @@ Proc::~Proc() for(pt=typeMap.begin();pt!=typeMap.end();pt++) ((*pt).second)->decrRef(); - //get rid of containers in container map - std::map::const_iterator it; - for(it=containerMap.begin();it!=containerMap.end();it++) - ((*it).second)->decrRef(); + removeContainers(); //get rid of loggers in logger map std::map::const_iterator lt; @@ -62,6 +88,8 @@ void Proc::writeDot(std::ostream &os) const os << "digraph " << getQualifiedName() << " {\n" ; os << "node [ style=\"filled\" ];\n" ; os << "compound=true;"; + os << "states [label=<
Ready Toload
Loaded Toactivate
Activated Done
Error Failed
Disabled Pause
> \n shape = plaintext \n style = invis \n ];\n"; + Bloc::writeDot(os); os << "}\n" ; } @@ -86,37 +114,77 @@ TypeCode *Proc::createType(const std::string& name, const std::string& kind) 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 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) @@ -124,6 +192,7 @@ void Proc::setTypeCode (const std::string& name,TypeCode *t) if(typeMap.count(name)!=0) typeMap[name]->decrRef(); typeMap[name]=t; + t->incrRef(); } @@ -149,6 +218,34 @@ YACS::StatesForNode Proc::getNodeState(int numId) 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::Node::idMap[numId])) + progress = node->getProgress(); + return progress; +} + +int Proc::getGlobalProgressPercent() +{ + list > weightList = getProgressWeight(); + int weightDone = 0; + int weightTotal = 0; + int progressPercent = 0; + for(list >::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) @@ -177,7 +274,7 @@ std::string Proc::getInPortValue(int nodeNumId, std::string portName) { YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId]; InputPort * inputPort = node->getInputPort(portName); - return inputPort->dump(); + return inputPort->getAsString(); } catch(YACS::Exception& ex) { @@ -187,6 +284,48 @@ std::string Proc::getInPortValue(int nodeNumId, std::string portName) } } +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 << "" << ex.what() << ""; + return msg.str(); + } +} + std::string Proc::getOutPortValue(int nodeNumId, std::string portName) { DEBTRACE("Proc::getOutPortValue " << nodeNumId << " " << portName); @@ -200,7 +339,7 @@ std::string Proc::getOutPortValue(int nodeNumId, std::string 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) { @@ -313,3 +452,197 @@ void Proc::modified() 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::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 myContainerMap; + std::map myComponentInstanceMap; + DeploymentTree treeToDup(getDeploymentTree()); + vector conts(treeToDup.getAllContainers()); + for(vector::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 comps=treeToDup.getComponentsLinkedToContainer(*iterCt); + for(vector::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; +}