00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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 }
00055
00056
00057
00058
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 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
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
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
00135 _LogicStateMachine = logicStateMachine;
00136
00137
00138 ComparisonBlock.setLogicStateMachine( logicStateMachine );
00139 }
00140
00141 }
00142
00143
00144
00145
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 }
00186
00187
00188
00189
00190
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 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
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
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
00305 _LogicStateMachine = logicStateMachine;
00306
00307
00308 LogicBlock.setLogicStateMachine( logicStateMachine );
00309
00310
00311 vector<CLogicConditionNode *>::iterator itNodes;
00312 for( itNodes = _Nodes.begin(); itNodes != _Nodes.end(); ++itNodes )
00313 {
00314 (*itNodes)->setLogicStateMachine( logicStateMachine );
00315 }
00316 }
00317
00318 }
00319
00320
00321
00322
00323
00324
00325 void CLogicConditionNode::addNode( CLogicConditionNode * node )
00326 {
00327 node->setLogicStateMachine( _LogicStateMachine );
00328 _Nodes.push_back( node );
00329
00330 }
00331
00332
00333
00334
00335
00336
00337 bool CLogicConditionNode::testLogic()
00338 {
00339
00340 if( LogicBlock.testLogic() == false )
00341 {
00342 return false;
00343 }
00344
00345
00346 if( _Nodes.size() == 0 )
00347 {
00348 return true;
00349 }
00350
00351
00352 if( LogicBlock.isNotBlock() )
00353 {
00354
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
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 }
00382
00383
00384
00385
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 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
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
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
00494 parent = CIXml::getNextChildNode (parent, "CONDITION_NODE");
00495 i++;
00496 }
00497 }
00498 }
00499 break;
00500 };
00501 }
00502
00503
00504
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 }
00516
00517
00518
00519
00520
00521
00522
00523
00524
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
00536 vector<CLogicConditionNode>::iterator itNodes;
00537 for( itNodes = Nodes.begin(); itNodes != Nodes.end(); ++itNodes )
00538 {
00539 (*itNodes).setLogicStateMachine( logicStateMachine );
00540 }
00541 }
00542
00543 }
00544
00545
00546
00547
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 }
00564
00565
00566
00567
00568
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 }
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
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
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
00628 parent = CIXml::getNextChildNode (parent, "CONDITION_NODE");
00629 i++;
00630 }
00631 }
00632 }
00633
00634
00635 }