From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/logic__state__machine_8cpp-source.html | 716 +++++++++++++++++++++ 1 file changed, 716 insertions(+) create mode 100644 docs/doxygen/nel/logic__state__machine_8cpp-source.html (limited to 'docs/doxygen/nel/logic__state__machine_8cpp-source.html') diff --git a/docs/doxygen/nel/logic__state__machine_8cpp-source.html b/docs/doxygen/nel/logic__state__machine_8cpp-source.html new file mode 100644 index 00000000..485aca7f --- /dev/null +++ b/docs/doxygen/nel/logic__state__machine_8cpp-source.html @@ -0,0 +1,716 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

logic_state_machine.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 
+00027 #include "nel/logic/logic_state_machine.h"
+00028 
+00029 #include "nel/net/service.h"
+00030 
+00031 using namespace std;
+00032 using namespace NLMISC;
+00033 using namespace NLNET;
+00034 
+00035 namespace NLLOGIC
+00036 {
+00037 
+00038 // test if a string is valid considering a filter and a motif
+00039 bool testNameWithFilter( sint8 filter, string motif, string varName );
+00040 
+00041 void xmlCheckNodeName (xmlNodePtr &node, const char *nodeName)
+00042 {
+00043         // Check node name
+00044         if ( node == NULL || ((const char*)node->name == NULL) || (strcmp ((const char*)node->name, nodeName) != 0) )
+00045         {
+00046 
+00047                 // try to find a child
+00048                 if (node != NULL)
+00049                 {
+00050                         node = CIXml::getFirstChildNode (node, nodeName);
+00051                         if ( node != NULL && ((const char*)node->name != NULL) && (strcmp ((const char*)node->name, nodeName) == 0) )
+00052                         {
+00053                                 nlinfo ("check node %s ok in the child", nodeName);
+00054                                 return;
+00055                         }
+00056                 }
+00057 
+00058                 // Make an error message
+00059                 char tmp[512];
+00060                 smprintf (tmp, 512, "LogicStateMachine STATE_MACHINE XML Syntax error in block line %d, node %s should be %s", 
+00061                         (int)node->content, node->name, nodeName);
+00062                 
+00063                 nlinfo (tmp);
+00064                 nlstop;
+00065                 throw EXmlParsingError (tmp);
+00066         }
+00067 
+00068         nlinfo ("check node %s ok", nodeName);
+00069 }
+00070 
+00071 std::string getXMLProp (xmlNodePtr node, const char *propName)
+00072 {
+00073         const char *name = (const char*)xmlGetProp (node, (xmlChar*)propName);
+00074         if (name)
+00075         {
+00076                 nlinfo ("get prop %s = %s", propName, name);
+00077                 string n = name;
+00078                 xmlFree ((void*)name);
+00079                 return n;
+00080         }
+00081         else
+00082         {
+00083                 // Make an error message
+00084                 char tmp[512];
+00085                 smprintf (tmp, 512, "LogicStateMachine XML Syntax error in block %s line %d, aguments Name not found", 
+00086                         node->name, (int)node->content);
+00087                 throw EXmlParsingError (tmp);
+00088                 return "";
+00089         }
+00090 }
+00091 
+00092 
+00093 //---------------------------------------------------
+00094 // setCurrentState :
+00095 // 
+00096 //---------------------------------------------------
+00097 void CLogicStateMachine::setCurrentState( string stateName )
+00098 {
+00099         map<string,CLogicState>::iterator itStates = _States.find( stateName );
+00100         if( itStates != _States.end() )
+00101         {
+00102                 (*itStates).second.exitState();
+00103         
+00104                 _CurrentState = stateName;
+00105 
+00106                 (*itStates).second.enterState();
+00107 
+00108                 nlinfo("Switching to state \"%s\"",_CurrentState.c_str());
+00109         }
+00110         else
+00111         {
+00112                 nlwarning("(LOGIC)<CLogicStateMachine::setCurrentState> The state \"%s\" is not in the state machine \"%s\"",stateName.c_str(),_Name.c_str());
+00113         }
+00114 
+00115 } // setCurrentState //
+00116 
+00117 
+00118 
+00119 //---------------------------------------------------
+00120 // addCondition :
+00121 // 
+00122 //---------------------------------------------------
+00123 void CLogicStateMachine::addCondition( CLogicCondition condition ) 
+00124 { 
+00125         condition.setLogicStateMachine(this);
+00126         _Conditions.insert(make_pair(condition.getName(),condition)); 
+00127 
+00128 } // addCondition //
+00129 
+00130 
+00131 
+00132 //---------------------------------------------------
+00133 // addState :
+00134 // 
+00135 //---------------------------------------------------
+00136 void CLogicStateMachine::addState( CLogicState logicState ) 
+00137 {
+00138         logicState.setLogicStateMachine( this );
+00139         _States.insert( std::make_pair(logicState.getName(),logicState) );
+00140         
+00141 } // addState //
+00142 
+00143 
+00144 
+00145 
+00146 //---------------------------------------------------
+00147 // addSIdMap :
+00148 // 
+00149 //---------------------------------------------------
+00150 void CLogicStateMachine::addSIdMap( const TSIdMap& sIdMap )
+00151 {
+00152         // call addSIdMap for each state
+00153         map<string,CLogicState>::iterator itStates;
+00154         for( itStates = _States.begin(); itStates != _States.end(); ++itStates )
+00155         {
+00156                 (*itStates).second.addSIdMap( sIdMap );
+00157         }
+00158 
+00159 } // addSIdMap //
+00160 
+00161 
+00162 
+00163 //---------------------------------------------------
+00164 // processLogic :
+00165 // 
+00166 //---------------------------------------------------
+00167 void CLogicStateMachine::processLogic()
+00168 {       
+00169         // call processLogic for the current state
+00170         map<string,CLogicState>::iterator itStates = _States.find( _CurrentState );
+00171         nlassert( itStates != _States.end() )
+00172         (*itStates).second.processLogic();
+00173 
+00174         // update the counters
+00175         map<string,CLogicCounter>::iterator itCount;
+00176         for( itCount = _Counters.begin(); itCount != _Counters.end(); ++itCount )
+00177         {
+00178                 (*itCount).second.update();
+00179         }
+00180         
+00181 } // processLogic //
+00182 
+00183 
+00184 
+00185 //---------------------------------------------------
+00186 // getMessagesToSend :
+00187 // 
+00188 //---------------------------------------------------
+00189 void CLogicStateMachine::getMessagesToSend( multimap<CEntityId,CMessage>& msgs )
+00190 {
+00191         map<std::string, CLogicState>::iterator itState;
+00192         for( itState = _States.begin(); itState != _States.end(); ++itState )
+00193         {
+00194                 (*itState).second.getMessagesToSend( msgs );
+00195         }       
+00196         
+00197 } // getMessagesToSend //
+00198 
+00199 
+00200 
+00201 
+00202 //---------------------------------------------------
+00203 // getVariable :
+00204 // 
+00205 //---------------------------------------------------
+00206 bool CLogicStateMachine::getVariable( std::string& varName, CLogicVariable& var )
+00207 {
+00208         map<string,CLogicVariable>::iterator itVar = _Variables.find( varName );
+00209         if( itVar != _Variables.end() )
+00210         {
+00211                 var = (*itVar).second;
+00212                 return true;
+00213         }
+00214 
+00215         map<string,CLogicCounter>::iterator itCount = _Counters.find( varName );
+00216         if( itCount != _Counters.end() )
+00217         {
+00218                 var = (*itCount).second;
+00219                 return true;
+00220         }
+00221         
+00222         return false;
+00223 
+00224 } // getVariable //
+00225 
+00226 
+00227 
+00228 //---------------------------------------------------
+00229 // getCondition :
+00230 // 
+00231 //---------------------------------------------------
+00232 bool CLogicStateMachine::getCondition( const std::string& condName, CLogicCondition& cond )
+00233 {
+00234         map<string,CLogicCondition>::iterator itCond = _Conditions.find( condName );
+00235         if( itCond != _Conditions.end() )
+00236         {
+00237                 cond = (*itCond).second;
+00238                 return true;
+00239         }
+00240         else
+00241         { 
+00242                 return false;
+00243         }
+00244 
+00245 } // getCondition //
+00246 
+00247 
+00248 //---------------------------------------------------
+00249 // modifyVariable :
+00250 // 
+00251 //---------------------------------------------------
+00252 void CLogicStateMachine::modifyVariable( string varName, string modifOperator, sint64 value )
+00253 {
+00254         map<string,CLogicVariable>::iterator itVar = _Variables.find( varName );
+00255         if( itVar != _Variables.end() )
+00256         {
+00257                 (*itVar).second.applyModification( modifOperator, value );
+00258                 return;
+00259         }
+00260         map<string,CLogicCounter>::iterator itCount = _Counters.find( varName );
+00261         if( itCount != _Counters.end() )
+00262         {
+00263                 (*itCount).second.applyModification( modifOperator, value );
+00264                 return;
+00265         }
+00266 
+00267         nlwarning("(LOGIC)<CLogicStateMachine::modifyVariable> The variable \"%s\" is not in the state machine \"%s\"",varName.c_str(),_Name.c_str());
+00268 
+00269 } // modifyVariable //
+00270 
+00271 
+00272 
+00273 //---------------------------------------------------
+00274 // serial :
+00275 // 
+00276 //---------------------------------------------------
+00277 /*void CLogicStateMachine::serial( IStream &f )
+00278 {
+00279         f.xmlPush("STATE_MACHINE");
+00280 
+00281         
+00282         f.serialCont( _Variables );
+00283         f.serialCont( _Counters );
+00284         f.serialCont( _Conditions );
+00285         f.serialCont( _States );
+00286         f.serial( _CurrentState );
+00287         f.serial( _Name );
+00288         
+00289         if( f.isReading() )
+00290         {
+00291                 // set the the logic state machine addr in each state
+00292                 map<string,CLogicState>::iterator itStates;
+00293                 for( itStates = _States.begin(); itStates != _States.end(); ++itStates )
+00294                 {
+00295                         (*itStates).second.setLogicStateMachine( this );
+00296                 }
+00297 
+00298                 // set the the logic state machine addr in each conditions
+00299                 map<string,CLogicCondition>::iterator itCond;
+00300                 for( itCond = _Conditions.begin(); itCond != _Conditions.end(); ++itCond )
+00301                 {
+00302                         (*itCond).second.setLogicStateMachine( this );
+00303                 }
+00304         }
+00305         
+00306         f.xmlPop();
+00307 
+00308 } // serial //*/
+00309 
+00310 
+00311 //---------------------------------------------------
+00312 //      Display the variables
+00313 //
+00314 //---------------------------------------------------
+00315 void CLogicStateMachine::displayVariables()
+00316 {
+00317         multimap<CEntityId,string> allVariables;
+00318         
+00319         // // get vars referenced in the states
+00320         map<string, CLogicState>::iterator itS;
+00321         for( itS = _States.begin(); itS != _States.end(); ++itS )
+00322         {
+00323                 (*itS).second.fillVarMap( allVariables );
+00324         }
+00325 
+00326         // extract the unclaimed variables from all the variables
+00327         vector<string> unclaimedVariables;
+00328         CEntityId unknown;
+00329         unknown.setType( 0xfe );
+00330         unknown.setCreatorId( 0 );
+00331         unknown.setDynamicId( 0 );
+00332         pair<multimap<CEntityId,string>::iterator,multimap<CEntityId,string>::iterator> itVarsRng = allVariables.equal_range(unknown);
+00333         multimap<CEntityId,string>::iterator itVars;
+00334         
+00335         for( itVars = itVarsRng.first; itVars != itVarsRng.second; )
+00336         {
+00337                 multimap<CEntityId,string>::iterator itDel = itVars++;
+00338                 unclaimedVariables.push_back( (*itDel).second );
+00339                 allVariables.erase( itDel );
+00340         }
+00341         /*
+00342         if( itVarsRng.first != allVariables.end() )
+00343         {
+00344                 itVars = itVarsRng.first;
+00345                 do
+00346                 {
+00347                         multimap<CEntityId,string>::iterator itDel = itVars++;
+00348                         unclaimedVariables.push_back( (*itDel).second );
+00349                         allVariables.erase( itDel );
+00350                 }
+00351                 while( itVars != itVarsRng.second );
+00352         }
+00353         */
+00354 
+00355 
+00356         nlinfo("VARIABLES/COUNTERS in %s : %d/%d are registered : ",_Name.c_str(),allVariables.size(),allVariables.size()+unclaimedVariables.size());
+00357         // display the registered variables
+00358         for( itVars = allVariables.begin(); itVars != allVariables.end(); ++itVars )
+00359         {
+00360                 map<string, CLogicVariable>::const_iterator itV = _Variables.find( (*itVars).second );
+00361                 nlinfo("[%d] %s = %f",(uint8)(*itVars).first.getDynamicId(),(*itV).first.c_str(),(double)(*itV).second.getValue());
+00362         }
+00363 
+00364         // display the unclaimed variables
+00365         sort( unclaimedVariables.begin(), unclaimedVariables.end() );
+00366         vector<string>::iterator itUV;
+00367         for( itUV = unclaimedVariables.begin(); itUV != unclaimedVariables.end(); ++itUV )
+00368         {
+00369                 map<string, CLogicVariable>::const_iterator itV = _Variables.find( *itUV );
+00370                 nlinfo("(-)%s = %f",(*itV).first.c_str(),(double)(*itV).second.getValue());
+00371         }
+00372         
+00373 } // displayVariables //
+00374 
+00375 
+00376 //---------------------------------------------------
+00377 //      Display the states
+00378 //
+00379 //---------------------------------------------------
+00380 void CLogicStateMachine::displayStates()
+00381 {
+00382         nlinfo("There are %d STATES in the state machine \"%s\": ",_States.size(),_Name.c_str());
+00383         map<string, CLogicState>::const_iterator itS;
+00384         for( itS = _States.begin(); itS != _States.end(); ++itS )
+00385         {
+00386                 nlinfo("%s",(*itS).first.c_str());
+00387         }
+00388         nlinfo("The current state is : \"%s\"",_CurrentState.c_str());
+00389 
+00390 } // displayStates //
+00391 
+00392 
+00393 //---------------------------------------------------
+00394 //      Set the verbose mode for the variable
+00395 //
+00396 //---------------------------------------------------
+00397 void CLogicStateMachine::setVerbose( string varName, bool b )
+00398 {
+00399         if( varName == "all" )
+00400         {
+00401                 map<string, CLogicVariable>::iterator itV;
+00402                 for( itV = _Variables.begin(); itV != _Variables.end(); ++itV )
+00403                 {
+00404                         (*itV).second.setVerbose( b );
+00405                 }
+00406                 map<string, CLogicCounter>::iterator itC;
+00407                 for( itC = _Counters.begin(); itC != _Counters.end(); ++itC )
+00408                 {
+00409                         (*itC).second.setVerbose( b );
+00410                 }
+00411                 if(b)
+00412                 {
+00413                         nlinfo("the verbose mode has been activated for all the variables",varName.c_str());
+00414                 }
+00415                 else
+00416                 {
+00417                         nlinfo("the verbose mode has been desactivated for all the variables",varName.c_str());
+00418                 }
+00419                 return;
+00420         }
+00421         
+00422         sint8 filter = -1;
+00423         string motif;
+00424         // *xxx* => we look for a string with xxx inside
+00425         if( varName[0]=='*' && varName[varName.size()-1]=='*') 
+00426         {
+00427                 motif = varName.substr(1,varName.size()-2);
+00428                 filter = 0;
+00429         }
+00430         else
+00431         // *xxx => we look for a string with xxx at the end
+00432         if( varName[0]=='*' ) 
+00433         {
+00434                 motif = varName.substr(1,varName.size()-1);
+00435                 filter = 1;
+00436         }
+00437         else
+00438         // xxx* => we look for a string with xxx at the begining
+00439         if( varName[varName.size()-1]=='*' ) 
+00440         {
+00441                 motif = varName.substr(0,varName.size()-1);
+00442                 filter = 2;
+00443         }
+00444 
+00445         // if no filter
+00446         if( filter == -1 )
+00447         {
+00448                 map<string, CLogicVariable>::iterator itV = _Variables.find( varName );
+00449                 if( itV != _Variables.end() )
+00450                 {
+00451                         (*itV).second.setVerbose( b );
+00452                 }
+00453                 map<string, CLogicCounter>::iterator itC = _Counters.find( varName );
+00454                 if( itC != _Counters.end() || varName =="all" )
+00455                 {
+00456                         (*itC).second.setVerbose( b );
+00457                 }
+00458         }
+00459         // if filter
+00460         else
+00461         {
+00462                 map<string, CLogicVariable>::iterator itV;
+00463                 for( itV = _Variables.begin(); itV != _Variables.end(); ++itV )
+00464                 {
+00465                         if( testNameWithFilter( filter, motif,(*itV).second.getName()) )
+00466                         {
+00467                                 (*itV).second.setVerbose( b );
+00468                         }
+00469                 }
+00470                 map<string, CLogicCounter>::iterator itC;
+00471                 for( itC = _Counters.begin(); itC != _Counters.end(); ++itC )
+00472                 {
+00473                         if( testNameWithFilter( filter, motif,(*itC).second.getName()) )
+00474                         {
+00475                                 (*itC).second.setVerbose( b );
+00476                         }
+00477                 }
+00478         }
+00479         if(b)
+00480         {
+00481                 nlinfo("the verbose mode for variable \"%s\" has been activated",varName.c_str());
+00482         }
+00483         else
+00484         {
+00485                 nlinfo("the verbose mode for variable \"%s\" has been desactivated",varName.c_str());
+00486         }
+00487         
+00488 } // setVerbose //
+00489 
+00490 
+00491 
+00492 //---------------------------------------------------
+00493 //      testNameWithFilter :
+00494 //
+00495 //---------------------------------------------------
+00496 bool testNameWithFilter( sint8 filter, string motif, string varName )
+00497 {
+00498         if( varName.size() > motif.size() )
+00499         {
+00500                 switch( filter )
+00501                 {
+00502                         // *xxx*
+00503                         case 0 :
+00504                         {
+00505                                 if(varName.find(motif) != -1)
+00506                                 {
+00507                                         return true;
+00508                                 }
+00509                         }
+00510                         break;
+00511 
+00512                         // *xxx
+00513                         case 1 :
+00514                         {
+00515                                 sint beginIndex = varName.size() - motif.size() - 1;
+00516                                 string endOfVarName = varName.substr(beginIndex,motif.size());
+00517                                 if( endOfVarName == motif )
+00518                                 {
+00519                                         return true;
+00520                                 }
+00521                         }
+00522                         break;
+00523         
+00524                         // xxx*
+00525                         case 2 :
+00526                         {
+00527                                 string beginOfVarName = varName.substr(0,motif.size());
+00528                                 if( beginOfVarName == motif )
+00529                                 {
+00530                                         return true;
+00531                                 }
+00532                         }
+00533                         break;
+00534                 }
+00535         }
+00536 
+00537         return false;
+00538 
+00539 } // testNameWithFilter //
+00540 
+00541 void CLogicStateMachine::write (xmlDocPtr doc) const
+00542 {
+00543         // Create the first node
+00544         xmlNodePtr node = xmlNewDocNode (doc, NULL, (const xmlChar*)"STATE_MACHINE", NULL);
+00545         xmlDocSetRootElement (doc, node);
+00546         xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)_Name.c_str());
+00547         xmlSetProp (node, (const xmlChar*)"CurrentState", (const xmlChar*)_CurrentState.c_str());
+00548 
+00549         for (std::map<std::string, CLogicVariable>::const_iterator vit = _Variables.begin(); vit != _Variables.end(); vit++)
+00550         {
+00551                 (*vit).second.write(node);
+00552         }
+00553 
+00554         for (std::map<std::string, CLogicCounter>::const_iterator cit = _Counters.begin(); cit != _Counters.end(); cit++)
+00555         {
+00556                 (*cit).second.write(node);
+00557         }
+00558 
+00559         for (std::map<std::string, CLogicCondition>::const_iterator c2it = _Conditions.begin(); c2it != _Conditions.end(); c2it++)
+00560         {
+00561                 (*c2it).second.write(node);
+00562         }
+00563         
+00564         for (std::map<std::string, CLogicState>::const_iterator sit = _States.begin(); sit != _States.end(); sit++)
+00565         {
+00566                 (*sit).second.write(node);
+00567         }
+00568 }
+00569 
+00570 void CLogicStateMachine::read (xmlNodePtr node)
+00571 {
+00572         xmlCheckNodeName (node, "STATE_MACHINE");
+00573 
+00574         setName (getXMLProp (node, "Name"));
+00575 
+00576         {
+00577                 // Count the parent
+00578                 uint nb = CIXml::countChildren (node, "VARIABLE");
+00579                 uint i = 0;
+00580                 xmlNodePtr parent = CIXml::getFirstChildNode (node, "VARIABLE");
+00581                 while (i<nb)
+00582                 {
+00583                         CLogicVariable v;
+00584                         v.read(parent);
+00585                         _Variables.insert (make_pair(v.getName(), v));
+00586 
+00587                         // Next parent
+00588                         parent = CIXml::getNextChildNode (parent, "VARIABLE");
+00589                         i++;
+00590                 }
+00591         }
+00592 
+00593         {
+00594                 // Count the parent
+00595                 uint nb = CIXml::countChildren (node, "COUNTER");
+00596                 uint i = 0;
+00597                 xmlNodePtr parent = CIXml::getFirstChildNode (node, "COUNTER");
+00598                 while (i<nb)
+00599                 {
+00600                         CLogicCounter v;
+00601                         v.read(parent);
+00602                         _Counters.insert (make_pair(v.getName(), v));
+00603 
+00604                         // Next parent
+00605                         parent = CIXml::getNextChildNode (parent, "COUNTER");
+00606                         i++;
+00607                 }
+00608         }
+00609 
+00610         {
+00611                 // Count the parent
+00612                 uint nb = CIXml::countChildren (node, "CONDITION");
+00613                 uint i = 0;
+00614                 xmlNodePtr parent = CIXml::getFirstChildNode (node, "CONDITION");
+00615                 while (i<nb)
+00616                 {
+00617                         CLogicCondition v;
+00618                         v.read(parent);
+00619                         _Conditions.insert (make_pair(v.getName(), v));
+00620 
+00621                         // Next parent
+00622                         parent = CIXml::getNextChildNode (parent, "CONDITION");
+00623                         i++;
+00624                 }
+00625         }
+00626 
+00627         {
+00628                 // Count the parent
+00629                 uint nb = CIXml::countChildren (node, "STATE");
+00630                 uint i = 0;
+00631                 xmlNodePtr parent = CIXml::getFirstChildNode (node, "STATE");
+00632                 while (i<nb)
+00633                 {
+00634                         CLogicState v;
+00635                         v.read(parent);
+00636                         _States.insert (make_pair(v.getName(), v));
+00637 
+00638                         // Next parent
+00639                         parent = CIXml::getNextChildNode (parent, "STATE");
+00640                         i++;
+00641                 }
+00642         }
+00643 
+00644         setCurrentState (getXMLProp (node, "CurrentState"));
+00645 }
+00646 
+00647 } // NLLOGIC
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1