# 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_condition.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/misc/o_xml.h"
00028 
00029 #include "nel/logic/logic_condition.h"
00030 #include "nel/logic/logic_variable.h"
00031 #include "nel/logic/logic_state_machine.h"
00032 
00033 using namespace NLMISC;
00034 using namespace std;
00035 
00036 namespace NLLOGIC
00037 {
00038 
00039 //-------------------------------------------------
00040 // setLogicStateMachine :
00041 //
00042 //-------------------------------------------------
00043 void CLogicComparisonBlock::setLogicStateMachine( CLogicStateMachine * logicStateMachine )
00044 { 
00045         if( logicStateMachine == 0 )
00046         {
00047                 nlwarning("(LOGIC)<CLogicComparisonBlock::setLogicStateMachine> The state machine is null");
00048         }
00049         else
00050         {
00051                 _LogicStateMachine = logicStateMachine; 
00052         }
00053         
00054 } // setLogicStateMachine //
00055 
00056 
00057 //-------------------------------------------------
00058 // testLogic :
00059 //
00060 //-------------------------------------------------
00061 bool CLogicComparisonBlock::testLogic()
00062 {
00063         CLogicVariable var;
00064         if( _LogicStateMachine->getVariable( VariableName, var ) == false )
00065         {
00066                 nlwarning("(LOGIC)<CLogicComparisonBlock::testLogic> The variable %s is unknown in the state machine",VariableName.c_str());
00067                 return false;
00068         }
00069 
00070         if( Operator == "<"  )  return ( var.getValue() <  Comparand );
00071         if( Operator == "<=" )  return ( var.getValue() <= Comparand );
00072         if( Operator == ">"  )  return ( var.getValue() >  Comparand );
00073         if( Operator == ">=" )  return ( var.getValue() >= Comparand );
00074         if( Operator == "==" )  return ( var.getValue() == Comparand );
00075         if( Operator == "!=" )  return ( var.getValue() != Comparand );
00076 
00077         nlwarning("(LOGIC)<CLogicComparisonBlock::testLogic> The comparison block operator %s is unknown",Operator.c_str());
00078         return false;
00079 
00080 } // testLogic //
00081 
00082 
00083 //-------------------------------------------------
00084 // serial :
00085 //
00086 //-------------------------------------------------
00087 /*void CLogicComparisonBlock::serial( IStream &f )
00088 {
00089         f.xmlPush("COMPARISON_BLOCK");
00090         
00091         f.serial( VariableName );
00092         f.serial( Operator );
00093         f.serial( Comparand );
00094         
00095         f.xmlPop();
00096 
00097 } // serial //*/
00098 
00099 void CLogicComparisonBlock::write (xmlNodePtr node) const
00100 {
00101         xmlNodePtr elmPtr = xmlNewChild ( node, NULL, (const xmlChar*)"COMPARISON_BLOCK", NULL);
00102         xmlSetProp (elmPtr, (const xmlChar*)"VariableName", (const xmlChar*)VariableName.c_str());
00103         xmlSetProp (elmPtr, (const xmlChar*)"Operator", (const xmlChar*)Operator.c_str());
00104         xmlSetProp (elmPtr, (const xmlChar*)"Comparand", (const xmlChar*)toString(Comparand).c_str());
00105 }
00106 
00107 void CLogicComparisonBlock::read (xmlNodePtr node)
00108 {
00109         xmlCheckNodeName (node, "COMPARISON_BLOCK");
00110 
00111         VariableName = getXMLProp (node, "VariableName");
00112         Operator = getXMLProp (node, "Operator");
00113         Comparand = atoiInt64(getXMLProp (node, "Comparand").c_str());
00114 }
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 //-------------------------------------------------
00123 // setLogicStateMachine :
00124 //
00125 //-------------------------------------------------
00126 void CLogicConditionLogicBlock::setLogicStateMachine( CLogicStateMachine * logicStateMachine )
00127 { 
00128         if( logicStateMachine == 0 )
00129         {
00130                 nlwarning("(LOGIC)<CCLogicConditionLogicBlock::setLogicStateMachine> The state machine is null");
00131         }
00132         else
00133         {
00134                 // set the state machine of this node
00135                 _LogicStateMachine = logicStateMachine; 
00136 
00137                 // set the state machine of the logic block 
00138                 ComparisonBlock.setLogicStateMachine( logicStateMachine );
00139         }
00140 
00141 } // setLogicStateMachine //
00142 
00143 
00144 //-------------------------------------------------
00145 // testLogic :
00146 //
00147 //-------------------------------------------------
00148 bool CLogicConditionLogicBlock::testLogic()
00149 {
00150         switch( Type )
00151         {
00152                 case NOT :
00153                 {
00154                         return true;
00155                 }
00156                 break;
00157 
00158                 case COMPARISON :
00159                 {
00160                         return ComparisonBlock.testLogic();
00161                 }
00162                 break;
00163 
00164                 case SUB_CONDITION :
00165                 {
00166                         CLogicCondition condition;
00167                         if( _LogicStateMachine->getCondition(SubCondition,condition) )
00168                         {
00169                                 return condition.testLogic();
00170                         }
00171                         else
00172                         {
00173                                 nlwarning("(LOGIC)<CLogicConditionLogicBlock::testLogic> The subcondition \"%s\" is unknown in the state machine \"%s\"",
00174                                         SubCondition.c_str(),_LogicStateMachine->getName().c_str());
00175                         }
00176                         
00177                 }
00178 
00179                 default :
00180                         nlerror("(LOGIC)<CLogicConditionLogicBlock::testLogic> logic block type %d is unknown",Type);
00181         }
00182         
00183         return false;
00184 
00185 } // testLogic //
00186 
00187 
00188 
00189 //-------------------------------------------------
00190 // fillVarSet :
00191 //
00192 //-------------------------------------------------
00193 void CLogicConditionLogicBlock::fillVarSet( set<string>& condVars )
00194 {
00195         if( Type == COMPARISON )
00196         {
00197                 condVars.insert( ComparisonBlock.VariableName );
00198         }
00199         else
00200         {
00201                 if( Type == SUB_CONDITION )
00202                 {
00203                         CLogicCondition condition;
00204                         if( _LogicStateMachine->getCondition(SubCondition,condition) )
00205                         {
00206                                 condition.fillVarSet( condVars );
00207                         }
00208                 }
00209         }
00210 
00211 } // fillVarSet //
00212 
00213 
00214 //-------------------------------------------------
00215 // serial :
00216 //
00217 //-------------------------------------------------
00218 /*void CLogicConditionLogicBlock::serial( IStream &f )
00219 {
00220         f.xmlPush("CONDITION_LOGIC_BLOCK");
00221 
00222         f.serialEnum( Type );
00223         switch( Type )
00224         {
00225                 case NOT : break;
00226                         
00227                 case COMPARISON :
00228                 {
00229                         f.serial( ComparisonBlock );
00230                 }
00231                 break;
00232 
00233                 case SUB_CONDITION :
00234                 {
00235                         f.serial( SubCondition );
00236                 }
00237                 break;
00238         };
00239         
00240         f.xmlPop();
00241 };*/
00242 
00243 void CLogicConditionLogicBlock::write (xmlNodePtr node) const
00244 {
00245         xmlNodePtr elmPtr = xmlNewChild ( node, NULL, (const xmlChar*)"CONDITION_LOGIC_NODE", NULL);
00246         xmlSetProp (elmPtr, (const xmlChar*)"Type", (const xmlChar*)toString(Type).c_str());
00247         switch( Type )
00248         {
00249                 case NOT : break;
00250                         
00251                 case COMPARISON :
00252                 {
00253                         ComparisonBlock.write(elmPtr);
00254                 }
00255                 break;
00256 
00257                 case SUB_CONDITION :
00258                 {
00259                         xmlSetProp (elmPtr, (const xmlChar*)"SubCondition", (const xmlChar*)SubCondition.c_str());
00260                 }
00261                 break;
00262         };
00263 }
00264 
00265 void CLogicConditionLogicBlock::read (xmlNodePtr node)
00266 {
00267         xmlCheckNodeName (node, "CONDITION_LOGIC_NODE");
00268 
00269         Type = (TLogicConditionLogicBlockType)atoi(getXMLProp (node, "Type").c_str());
00270         switch( Type )
00271         {
00272                 case NOT : break;
00273                         
00274                 case COMPARISON :
00275                 {
00276                         ComparisonBlock.read (node);
00277                 }
00278                 break;
00279 
00280                 case SUB_CONDITION :
00281                 {
00282                         SubCondition = getXMLProp (node, "SubCondition");
00283                 }
00284                 break;
00285         };
00286 }
00287 
00288 //-----------------------------------------
00289 
00290 
00291 
00292 //-------------------------------------------------
00293 // setLogicStateMachine :
00294 //
00295 //-------------------------------------------------
00296 void CLogicConditionNode::setLogicStateMachine( CLogicStateMachine * logicStateMachine )
00297 { 
00298         if( logicStateMachine == 0 )
00299         {
00300                 nlwarning("(LOGIC)<CLogicConditionNode::setLogicStateMachine> The state machine is null");
00301         }
00302         else
00303         {
00304                 // set the state machine of this node
00305                 _LogicStateMachine = logicStateMachine; 
00306 
00307                 // set the state machine of the logic block 
00308                 LogicBlock.setLogicStateMachine( logicStateMachine );
00309                 
00310                 // set the state machine for the sub nodes
00311                 vector<CLogicConditionNode *>::iterator itNodes;
00312                 for( itNodes = _Nodes.begin(); itNodes != _Nodes.end(); ++itNodes )
00313                 {
00314                         (*itNodes)->setLogicStateMachine( logicStateMachine );
00315                 }
00316         }
00317 
00318 } // setLogicStateMachine //
00319 
00320 
00321 //-------------------------------------------------
00322 // addNode :
00323 //
00324 //-------------------------------------------------
00325 void CLogicConditionNode::addNode( CLogicConditionNode * node )
00326 {
00327         node->setLogicStateMachine( _LogicStateMachine );
00328         _Nodes.push_back( node );
00329 
00330 } // addToSubNodes //
00331 
00332 
00333 //-------------------------------------------------
00334 // testLogic :
00335 //
00336 //-------------------------------------------------
00337 bool CLogicConditionNode::testLogic()
00338 {
00339         // test the logic block
00340         if( LogicBlock.testLogic() == false )
00341         {
00342                 return false;
00343         }
00344 
00345         // if there's no subtree we assess the subtree is true
00346         if( _Nodes.size() == 0 )
00347         {
00348                 return true;
00349         }
00350 
00351         // test the subtree
00352         if( LogicBlock.isNotBlock() )
00353         {
00354                 // the subtree is false if at least one node is true
00355                 vector<CLogicConditionNode *>::iterator itNodes;
00356                 for( itNodes = _Nodes.begin(); itNodes != _Nodes.end(); ++itNodes )
00357                 {
00358                         if( (*itNodes)->testLogic() == true )
00359                         {
00360                                 return false;
00361                         }
00362                 }
00363 
00364                 return true;
00365         }
00366         else
00367         {
00368                 // the subtree is true if at least one node is true
00369                 vector<CLogicConditionNode *>::iterator itNodes;
00370                 for( itNodes = _Nodes.begin(); itNodes != _Nodes.end(); ++itNodes )
00371                 {
00372                         if( (*itNodes)->testLogic() == true )
00373                         {
00374                                 return true;
00375                         }
00376                 }
00377 
00378                 return false;
00379         }
00380 
00381 } // testLogic //
00382 
00383 
00384 //-------------------------------------------------
00385 // fillVarSet :
00386 //
00387 //-------------------------------------------------
00388 void CLogicConditionNode::fillVarSet( set<string>& condVars )
00389 {
00390         if( Type == LOGIC_NODE )
00391         {
00392                 LogicBlock.fillVarSet( condVars );
00393         }
00394 
00395         vector<CLogicConditionNode *>::iterator itNode;
00396         for( itNode = _Nodes.begin(); itNode != _Nodes.end(); ++itNode )
00397         {
00398                 (*itNode)->fillVarSet( condVars );
00399         }
00400 
00401 } // fillVarSet //
00402 
00403 
00404 //-------------------------------------------------
00405 // serial :
00406 //
00407 //-------------------------------------------------
00408 /*void CLogicConditionNode::serial( IStream &f )
00409 {
00410         f.xmlPush("CONDITION_NODE");
00411         
00412         f.serialEnum( Type );
00413         switch( Type )
00414         {
00415                 case TERMINATOR : break;
00416                 case LOGIC_NODE :
00417                 {
00418                         f.serial( LogicBlock );
00419                         if( f.isReading() )
00420                         {
00421                                 uint32 sz;
00422                                 f.serial( sz );
00423                                 uint i;
00424                                 for( i = 0; i < sz; i++ )
00425                                 {
00426                                         CLogicConditionNode * node = new CLogicConditionNode();
00427                                         f.serial( *node );
00428                                         _Nodes.push_back( node );
00429                                 }
00430                         }
00431                         else
00432                         {
00433                                 uint32 sz = _Nodes.size();
00434                                 f.serial( sz );
00435                                 vector<CLogicConditionNode *>::iterator itNode;
00436                                 for( itNode = _Nodes.begin(); itNode != _Nodes.end(); ++itNode )
00437                                 {
00438                                         f.serial( **itNode );
00439                                 }
00440                         }
00441                 }
00442                 break;
00443         };
00444 
00445         f.xmlPop();
00446 
00447 } // serial //*/
00448 
00449 void CLogicConditionNode::write (xmlNodePtr node) const
00450 {
00451         xmlNodePtr elmPtr = xmlNewChild ( node, NULL, (const xmlChar*)"CONDITION_NODE", NULL);
00452         xmlSetProp (elmPtr, (const xmlChar*)"Type", (const xmlChar*)toString(Type).c_str());
00453 
00454         switch( Type )
00455         {
00456                 case TERMINATOR : break;
00457                 case LOGIC_NODE :
00458                 {
00459                         LogicBlock.write(elmPtr);
00460                         vector<CLogicConditionNode *>::const_iterator itNode = _Nodes.begin();
00461                         for( ; itNode != _Nodes.end(); ++itNode )
00462                         {
00463                                 (*itNode)->write(elmPtr);
00464                         }
00465                 }
00466                 break;
00467         };
00468 }
00469 
00470 void CLogicConditionNode::read (xmlNodePtr node)
00471 {
00472         xmlCheckNodeName (node, "CONDITION_NODE");
00473 
00474         Type = (TConditionNodeType )atoi(getXMLProp (node, "Type").c_str());
00475         switch( Type )
00476         {
00477                 case TERMINATOR : break;
00478                 case LOGIC_NODE :
00479                 {
00480                         LogicBlock.read (node);
00481 
00482                         {
00483                                 // Count the parent
00484                                 uint nb = CIXml::countChildren (node, "CONDITION_NODE");
00485                                 uint i = 0;
00486                                 xmlNodePtr parent = CIXml::getFirstChildNode (node, "CONDITION_NODE");
00487                                 while (i<nb)
00488                                 {
00489                                         CLogicConditionNode *v = new CLogicConditionNode();
00490                                         v->read(parent);
00491                                         _Nodes.push_back (v);
00492 
00493                                         // Next parent
00494                                         parent = CIXml::getNextChildNode (parent, "CONDITION_NODE");
00495                                         i++;
00496                                 }
00497                         }
00498                 }
00499                 break;
00500         };
00501 }
00502 
00503 //-------------------------------------------------
00504 // ~CLogicConditionNode :
00505 //
00506 //-------------------------------------------------
00507 CLogicConditionNode::~CLogicConditionNode()
00508 {
00509         vector<CLogicConditionNode *>::iterator itNodes;
00510         for( itNodes = _Nodes.begin(); itNodes != _Nodes.end(); ++itNodes )
00511         {
00512                 delete (*itNodes);
00513         }
00514 
00515 } // ~CLogicConditionNode //
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 //-------------------------------------------------
00524 // setLogicStateMachine :
00525 //
00526 //-------------------------------------------------
00527 void CLogicCondition::setLogicStateMachine( CLogicStateMachine * logicStateMachine )
00528 { 
00529         if( logicStateMachine == 0 )
00530         {
00531                 nlwarning("(LOGIC)<CLogicCondition::setLogicStateMachine> The state machine is null");
00532         }
00533         else
00534         {
00535                 // init the logic state machine for each node
00536                 vector<CLogicConditionNode>::iterator itNodes;
00537                 for( itNodes = Nodes.begin(); itNodes != Nodes.end(); ++itNodes )
00538                 {
00539                         (*itNodes).setLogicStateMachine( logicStateMachine );
00540                 }
00541         }
00542 
00543 } // setLogicStateMachine //
00544 
00545 
00546 //-------------------------------------------------
00547 // testLogic :
00548 //
00549 //-------------------------------------------------
00550 bool CLogicCondition::testLogic()
00551 {
00552         vector<CLogicConditionNode>::iterator itNodes;
00553         for( itNodes = Nodes.begin(); itNodes != Nodes.end(); ++itNodes )
00554         {
00555                 if( (*itNodes).testLogic() == false )
00556                 {
00557                         return false;
00558                 }
00559         }
00560 
00561         return true;
00562 
00563 } // testLogic //
00564 
00565 
00566 
00567 //-------------------------------------------------
00568 // fillVarSet :
00569 //
00570 //-------------------------------------------------
00571 void CLogicCondition::fillVarSet( set<string>& condVars )
00572 {
00573         vector<CLogicConditionNode>::iterator itNode;
00574         for( itNode = Nodes.begin(); itNode != Nodes.end(); ++itNode )
00575         {
00576                 (*itNode).fillVarSet( condVars );
00577         }
00578 
00579 } // fillVarSet //
00580 
00581 
00582 
00583 //-------------------------------------------------
00584 // serial :
00585 //
00586 //-------------------------------------------------
00587 /*void CLogicCondition::serial( IStream &f )
00588 {
00589         f.xmlPush("CONDITION");
00590         
00591         f.serial( _ConditionName );
00592         f.serialCont( Nodes );
00593 
00594         f.xmlPop();
00595 
00596 } // serial //*/
00597 
00598 void CLogicCondition::write (xmlNodePtr node) const
00599 {
00600         xmlNodePtr elmPtr = xmlNewChild ( node, NULL, (const xmlChar*)"CONDITION", NULL);
00601         xmlSetProp (elmPtr, (const xmlChar*)"Name", (const xmlChar*)_ConditionName.c_str());
00602 
00603         uint i;
00604         for (i = 0; i < Nodes.size(); i++)
00605         {
00606                 Nodes[i].write(elmPtr);
00607         }
00608 }
00609 
00610 void CLogicCondition::read (xmlNodePtr node)
00611 {
00612         xmlCheckNodeName (node, "CONDITION");
00613 
00614         _ConditionName = getXMLProp (node, "Name");
00615 
00616         {
00617                 // Count the parent
00618                 uint nb = CIXml::countChildren (node, "CONDITION_NODE");
00619                 uint i = 0;
00620                 xmlNodePtr parent = CIXml::getFirstChildNode (node, "CONDITION_NODE");
00621                 while (i<nb)
00622                 {
00623                         CLogicConditionNode v;
00624                         v.read(parent);
00625                         Nodes.push_back (v);
00626 
00627                         // Next parent
00628                         parent = CIXml::getNextChildNode (parent, "CONDITION_NODE");
00629                         i++;
00630                 }
00631         }
00632 }
00633 
00634 
00635 } // NLLOGIC