00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "nel/ai/agent/agent.h"
00025 #include "nel/ai/agent/object_type.h"
00026 #include "nel/ai/agent/agent_local_mailer.h"
00027 #include "nel/ai/agent/agent_digital.h"
00028 #include "nel/ai/agent/agent_method_def.h"
00029 #include "nel/ai/script/interpret_object_message.h"
00030 #include "nel/ai/script/interpret_object_agent.h"
00031 #include "nel/ai/script/type_def.h"
00032 #include "nel/ai/agent/msg_notify.h"
00033 #include "nel/ai/agent/object_ident.h"
00034
00035 namespace NLAIAGENT
00036 {
00037
00038 IAgent::IAgent(const IAgent &a) : IAgentComposite(a)
00039 {
00040 _Iter_Child = _AgentList.begin();
00041 }
00042
00043 IAgent::IAgent(IBasicAgent *parent): IAgentComposite(parent)
00044 {
00045 _Iter_Child = _AgentList.begin();
00046 }
00047
00048 IAgent::IAgent(IBasicAgent *parent,IMailBox *m): IAgentComposite(parent,m)
00049 {
00050 _Iter_Child = _AgentList.begin();
00051 }
00052
00053
00054
00055
00056
00057 void IAgent::Kill()
00058 {
00059
00060
00061 #ifdef NL_DEBUG
00062 if(_SizeChild != (sint)_AgentList.size())
00063 {
00064 sint i = (sint)_AgentList.size();
00065 throw;
00066 }
00067
00068 nlinfo (" Kill 0x0%0x", this);
00069
00070 #endif
00071 sint n = _SizeChild ;
00072 while ( n--)
00073 {
00074 IConnectIA *c = _AgentList.front();
00075 _AgentList.pop_front();
00076 c->onKill(this);
00077 c->release();
00078 }
00079 _SizeChild = 0;
00080 IAgentComposite::Kill();
00081 }
00082
00083 void IAgent::onKill(IConnectIA *a)
00084 {
00085 if(eraseFromList<IBasicAgent *>(&_AgentList,(IBasicAgent *)a))
00086 {
00087 a->release();
00088 _SizeChild --;
00089 }
00090 removeConnection(a);
00091 IAgentComposite::onKill(a);
00092 }
00093
00094 const NLAIC::IBasicType *IAgent::clone() const
00095 {
00096 NLAIC::IBasicInterface *m = new IAgent(*this);
00097 return m;
00098 }
00099
00100 const NLAIC::IBasicType *IAgent::newInstance() const
00101 {
00102 NLAIC::IBasicInterface *m;
00103 if(getParent() != NULL) m = new IAgent((IBasicAgent *)getParent());
00104 else m = new IAgent(NULL);
00105 return m;
00106 }
00107
00108 void IAgent::getDebugString(std::string &t) const
00109 {
00110 t += NLAIC::stringGetBuild("class IAgent<%4x>",this);
00111 }
00112
00113 bool IAgent::isEqual(const IBasicObjectIA &a) const
00114 {
00115 return true;
00116 }
00117
00118
00119
00120
00121
00122 IAgent::~IAgent()
00123 {
00124 Kill();
00125 }
00126
00127 void IAgent::save(NLMISC::IStream &os)
00128 {
00129 IBasicAgent::save(os);
00130 IAgentComposite::save(os);
00131 }
00132
00133 void IAgent::load(NLMISC::IStream &is)
00134 {
00135 IBasicAgent::load(is);
00136 IAgentComposite::load(is);
00137 }
00138
00139 bool IAgent::runChildrenStepByStep()
00140 {
00141 if(_Iter_Child != _AgentList.end())
00142 {
00143 IBasicAgent *c = *_Iter_Child;
00144
00145 if(c->runStep().ResultState == ProcessNotComplit.ResultState) return false;
00146
00147 if(c->getState().ResultState == processToKill)
00148 {
00149 _Iter_Child ++;
00150 removeChild(c);
00151 }
00152 else _Iter_Child++;
00153
00154 return false;
00155
00156 }
00157
00158 _Iter_Child = _AgentList.begin();
00159 return true;
00160 }
00161
00162 void IAgent::runChildren()
00163 {
00164 std::list<IBasicAgent *>::iterator i_agl = _AgentList.begin();
00165 sint n = _SizeChild;
00166
00167 #ifdef NL_DEBUG
00168 if(n != (sint)_AgentList.size())
00169 throw;
00170 #endif
00171
00172 while ( n -- )
00173 {
00174 IBasicAgent *c = *i_agl;
00175
00176
00177 c->run();
00178 switch(c->getState().ResultState)
00179 {
00180 case processToKill:
00181 {
00182 i_agl ++;
00183 removeChild(c);
00184 }
00185 break;
00186 case processPresKill:
00187 {
00188 i_agl ++;
00189 c->incRef();
00190 removeChild(c);
00191 onKill(c);
00192 }
00193 break;
00194 default:
00195 i_agl ++;
00196 break;
00197
00198 };
00199 }
00200 }
00201
00202 void IAgent::processMessages()
00203 {
00204 IMailBox *mail = getMail();
00205
00206 sint n = mail->size();
00207
00208 while( n --)
00209 {
00210 const IMessageBase &msg = getMail()->getMessage();
00211 #ifdef NL_DEBUG
00212 const char *msgBase = (const char *)msg.getType();
00213 const char *classBase = (const char *)getType();
00214 #endif
00215 try
00216 {
00217 (void)IBasicAgent::run( msg );
00218 mail->popMessage();
00219 }
00220 catch(NLAIE::IException &)
00221 {
00222
00223 IMessageBase *o = (IMessageBase *)msg.clone();
00224 o->setMethodIndex(-1,-1);
00225 o->setSender(this);
00226 o->setPerformatif(IMessageBase::PError);
00227 o->setReceiver((IObjectIA *)msg.getSender());
00228 ((IObjectIA *)msg.getSender())->sendMessage(o);
00229
00230 mail->popMessage();
00231 }
00232 }
00233 }
00234
00235
00236
00237
00238 const IObjectIA::CProcessResult &IAgent::run()
00239 {
00240
00241
00242
00243
00244 runChildren();
00245 getMail()->run();
00246
00247 processMessages();
00248
00249 if(haveActivity() && getState().ResultState == processIdle) runActivity();
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 return getState();
00262 }
00263
00264 const IObjectIA::CProcessResult &IAgent::runStep()
00265 {
00266 if(runChildrenStepByStep())
00267 {
00268 getMail()->run();
00269
00270 processMessages();
00271
00272 if(haveActivity() && getState().ResultState == processIdle) runActivity();
00273 return getState();
00274 }
00275 else
00276 return IObjectIA::ProcessNotComplit;
00277 }
00278
00279 const NLAIC::CIdentType &IAgent::getType() const
00280 {
00281 return *IdAgent;
00282 }
00283
00284
00287
00288 IBasicAgent::IBasicAgent(const IBasicAgent &a): IConnectIA(a),_Mail((IMailBox *)a._Mail->clone())
00289 {
00290 _Mail->setParent((const IWordNumRef *) *this);
00291 }
00292
00293
00294 IBasicAgent::IBasicAgent(const IWordNumRef *parent): IConnectIA(parent)
00295 {
00296 _Mail = new tMailBoxLettre((const IWordNumRef *) *this);
00297
00298 }
00299
00300 IBasicAgent::IBasicAgent(const IWordNumRef *parent,IMailBox *m): IConnectIA(parent),_Mail(m)
00301 {
00302 _Mail->setParent((const IWordNumRef *) *this);
00303 }
00304
00305 IBasicAgent::~IBasicAgent()
00306 {
00307 _Mail->setParent(NULL);
00308 _Mail->release();
00309 }
00310
00311 const IObjectIA::CProcessResult &IBasicAgent::getState() const
00312 {
00313 return _RunState;
00314 }
00315
00316 void IBasicAgent::setState(TProcessStatement state, IObjectIA *result)
00317 {
00318 _RunState.ResultState = state;
00319 _RunState.Result = result;
00320 }
00321
00322 IObjectIA::CProcessResult IBasicAgent::sendMessage(IMessageBase *msg)
00323 {
00324 _Mail->addMessage(msg);
00325 return IObjectIA::ProcessRun;
00326 }
00327
00328 IObjectIA::CProcessResult IBasicAgent::sendMessage(IMessageBase *msg, IBasicAgent &receiver)
00329 {
00330 receiver.getMail()->addMessage( msg );
00331 return IObjectIA::ProcessRun;
00332 }
00333
00334 IMailBox *IBasicAgent::getMail() const
00335 {
00336 return _Mail;
00337 }
00338
00339 void IBasicAgent::save(NLMISC::IStream &os)
00340 {
00341 IConnectIA::save(os);
00342 _Mail->save(os);
00343 }
00344
00345 void IBasicAgent::load(NLMISC::IStream &is)
00346 {
00347 IConnectIA::load(is);
00348 _Mail->load(is);
00349 NLAIC::CIdentTypeAlloc id;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 void IBasicAgent::onKill(IConnectIA *a)
00363 {
00364 _Mail->onKill(a);
00365 }
00366
00367 IObjectIA *IBasicAgent::run(const IMessageBase &msg)
00368 {
00369 IMessageBase *returnMsg = NULL;
00370 switch(msg.getPerformatif())
00371 {
00372 case IMessageBase::PUndefine:
00373 {
00374 std::string text;
00375 text = NLAIC::stringGetBuild("Function IObjectIA *IBasicAgent::run('%s') proccess an IMessageBase::PUndefine performatif",(const char *)msg.getType());
00376 throw NLAIE::CExceptionNotImplemented(text.c_str());
00377 }
00378 break;
00379 case IMessageBase::PExec:
00380
00381 returnMsg = runExec(msg);
00382 if(msg.getContinuation() != NULL)
00383 {
00384 returnMsg->incRef();
00385 ((IObjectIA *)msg.getContinuation())->sendMessage(returnMsg);
00386 }
00387 break;
00388 case IMessageBase::PAchieve:
00389 returnMsg = runAchieve(msg);
00390 if(msg.getContinuation() != NULL)
00391 {
00392 returnMsg->incRef();
00393 ((IObjectIA *)msg.getContinuation())->sendMessage(returnMsg);
00394 }
00395 break;
00396 case IMessageBase::PAsk:
00397 returnMsg = runAsk(msg);
00398 returnMsg->setPerformatif(IMessageBase::PTell);
00399 returnMsg->incRef();
00400 ((IObjectIA *)msg.getSender())->sendMessage(returnMsg);
00401 if(msg.getContinuation() != NULL)
00402 {
00403 returnMsg->incRef();
00404 ((IObjectIA *)msg.getContinuation())->sendMessage(returnMsg);
00405 }
00406 break;
00407 case IMessageBase::PTell:
00408 returnMsg = runTell(msg);
00409
00410 break;
00411 case IMessageBase::PBreak:
00412 returnMsg = runBreak(msg);
00413 break;
00414 case IMessageBase::PKill:
00415 returnMsg = runKill(msg);
00416 break;
00417 case IMessageBase::PError:
00418 returnMsg = runError(msg);
00419 break;
00420
00421 case IMessageBase::PEven:
00422 returnMsg = runEven(msg);
00423 ((IMessageBase &)msg).setDispatch();
00424 break;
00425 default: break;
00426 }
00427
00428 if(returnMsg) returnMsg->release();
00429 return NULL;
00430 }
00431
00432
00433 const static sint32 _GetMailer = 0;
00434 const static sint32 _Father = 1;
00435 const static sint32 _RunTel = 2;
00436 const static sint32 _RunAsk = 3;
00437 const static sint32 _GetNumId = 4;
00438 const static sint32 _LastM = 5;
00439
00440 IBasicAgent::CMethodCall IBasicAgent::_Method[] =
00441 {
00442 IBasicAgent::CMethodCall(_MAILER_,_GetMailer),
00443 IBasicAgent::CMethodCall(_FATHER_,_Father),
00444 IBasicAgent::CMethodCall(_RUNTEL_,_RunTel),
00445 IBasicAgent::CMethodCall(_RUNASK_,_RunAsk),
00446 IBasicAgent::CMethodCall(_GETNUMID_,_GetNumId)
00447 };
00448
00449
00450 sint32 IBasicAgent::getMethodIndexSize() const
00451 {
00452 return IObjectIA::getMethodIndexSize() + _LastM;
00453 }
00454
00455 tQueue IBasicAgent::isMember(const IVarName *className,const IVarName *methodName,const IObjectIA &p) const
00456 {
00457 if(className == NULL)
00458 {
00459 tQueue a;
00460 for(int i = 0; i < _LastM; i++)
00461 {
00462 if(*methodName == IBasicAgent::_Method[i].MethodName)
00463 {
00464 CObjectType *c;
00465 if(i == _RunTel || i == _RunAsk)
00466 {
00467 static NLAISCRIPT::CParam paramMsg(1,new NLAISCRIPT::COperandSimple (new NLAIC::CIdentType(NLAISCRIPT::CMsgNotifyParentClass::IdMsgNotifyParentClass)));
00468
00469 if(paramMsg.eval((NLAISCRIPT::CParam &)p) < 0.0) continue;
00470 c = new CObjectType(new NLAIC::CIdentType(NLAISCRIPT::CMessageClass::IdMessageClass));
00471 }
00472 else
00473 if (i == _GetNumId)
00474 {
00475 c = new CObjectType(new NLAIC::CIdentType(CStringType::IdStringType));
00476 }
00477 else
00478 {
00479 c = new CObjectType(new NLAIC::CIdentType(CLocalAgentMail::LocalAgentMail));
00480 }
00481 a.push(CIdMethod(IBasicAgent::_Method[i].Index + IObjectIA::getMethodIndexSize(),0.0,NULL,c));
00482 break;
00483 }
00484 }
00485
00486 if(a.size()) return a;
00487 else return IConnectIA::isMember(className,methodName,p);
00488 }
00489 return IConnectIA::isMember(className,methodName,p);
00490 }
00491
00492 IObjectIA::CProcessResult IBasicAgent::runMethodeMember(sint32 h, sint32 index,IObjectIA *p)
00493 {
00494 return IConnectIA::runMethodeMember(h,index,p);
00495 }
00496
00497 IObjectIA::CProcessResult IBasicAgent::runMethodeMember(sint32 index,IObjectIA *p)
00498 {
00499 IBaseGroupType *param = (IBaseGroupType *)p;
00500
00501 switch(index - IObjectIA::getMethodIndexSize())
00502 {
00503 case _GetMailer:
00504 {
00505 IObjectIA::CProcessResult a;
00506 a.Result = new CLocalAgentMail(this);
00507 return a;
00508 }
00509 break;
00510
00511 case _Father:
00512 {
00513 IObjectIA::CProcessResult a;
00514 IRefrence *father = getParent();
00515 if ( father )
00516 a.Result = new CLocalAgentMail( (IBasicAgent *) father );
00517 else
00518 {
00519 a.Result = &DigitalType::NullOperator;
00520 a.Result->incRef();
00521 }
00522 return a;
00523 }
00524 break;
00525
00526 case _RunAsk:
00527 case _RunTel:
00528 {
00529 IObjectIA::CProcessResult a;
00530 a.Result = run((const IMessageBase &)*param->get());
00531 return a;
00532 }
00533 break;
00534
00535 case _GetNumId:
00536 {
00537 IObjectIA::CProcessResult a;
00538 std::string t;
00539 ((const IWordNumRef &)*this).getNumIdent().getDebugString(t);
00540 a.Result = new CStringType(CStringVarName(t.c_str()));
00541 return a;
00542 }
00543 break;
00544
00545 }
00546 return IConnectIA::runMethodeMember(index,p);
00547 }
00548
00549 IMessageBase *IBasicAgent::runAsk(const IMessageBase &m)
00550 {
00551 if(NLAISCRIPT::CMsgNotifyParentClass::IdMsgNotifyParentClass == m.getType())
00552 {
00553 if(getParent() != NULL)
00554 {
00555 CNotifyParentScript *msg = new CNotifyParentScript();
00556 return msg;
00557 }
00558 else
00559 {
00560 CNotifyParentScript *msg = new CNotifyParentScript((IBasicAgent *)getParent());
00561 return msg;
00562 }
00563 }
00564 else
00565 {
00566 std::string debugString;
00567 std::string text;
00568 getDebugString(debugString);
00569 text += NLAIC::stringGetBuild("runAsk(%s) note implementaited for the '%s' interface for the instence '%s'",(const char *)m.getType(),(const char *)getType(),debugString.c_str());
00570 throw NLAIE::CExceptionNotImplemented(text.c_str());
00571 return NULL;
00572 }
00573 }
00574
00575 IMessageBase *IBasicAgent::runTell(const IMessageBase &m)
00576 {
00577 if(NLAISCRIPT::CMsgNotifyParentClass::IdMsgNotifyParentClass == m.getType())
00578 {
00579
00580
00581
00582
00583
00584 return (IMessageBase *)m.clone();
00585 }
00586 else
00587 {
00588
00589
00590
00591
00592
00593 return NULL;
00594 }
00595 }
00596 }