00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "nel/logic/logic_state.h"
00028 #include "nel/logic/logic_state_machine.h"
00029
00030
00031 using namespace std;
00032 using namespace NLMISC;
00033 using namespace NLNET;
00034
00035 namespace NLLOGIC
00036 {
00037
00038
00039
00040
00041
00042 CLogicState::CLogicState()
00043 {
00044 _StateName = "no_state";
00045 _LogicStateMachine = 0;
00046
00047 }
00048
00049
00050
00051
00052
00053
00054 void CLogicState::setLogicStateMachine( CLogicStateMachine * logicStateMachine )
00055 {
00056 if( logicStateMachine == 0 )
00057 {
00058 nlwarning("(LOGIC)<CLogicCondition::setLogicStateMachine> The state machine is null");
00059 }
00060 else
00061 {
00062
00063 _LogicStateMachine = logicStateMachine;
00064
00065
00066 vector<CLogicEvent>::iterator itEvent;
00067 for( itEvent = _Events.begin(); itEvent != _Events.end(); ++itEvent )
00068 {
00069 (*itEvent).setLogicStateMachine( logicStateMachine );
00070 }
00071 }
00072
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 void CLogicState::addEvent( CLogicEvent event )
00082 {
00083 event.setLogicStateMachine( _LogicStateMachine );
00084 _Events.push_back( event );
00085
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 void CLogicState::addSIdMap( const TSIdMap& sIdMap )
00097 {
00098 vector<CLogicEventMessage>::iterator itMsg;
00099
00101 for( itMsg = _EntryMessages.begin(); itMsg != _EntryMessages.end(); ++itMsg )
00102 {
00103 TSIdMap::const_iterator itId = sIdMap.find( (*itMsg).Destination );
00104
00105 if( itId != sIdMap.end() )
00106 {
00107 (*itMsg).DestinationId = (*itId).second;
00108 }
00109 }
00111 trySendEntryMessages();
00112
00113
00114
00115 vector<CLogicEvent>::iterator itEvt;
00116 for( itEvt = _Events.begin(); itEvt != _Events.end(); ++itEvt )
00117 {
00118 string dest = (*itEvt).EventAction.EventMessage.Destination;
00119 TSIdMap::const_iterator itId = sIdMap.find( dest );
00120
00121 if( itId != sIdMap.end() )
00122 {
00123 (*itEvt).EventAction.EventMessage.DestinationId = (*itId).second;
00124 }
00125 }
00127 trySendEventMessages();
00128
00129
00131 for( itMsg = _ExitMessages.begin(); itMsg != _ExitMessages.end(); ++itMsg )
00132 {
00133 TSIdMap::const_iterator itId = sIdMap.find( (*itMsg).Destination );
00134
00135 if( itId != sIdMap.end() )
00136 {
00137 (*itMsg).DestinationId = (*itId).second;
00138 }
00139 }
00140
00141 }
00142
00143
00144
00145
00146
00147
00148 void CLogicState::processLogic()
00149 {
00150
00151 vector<CLogicEvent>::iterator itEvent;
00152 for( itEvent = _Events.begin(); itEvent != _Events.end(); ++itEvent )
00153 {
00154 if( (*itEvent).testCondition() )
00155 {
00156
00157 if( (*itEvent).EventAction.IsStateChange )
00158 {
00159 _LogicStateMachine->setCurrentState( (*itEvent).EventAction.StateChange );
00160 }
00161 else
00162 {
00163
00164 (*itEvent).EventAction.enableSendMessage();
00165
00167 trySendEventMessages();
00168 }
00169 }
00170 else
00171 {
00172
00173
00174 }
00175 }
00176
00177 }
00178
00179
00180
00181
00182
00183
00184 void CLogicState::enterState()
00185 {
00187 trySendEntryMessages();
00188
00189 }
00190
00191
00192
00193
00194
00195
00196 void CLogicState::exitState()
00197 {
00198 vector<CLogicEventMessage>::iterator itMsg;
00199 for( itMsg = _ExitMessages.begin(); itMsg != _ExitMessages.end(); ++itMsg )
00200 {
00201 if( (*itMsg).DestinationId != CEntityId() )
00202 {
00203 CMessage msgOut( (*itMsg).MessageId );
00204 msgOut.serial( (*itMsg).Arguments );
00205
00206 _MessagesToSend.insert( make_pair((*itMsg).DestinationId,msgOut) );
00207 }
00208 }
00209
00210
00211 for( itMsg = _EntryMessages.begin(); itMsg != _EntryMessages.end(); ++itMsg )
00212 {
00213 (*itMsg).ToSend = false;
00214 (*itMsg).Sent = false;
00215 }
00216
00217
00218 vector<CLogicEvent>::iterator itEvent;
00219 for( itEvent = _Events.begin(); itEvent != _Events.end(); ++itEvent )
00220 {
00221 (*itEvent).reset();
00222 }
00223
00224
00225 for( itMsg = _ExitMessages.begin(); itMsg != _ExitMessages.end(); ++itMsg )
00226 {
00227 (*itMsg).ToSend = false;
00228 (*itMsg).Sent = false;
00229 }
00230
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 void CLogicState::trySendEntryMessages()
00240 {
00242 vector<CLogicEventMessage>::iterator itMsg;
00243 for( itMsg = _EntryMessages.begin(); itMsg != _EntryMessages.end(); ++itMsg )
00244 {
00245 if( !(*itMsg).Sent && (*itMsg).DestinationId.getType() != 0xfe )
00246 {
00247 CMessage msgOut( (*itMsg).MessageId );
00248 msgOut.serial( (*itMsg).Arguments );
00249
00250 _MessagesToSend.insert( make_pair((*itMsg).DestinationId,msgOut) );
00251
00252 (*itMsg).ToSend = false;
00253 (*itMsg).Sent = true;
00254 }
00255 }
00256
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 void CLogicState::trySendEventMessages()
00266 {
00267
00268 vector<CLogicEvent>::iterator itEvent;
00269 for( itEvent = _Events.begin(); itEvent != _Events.end(); ++itEvent )
00270 {
00271 if( (*itEvent).EventAction.EventMessage.ToSend == true )
00272 {
00273 if( (*itEvent).EventAction.EventMessage.Sent == false )
00274 {
00275 if( (*itEvent).EventAction.EventMessage.DestinationId.getType() != 0xfe )
00276 {
00277 CMessage msgOut( (*itEvent).EventAction.EventMessage.MessageId );
00278 msgOut.serial( (*itEvent).EventAction.EventMessage.Arguments );
00279
00280 _MessagesToSend.insert( make_pair((*itEvent).EventAction.EventMessage.DestinationId,msgOut) );
00281
00282 (*itEvent).EventAction.EventMessage.ToSend = false;
00283 (*itEvent).EventAction.EventMessage.Sent = true;
00284 }
00285 }
00286 }
00287 }
00288
00289 }
00290
00291
00292
00293
00294
00295
00296 void CLogicState::getMessagesToSend( multimap<CEntityId,CMessage>& msgs )
00297 {
00298 multimap<CEntityId,CMessage>::iterator itMsg;
00299 for( itMsg = _MessagesToSend.begin(); itMsg != _MessagesToSend.end(); ++itMsg )
00300 {
00301 msgs.insert( *itMsg );
00302 }
00303
00304
00305 _MessagesToSend.clear();
00306
00307 }
00308
00309
00310
00311
00312
00313
00314
00315 void CLogicState::fillVarMap( multimap<CEntityId,string >& stateMachineVariables )
00316 {
00317
00318 vector<CLogicEvent>::iterator itEvt;
00319 for( itEvt = _Events.begin(); itEvt != _Events.end(); ++itEvt )
00320 {
00321
00322 CLogicCondition condition;
00323 if( _LogicStateMachine->getCondition((*itEvt).ConditionName,condition) )
00324 {
00325
00326 set<string> condVars;
00327 condition.fillVarSet( condVars );
00328
00329
00330 set<string>::iterator itCV;
00331 for( itCV = condVars.begin(); itCV != condVars.end(); ++itCV )
00332 {
00333 stateMachineVariables.insert( make_pair((*itEvt).EventAction.EventMessage.DestinationId,*itCV) );
00334 }
00335 }
00336 }
00337
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 void CLogicState::write (xmlNodePtr node) const
00360 {
00361 xmlNodePtr elmPtr = xmlNewChild ( node, NULL, (const xmlChar*)"STATE", NULL);
00362 xmlSetProp (elmPtr, (const xmlChar*)"Name", (const xmlChar*)_StateName.c_str());
00363
00364 uint i;
00365 for (i = 0; i < _EntryMessages.size(); i++)
00366 {
00367 _EntryMessages[i].write(elmPtr, "ENTRY_");
00368 }
00369 for (i = 0; i < _ExitMessages.size(); i++)
00370 {
00371 _ExitMessages[i].write(elmPtr, "EXIT_");
00372 }
00373 for (i = 0; i < _Events.size(); i++)
00374 {
00375 _Events[i].write(elmPtr);
00376 }
00377 }
00378
00379 void CLogicState::read (xmlNodePtr node)
00380 {
00381 xmlCheckNodeName (node, "STATE");
00382
00383 _StateName = getXMLProp (node, "Name");
00384
00385 {
00386
00387 uint nb = CIXml::countChildren (node, "ENTRY_EVENT_MESSAGE");
00388 uint i = 0;
00389 xmlNodePtr parent = CIXml::getFirstChildNode (node, "ENTRY_EVENT_MESSAGE");
00390 while (i<nb)
00391 {
00392 CLogicEventMessage v;
00393 v.read(parent);
00394 _EntryMessages.push_back(v);
00395
00396
00397 parent = CIXml::getNextChildNode (parent, "ENTRY_EVENT_MESSAGE");
00398 i++;
00399 }
00400 }
00401
00402 {
00403
00404 uint nb = CIXml::countChildren (node, "EXIT_EVENT_MESSAGE");
00405 uint i = 0;
00406 xmlNodePtr parent = CIXml::getFirstChildNode (node, "EXIT_EVENT_MESSAGE");
00407 while (i<nb)
00408 {
00409 CLogicEventMessage v;
00410 v.read(parent);
00411 _ExitMessages.push_back(v);
00412
00413
00414 parent = CIXml::getNextChildNode (parent, "EXIT_EVENT_MESSAGE");
00415 i++;
00416 }
00417 }
00418
00419 {
00420
00421 uint nb = CIXml::countChildren (node, "EVENT");
00422 uint i = 0;
00423 xmlNodePtr parent = CIXml::getFirstChildNode (node, "EVENT");
00424 while (i<nb)
00425 {
00426 CLogicEvent v;
00427 v.read(parent);
00428 _Events.push_back(v);
00429
00430
00431 parent = CIXml::getNextChildNode (parent, "EVENT");
00432 i++;
00433 }
00434 }
00435
00436 }
00437
00438
00439 }
00440