1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/logic/logic_condition.h"
21 #include "nel/logic/logic_variable.h"
22 #include "nel/logic/logic_state_machine.h"
24 #include "nel/misc/o_xml.h"
26 using namespace NLMISC
;
32 //-------------------------------------------------
33 // setLogicStateMachine :
35 //-------------------------------------------------
36 void CLogicComparisonBlock::setLogicStateMachine( CLogicStateMachine
* logicStateMachine
)
38 if( logicStateMachine
== 0 )
40 nlwarning("(LOGIC)<CLogicComparisonBlock::setLogicStateMachine> The state machine is null");
44 _LogicStateMachine
= logicStateMachine
;
47 } // setLogicStateMachine //
50 //-------------------------------------------------
53 //-------------------------------------------------
54 bool CLogicComparisonBlock::testLogic()
57 if( _LogicStateMachine
->getVariable( VariableName
, var
) == false )
59 nlwarning("(LOGIC)<CLogicComparisonBlock::testLogic> The variable %s is unknown in the state machine",VariableName
.c_str());
63 if( Operator
== "<" ) return ( var
.getValue() < Comparand
);
64 if( Operator
== "<=" ) return ( var
.getValue() <= Comparand
);
65 if( Operator
== ">" ) return ( var
.getValue() > Comparand
);
66 if( Operator
== ">=" ) return ( var
.getValue() >= Comparand
);
67 if( Operator
== "==" ) return ( var
.getValue() == Comparand
);
68 if( Operator
== "!=" ) return ( var
.getValue() != Comparand
);
70 nlwarning("(LOGIC)<CLogicComparisonBlock::testLogic> The comparison block operator %s is unknown",Operator
.c_str());
76 //-------------------------------------------------
79 //-------------------------------------------------
80 /*void CLogicComparisonBlock::serial( IStream &f )
82 f.xmlPush("COMPARISON_BLOCK");
84 f.serial( VariableName );
86 f.serial( Comparand );
92 void CLogicComparisonBlock::write (xmlNodePtr node
) const
94 xmlNodePtr elmPtr
= xmlNewChild ( node
, NULL
, (const xmlChar
*)"COMPARISON_BLOCK", NULL
);
95 xmlSetProp (elmPtr
, (const xmlChar
*)"VariableName", (const xmlChar
*)VariableName
.c_str());
96 xmlSetProp (elmPtr
, (const xmlChar
*)"Operator", (const xmlChar
*)Operator
.c_str());
97 xmlSetProp (elmPtr
, (const xmlChar
*)"Comparand", (const xmlChar
*)toString(Comparand
).c_str());
100 void CLogicComparisonBlock::read (xmlNodePtr node
)
102 xmlCheckNodeName (node
, "COMPARISON_BLOCK");
104 VariableName
= getXMLProp (node
, "VariableName");
105 Operator
= getXMLProp (node
, "Operator");
106 Comparand
= atoiInt64(getXMLProp (node
, "Comparand").c_str());
115 //-------------------------------------------------
116 // setLogicStateMachine :
118 //-------------------------------------------------
119 void CLogicConditionLogicBlock::setLogicStateMachine( CLogicStateMachine
* logicStateMachine
)
121 if( logicStateMachine
== 0 )
123 nlwarning("(LOGIC)<CCLogicConditionLogicBlock::setLogicStateMachine> The state machine is null");
127 // set the state machine of this node
128 _LogicStateMachine
= logicStateMachine
;
130 // set the state machine of the logic block
131 ComparisonBlock
.setLogicStateMachine( logicStateMachine
);
134 } // setLogicStateMachine //
137 //-------------------------------------------------
140 //-------------------------------------------------
141 bool CLogicConditionLogicBlock::testLogic()
153 return ComparisonBlock
.testLogic();
159 CLogicCondition condition
;
160 if( _LogicStateMachine
->getCondition(SubCondition
,condition
) )
162 return condition
.testLogic();
166 nlwarning("(LOGIC)<CLogicConditionLogicBlock::testLogic> The subcondition \"%s\" is unknown in the state machine \"%s\"",
167 SubCondition
.c_str(),_LogicStateMachine
->getName().c_str());
173 nlerror("(LOGIC)<CLogicConditionLogicBlock::testLogic> logic block type %d is unknown",Type
);
182 //-------------------------------------------------
185 //-------------------------------------------------
186 void CLogicConditionLogicBlock::fillVarSet( set
<string
>& condVars
)
188 if( Type
== COMPARISON
)
190 condVars
.insert( ComparisonBlock
.VariableName
);
194 if( Type
== SUB_CONDITION
)
196 CLogicCondition condition
;
197 if( _LogicStateMachine
->getCondition(SubCondition
,condition
) )
199 condition
.fillVarSet( condVars
);
207 //-------------------------------------------------
210 //-------------------------------------------------
211 /*void CLogicConditionLogicBlock::serial( IStream &f )
213 f.xmlPush("CONDITION_LOGIC_BLOCK");
215 f.serialEnum( Type );
222 f.serial( ComparisonBlock );
228 f.serial( SubCondition );
236 void CLogicConditionLogicBlock::write (xmlNodePtr node
) const
238 xmlNodePtr elmPtr
= xmlNewChild ( node
, NULL
, (const xmlChar
*)"CONDITION_LOGIC_NODE", NULL
);
239 xmlSetProp (elmPtr
, (const xmlChar
*)"Type", (const xmlChar
*)toString((uint32
)Type
).c_str());
246 ComparisonBlock
.write(elmPtr
);
252 xmlSetProp (elmPtr
, (const xmlChar
*)"SubCondition", (const xmlChar
*)SubCondition
.c_str());
258 void CLogicConditionLogicBlock::read (xmlNodePtr node
)
260 xmlCheckNodeName (node
, "CONDITION_LOGIC_NODE");
262 NLMISC::fromString(getXMLProp(node
, "Type"), uType
);
263 Type
= (TLogicConditionLogicBlockType
)uType
;
270 ComparisonBlock
.read (node
);
276 SubCondition
= getXMLProp (node
, "SubCondition");
282 //-----------------------------------------
286 //-------------------------------------------------
287 // setLogicStateMachine :
289 //-------------------------------------------------
290 void CLogicConditionNode::setLogicStateMachine( CLogicStateMachine
* logicStateMachine
)
292 if( logicStateMachine
== 0 )
294 nlwarning("(LOGIC)<CLogicConditionNode::setLogicStateMachine> The state machine is null");
298 // set the state machine of this node
299 _LogicStateMachine
= logicStateMachine
;
301 // set the state machine of the logic block
302 LogicBlock
.setLogicStateMachine( logicStateMachine
);
304 // set the state machine for the sub nodes
305 vector
<CLogicConditionNode
*>::iterator itNodes
;
306 for( itNodes
= _Nodes
.begin(); itNodes
!= _Nodes
.end(); ++itNodes
)
308 (*itNodes
)->setLogicStateMachine( logicStateMachine
);
312 } // setLogicStateMachine //
315 //-------------------------------------------------
318 //-------------------------------------------------
319 void CLogicConditionNode::addNode( CLogicConditionNode
* node
)
321 node
->setLogicStateMachine( _LogicStateMachine
);
322 _Nodes
.push_back( node
);
324 } // addToSubNodes //
327 //-------------------------------------------------
330 //-------------------------------------------------
331 bool CLogicConditionNode::testLogic()
333 // test the logic block
334 if( LogicBlock
.testLogic() == false )
339 // if there's no subtree we assess the subtree is true
346 if( LogicBlock
.isNotBlock() )
348 // the subtree is false if at least one node is true
349 vector
<CLogicConditionNode
*>::iterator itNodes
;
350 for( itNodes
= _Nodes
.begin(); itNodes
!= _Nodes
.end(); ++itNodes
)
352 if( (*itNodes
)->testLogic() == true )
362 // the subtree is true if at least one node is true
363 vector
<CLogicConditionNode
*>::iterator itNodes
;
364 for( itNodes
= _Nodes
.begin(); itNodes
!= _Nodes
.end(); ++itNodes
)
366 if( (*itNodes
)->testLogic() == true )
378 //-------------------------------------------------
381 //-------------------------------------------------
382 void CLogicConditionNode::fillVarSet( set
<string
>& condVars
)
384 if( Type
== LOGIC_NODE
)
386 LogicBlock
.fillVarSet( condVars
);
389 vector
<CLogicConditionNode
*>::iterator itNode
;
390 for( itNode
= _Nodes
.begin(); itNode
!= _Nodes
.end(); ++itNode
)
392 (*itNode
)->fillVarSet( condVars
);
398 //-------------------------------------------------
401 //-------------------------------------------------
402 /*void CLogicConditionNode::serial( IStream &f )
404 f.xmlPush("CONDITION_NODE");
406 f.serialEnum( Type );
409 case TERMINATOR : break;
412 f.serial( LogicBlock );
418 for( i = 0; i < sz; i++ )
420 CLogicConditionNode * node = new CLogicConditionNode();
422 _Nodes.push_back( node );
427 uint32 sz = _Nodes.size();
429 vector<CLogicConditionNode *>::iterator itNode;
430 for( itNode = _Nodes.begin(); itNode != _Nodes.end(); ++itNode )
432 f.serial( **itNode );
443 void CLogicConditionNode::write (xmlNodePtr node
) const
445 xmlNodePtr elmPtr
= xmlNewChild ( node
, NULL
, (const xmlChar
*)"CONDITION_NODE", NULL
);
446 xmlSetProp (elmPtr
, (const xmlChar
*)"Type", (const xmlChar
*)toString((uint32
)Type
).c_str());
450 case TERMINATOR
: break;
453 LogicBlock
.write(elmPtr
);
454 vector
<CLogicConditionNode
*>::const_iterator itNode
= _Nodes
.begin();
455 for( ; itNode
!= _Nodes
.end(); ++itNode
)
457 (*itNode
)->write(elmPtr
);
464 void CLogicConditionNode::read (xmlNodePtr node
)
466 xmlCheckNodeName (node
, "CONDITION_NODE");
468 NLMISC::fromString(getXMLProp(node
, "Type"), uType
);
469 Type
= (TConditionNodeType
)uType
;
472 case TERMINATOR
: break;
475 LogicBlock
.read (node
);
479 uint nb
= CIXml::countChildren (node
, "CONDITION_NODE");
481 xmlNodePtr parent
= CIXml::getFirstChildNode (node
, "CONDITION_NODE");
484 CLogicConditionNode
*v
= new CLogicConditionNode();
486 _Nodes
.push_back (v
);
489 parent
= CIXml::getNextChildNode (parent
, "CONDITION_NODE");
498 //-------------------------------------------------
499 // ~CLogicConditionNode :
501 //-------------------------------------------------
502 CLogicConditionNode::~CLogicConditionNode()
504 vector
<CLogicConditionNode
*>::iterator itNodes
;
505 for( itNodes
= _Nodes
.begin(); itNodes
!= _Nodes
.end(); ++itNodes
)
510 } // ~CLogicConditionNode //
518 //-------------------------------------------------
519 // setLogicStateMachine :
521 //-------------------------------------------------
522 void CLogicCondition::setLogicStateMachine( CLogicStateMachine
* logicStateMachine
)
524 if( logicStateMachine
== 0 )
526 nlwarning("(LOGIC)<CLogicCondition::setLogicStateMachine> The state machine is null");
530 // init the logic state machine for each node
531 vector
<CLogicConditionNode
>::iterator itNodes
;
532 for( itNodes
= Nodes
.begin(); itNodes
!= Nodes
.end(); ++itNodes
)
534 (*itNodes
).setLogicStateMachine( logicStateMachine
);
538 } // setLogicStateMachine //
541 //-------------------------------------------------
544 //-------------------------------------------------
545 bool CLogicCondition::testLogic()
547 vector
<CLogicConditionNode
>::iterator itNodes
;
548 for( itNodes
= Nodes
.begin(); itNodes
!= Nodes
.end(); ++itNodes
)
550 if( (*itNodes
).testLogic() == false )
562 //-------------------------------------------------
565 //-------------------------------------------------
566 void CLogicCondition::fillVarSet( set
<string
>& condVars
)
568 vector
<CLogicConditionNode
>::iterator itNode
;
569 for( itNode
= Nodes
.begin(); itNode
!= Nodes
.end(); ++itNode
)
571 (*itNode
).fillVarSet( condVars
);
578 //-------------------------------------------------
581 //-------------------------------------------------
582 /*void CLogicCondition::serial( IStream &f )
584 f.xmlPush("CONDITION");
586 f.serial( _ConditionName );
587 f.serialCont( Nodes );
593 void CLogicCondition::write (xmlNodePtr node
) const
595 xmlNodePtr elmPtr
= xmlNewChild ( node
, NULL
, (const xmlChar
*)"CONDITION", NULL
);
596 xmlSetProp (elmPtr
, (const xmlChar
*)"Name", (const xmlChar
*)_ConditionName
.c_str());
599 for (i
= 0; i
< Nodes
.size(); i
++)
601 Nodes
[i
].write(elmPtr
);
605 void CLogicCondition::read (xmlNodePtr node
)
607 xmlCheckNodeName (node
, "CONDITION");
609 _ConditionName
= getXMLProp (node
, "Name");
613 uint nb
= CIXml::countChildren (node
, "CONDITION_NODE");
615 xmlNodePtr parent
= CIXml::getFirstChildNode (node
, "CONDITION_NODE");
618 CLogicConditionNode v
;
623 parent
= CIXml::getNextChildNode (parent
, "CONDITION_NODE");