From: Ovidiu Mircescu Date: Mon, 27 Feb 2017 09:56:37 +0000 (+0100) Subject: Save foreach state - work in progress. X-Git-Tag: SHAPER_2.7.0~3 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e3255204c864201f5bc1aa040d4273ed2f44e8cd;p=modules%2Fyacs.git Save foreach state - work in progress. --- e3255204c864201f5bc1aa040d4273ed2f44e8cd diff --cc src/engine/ForEachLoop.cxx index 54535a140,4c767b5b7..4ed7f7ac5 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@@ -29,7 -29,7 +29,7 @@@ #include #include // std::replace_if --//#define _DEVDEBUG_ ++#define _DEVDEBUG_ #include "YacsTrace.hxx" using namespace YACS::ENGINE; @@@ -1194,20 -1196,31 +1206,69 @@@ void ForEachLoop::assignPassedResults(c _passedData=new ForEachLoopPassedData(passedIds,passedOutputs,nameOfOutputs); } +int ForEachLoop::getFEDeltaBetween(OutPort *start, InPort *end) +{ + Node *ns(start->getNode()),*ne(end->getNode()); + ComposedNode *co(getLowestCommonAncestor(ns,ne)); + int ret(0); + Node *work(ns); + while(work!=co) + { + ForEachLoop *isFE(dynamic_cast(work)); + if(isFE) + ret++; + work=work->getFather(); + } + if(dynamic_cast(start)) + ret--; + return ret; +} ++ + /*! + * This method is used to obtain the values already processed by the ForEachLoop. + * A new ForEachLoopPassedData object is returned. You have to delete it. + */ + ForEachLoopPassedData* ForEachLoop::getProcessedData()const + { + std::vector outputs; + std::vector nameOfOutputs; + if(_execVals.empty() || _execOutGoingPorts.empty()) + return new ForEachLoopPassedData(std::vector(), outputs, nameOfOutputs); + std::size_t sz(_execVals.size()); + outputs.resize(sz); + nameOfOutputs.resize(sz); + const std::vector& ports(_execOutGoingPorts[0]); + for(std::size_t i=0;iremoveUnsetItemsFromThis(); + nameOfOutputs[i]=ports[i]->getName(); + } + return new ForEachLoopPassedData(_execVals[0]->getSetItems(), outputs, nameOfOutputs); + } + + void ForEachLoop::setProcessedData(ForEachLoopPassedData* processedData) + { + if(_passedData) + delete _passedData; + _passedData = processedData; + } ++ ++/*! ++ * \param portName : "interceptorized" name of port. ++ */ ++const YACS::ENGINE::TypeCode* ForEachLoop::getOutputPortType(const std::string& portName)const ++{ ++ const YACS::ENGINE::TypeCode* ret=NULL; ++ vector::const_iterator it; ++ for(it=_outGoingPorts.begin();it!=_outGoingPorts.end() && ret==NULL;it++) ++ { ++ std::string originalPortName(getPortName(*it)); ++ //InterceptorizeNameOfPort(originalPortName); ++ DEBTRACE("ForEachLoop::getOutputPortType compare " << portName << " == " << originalPortName); ++ if(originalPortName == portName) ++ { ++ ret = (*it)->edGetType()->contentType(); ++ } ++ } ++ return ret; ++} diff --cc src/engine/ForEachLoop.hxx index 7c1968d38,875b900fa..0f3690fb0 --- a/src/engine/ForEachLoop.hxx +++ b/src/engine/ForEachLoop.hxx @@@ -195,11 -200,12 +200,14 @@@ namespace YAC std::list getProgressWeight() const; int getCurrentIndex() const { return _currentIndex; } int getNbOfElementsToBeProcessed() const; + static int getFEDeltaBetween(OutPort *start, InPort *end); #ifndef SWIG + ForEachLoopPassedData* getProcessedData()const; + void setProcessedData(ForEachLoopPassedData* processedData); std::vector getPassedResults(Executor *execut, std::vector& outputs, std::vector& nameOfOutputs) const; void assignPassedResults(const std::vector& passedIds, const std::vector& passedOutputs, const std::vector& nameOfOutputs); #endif ++ const TypeCode* getOutputPortType(const std::string& portName)const; protected: Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; void checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, diff --cc src/runtime_swig/CMakeLists.txt index 1f3e47394,879620de2..abfcdca0a --- a/src/runtime_swig/CMakeLists.txt +++ b/src/runtime_swig/CMakeLists.txt @@@ -92,12 -92,15 +92,13 @@@ SET(SWIGINCLUDE ${PROJECT_SOURCE_DIR}/src/runtime/CORBAPorts.hxx ${PROJECT_SOURCE_DIR}/src/runtime/TypeConversions.hxx ${PROJECT_SOURCE_DIR}/src/runtime/SalomeOptimizerLoop.hxx + ${PROJECT_SOURCE_DIR}/src/runtime/VisitorSalomeSaveState.hxx ) +SET(SWIG_MODULE_SALOMERuntime_EXTRA_DEPS + ${PROJECT_SOURCE_DIR}/src/engine_swig/pilot.i + ${PROJECT_SOURCE_DIR}/src/engine_swig/engtypemaps.i + ${SWIGINCLUDES}) SWIG_ADD_MODULE(SALOMERuntime python SALOMERuntime.i) -ADD_DEPENDENCIES(_SALOMERuntime - SALOMERuntime.i - ${PROJECT_SOURCE_DIR}/src/engine_swig/pilot.i - ${PROJECT_SOURCE_DIR}/src/engine_swig/engtypemaps.i - docruntime.i - ${SWIGINCLUDES}) SWIG_LINK_LIBRARIES(SALOMERuntime ${_link_LIBRARIES}) IF(WIN32) diff --cc src/yacsloader/CMakeLists.txt index 20052f372,ddfc6b004..71a9807f8 --- a/src/yacsloader/CMakeLists.txt +++ b/src/yacsloader/CMakeLists.txt @@@ -73,6 -73,6 +73,7 @@@ SET(YACSloader_LIBRARIE ${OMNIORB_LIBRARIES} ${LIBXML2_LIBRARIES} YACSlibEngine ++ YACSRuntimeSALOME ) SET(_link_LIBRARIES YACSloader diff --cc src/yacsloader/LoadState.cxx index faaa1a5fd,f4222f10c..2de532554 --- a/src/yacsloader/LoadState.cxx +++ b/src/yacsloader/LoadState.cxx @@@ -27,6 -27,8 +27,9 @@@ #include "Runtime.hxx" #include "InputPort.hxx" #include "ElementaryNode.hxx" + #include "ForEachLoop.hxx" + #include "Any.hxx" ++#include "TypeConversions.hxx" #include #include @@@ -34,7 -36,7 +37,7 @@@ #include #include --//#define _DEVDEBUG_ ++#define _DEVDEBUG_ #include "YacsTrace.hxx" using namespace YACS::ENGINE; @@@ -231,6 -232,6 +234,7 @@@ public void nodeParser::init(const xmlChar** p, xmlParserBase* father) { DEBTRACE("nodeParser::init()"); ++ _loopSamples.clear(); _state = XMLINNODE; _father = father; _stackState.push(_state); @@@ -250,6 -251,7 +254,12 @@@ void nodeParser::onStart (const XML_Cha else if (element == "nbdone") parser = new attrParser(); else if (element == "condition") parser = new attrParser(); else if (element == "outputPort") parser = new outputParser(); - else if (element == "loopOutputPort") parser = new loopPortParser(); ++ else if (element == "loopOutputPort") ++ { ++ loopPortParser* sparser = new loopPortParser(); ++ _loopSamples.push_back(sparser); ++ parser = sparser; ++ } else { _what = "expected name, state or inputPort, got <" + element + ">"; @@@ -362,10 -364,10 +372,118 @@@ void nodeParser::onEnd (const XML_Cha } mySwitch->edGetConditionPort()->edInit(condition); } ++ else if (nodeType == "forEachLoop") ++ { ++ ForEachLoop* feNode = dynamic_cast(node); ++ if(!feNode) ++ { ++ _what = "node is not a ForEachLoop: " + _mapAttrib["name"]; ++ _state = XMLFATALERROR; ++ stopParse(_what); ++ } ++ else ++ { ++ std::vector passedIds; ++ std::vector passedOutputs; ++ std::vector nameOfOutputs; ++ bool firstPort = true; ++ std::list::const_iterator itPort; ++ for(itPort=_loopSamples.begin(); itPort!=_loopSamples.end(); itPort++) ++ { ++ const std::string& portName =(*itPort)->getPortName(); ++ nameOfOutputs.push_back(portName); ++ const YACS::ENGINE::TypeCode* tc = feNode->getOutputPortType(portName); ++ if(!tc) ++ { ++ _what = "Impossible to find the type of the port " + portName; ++ _state = XMLFATALERROR; ++ stopParse(_what); ++ return; ++ } ++ unsigned int nbSamples = (*itPort)->getNbSamples(); ++ SequenceAny* seqValues = SequenceAny::New(tc, nbSamples); ++ passedOutputs.push_back(seqValues); ++ for(unsigned int i = 0; i < nbSamples; i++) ++ { ++ unsigned int sampleId = (*itPort)->getSampleId(i); ++ const std::string& sampleData = (*itPort)->getSampleData(i); ++ Any* value = xmlToAny(sampleData, tc); ++ if(firstPort) ++ { ++ passedIds.push_back(sampleId); ++ seqValues->setEltAtRank(i, value); ++ } ++ else ++ { ++ unsigned int pos = 0; ++ while(pos < passedIds.size() && sampleId != passedIds[pos]) ++ pos++; ++ if(pos < passedIds.size()) ++ seqValues->setEltAtRank(pos, value); ++ else ++ { ++ _what = "Inconsistent sample id in foreach node " + _mapAttrib["name"]; ++ _state = XMLFATALERROR; ++ stopParse(_what); ++ itPort=_loopSamples.end(); ++ return; ++ } ++ } ++ } ++ firstPort = false; ++ } ++ feNode->assignPassedResults(passedIds, passedOutputs, nameOfOutputs); ++ } ++ } stateParser::onEnd(name); } ++Any* nodeParser::xmlToAny(const std::string& data, const YACS::ENGINE::TypeCode* tc)const ++{ ++ xmlDocPtr doc; ++ xmlNodePtr cur; ++ //YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(0); ++ YACS::ENGINE::Any *ob=NULL; ++ { ++ doc = xmlParseMemory(data.c_str(), data.length()); ++ if (doc == NULL ) ++ { ++ stringstream msg; ++ msg << "Problem in conversion: XML Document not parsed successfully "; ++ msg << " (" << __FILE__ << ":" << __LINE__ << ")"; ++ throw ConversionException(msg.str()); ++ } ++ cur = xmlDocGetRootElement(doc); ++ if (cur == NULL) ++ { ++ xmlFreeDoc(doc); ++ stringstream msg; ++ msg << "Problem in conversion: empty XML Document"; ++ msg << " (" << __FILE__ << ":" << __LINE__ << ")"; ++ throw ConversionException(msg.str()); ++ } ++ while (cur != NULL) ++ { ++ if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) ++ { ++ ob=convertXmlNeutral(tc,doc,cur); ++ break; ++ } ++ cur = cur->next; ++ } ++ xmlFreeDoc(doc); ++ if(ob==NULL) ++ { ++ stringstream msg; ++ msg << "Problem in conversion: incorrect XML value"; ++ msg << " (" << __FILE__ << ":" << __LINE__ << ")"; ++ throw ConversionException(msg.str()); ++ } ++ } ++ return ob; ++} ++ // ---------------------------------------------------------------------------- void attrParser::init(const xmlChar** p, xmlParserBase* father) @@@ -660,7 -662,148 +778,130 @@@ void simpleTypeParser::charData(std::st _data = _data + data; } + // ---------------------------------------------------------------------------- + + void loopPortParser::init(const xmlChar** p, xmlParserBase* father) + { + DEBTRACE("loopPortParser::init()"); - _state = XMLINPORT; ++ //_state = XMLINPORT; + _father = father; + _stackState.push(_state); ++ _ids.clear(); ++ _sampleData.clear(); + if (p) getAttributes(p); + } + + void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p) + { + DEBTRACE("loopPortParser::onStart" << elem); + string element(elem); + stateParser *parser = 0; + if (element == "name") parser = new attrParser(); - else if (element == "sample") parser = new sampleParser(); ++ else if (element == "sample") parser = new sampleParser(this); + else + { + _what = "expected name or sample, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } + } + + void loopPortParser::onEnd(const XML_Char* name) + { - string portName = _mapAttrib["name"]; - string nodeName = _father->getAttribute("name"); - string nodeType = _father->getAttribute("type"); - Node *node = _p->getChildByName(nodeName); - if (nodeType != "forEachLoop") - { - _what = "loopOutputPort attribute is not valid for node <" + nodeName + ">"; - _state = XMLFATALERROR; - stopParse(_what); - } ++ stateParser::onEnd(name); + } + + void loopPortParser::charData(std::string data) + { + } ++void loopPortParser::addSample(int index, const std::string data) ++{ ++ _ids.push_back(index); ++ _sampleData.push_back(data); ++} ++ ++unsigned int loopPortParser::getNbSamples()const ++{ ++ return _ids.size(); ++} ++ ++unsigned int loopPortParser::getSampleId(unsigned int i)const ++{ ++ return _ids[i]; ++} ++ ++const std::string& loopPortParser::getSampleData(unsigned int i)const ++{ ++ return _sampleData[i]; ++} ++ ++const std::string& loopPortParser::getPortName()const ++{ ++ return _mapAttrib.at("name"); ++} ++ + // ---------------------------------------------------------------------------- + ++sampleParser::sampleParser(loopPortParser* father) ++: stateParser(), ++ _sampleFather(father) ++{ ++} ++ + void sampleParser::init(const xmlChar** p, xmlParserBase* father) + { + DEBTRACE("sampleParser::init()"); - _state = XMLINPORT; ++ //_state = XMLINPORT; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); + } + + void sampleParser::onStart(const XML_Char* elem, const xmlChar** p) + { + DEBTRACE("sampleParser::onStart" << elem); + string element(elem); + stateParser *parser = 0; + if (element == "index") parser = new attrParser(); + else if (element == "value") parser = new valueParser(); + else + { + _what = "expected index or value, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } + } + + void sampleParser::onEnd(const XML_Char* name) + { + if (_mapAttrib.find("index") == _mapAttrib.end()) + { + _what = "no attribute index in sample "; + _state = XMLFATALERROR; + stopParse(_what); + } + int index = atoi(_mapAttrib["index"].c_str()); - Any * value; - value = xmlToAny(); ++ _sampleFather->addSample(index, _data); ++ stateParser::onEnd(name); + } + + void sampleParser::charData(std::string data) + { -} - -Any* sampleParser::xmlToAny() throw(ConversionException) -{ - xmlDocPtr doc; - xmlNodePtr cur; - YACS::ENGINE::Any *ob=NULL; - { - doc = xmlParseMemory(_data.c_str(), _data.length()); - if (doc == NULL ) - { - stringstream msg; - msg << "Problem in conversion: XML Document not parsed successfully "; - msg << " (" << __FILE__ << ":" << __LINE__ << ")"; - throw ConversionException(msg.str()); - } - cur = xmlDocGetRootElement(doc); - if (cur == NULL) - { - xmlFreeDoc(doc); - stringstream msg; - msg << "Problem in conversion: empty XML Document"; - msg << " (" << __FILE__ << ":" << __LINE__ << ")"; - throw ConversionException(msg.str()); - } - while (cur != NULL) - { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) - { - ob=convertXmlNeutral(edGetType(),doc,cur); - break; - } - cur = cur->next; - } - xmlFreeDoc(doc); - if(ob==NULL) - { - stringstream msg; - msg << "Problem in conversion: incorrect XML value"; - msg << " (" << __FILE__ << ":" << __LINE__ << ")"; - throw ConversionException(msg.str()); - } - } - return ob; ++ _data = _data + data; + } // ---------------------------------------------------------------------------- diff --cc src/yacsloader/LoadState.hxx index 3935d569e,16e423442..6102e0b3f --- a/src/yacsloader/LoadState.hxx +++ b/src/yacsloader/LoadState.hxx @@@ -25,6 -26,7 +26,8 @@@ #include "define.hxx" #include "Exception.hxx" + #include ++#include namespace YACS { @@@ -32,6 -34,8 +35,9 @@@ { class Proc; class Runtime; + class SequenceAny; + class Any; ++ class TypeCode; //! Load state from a file into a Proc /*! @@@ -105,14 -109,14 +111,18 @@@ }; ++ class loopPortParser; class YACSLOADER_EXPORT nodeParser: public stateParser { public: virtual void init(const xmlChar** p, xmlParserBase* father=0); virtual void onStart (const XML_Char* elem, const xmlChar** p); virtual void onEnd (const XML_Char* name); ++ Any* xmlToAny(const std::string& data, const TypeCode* tc)const; std::string _nodeName; std::string _nodeState; ++ private: ++ std::list _loopSamples; }; class YACSLOADER_EXPORT attrParser: public stateParser @@@ -172,6 -176,29 +182,37 @@@ virtual void charData(std::string data); }; + class YACSLOADER_EXPORT loopPortParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData(std::string data); ++ void addSample(int index, const std::string data); ++ unsigned int getNbSamples()const; ++ unsigned int getSampleId(unsigned int i)const; ++ const std::string& getSampleData(unsigned int i)const; ++ const std::string& getPortName()const; ++ private: + std::vector _ids; - std::vector _outputValues; - std::vector _outputNames; ++ std::vector _sampleData; + }; + + class YACSLOADER_EXPORT sampleParser: public stateParser + { + public: ++ sampleParser(loopPortParser* father); + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData(std::string data); - protected: - Any* xmlToAny()throw(ConversionException); ++ //protected: ++ // Any* xmlToAny()throw(ConversionException); ++ private: ++ loopPortParser* _sampleFather; + }; + } } #endif diff --cc src/yacsloader_swig/loader.i index 4f41b4ad1,821157f5d..13dd1bcd9 --- a/src/yacsloader_swig/loader.i +++ b/src/yacsloader_swig/loader.i @@@ -67,5 -67,5 +67,5 @@@ %include "YACSloaderExport.hxx" %include "parsers.hxx" %import "xmlParserBase.hxx" --%include "LoadState.hxx" ++//%include "LoadState.hxx"