# 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  

agents.cpp

Go to the documentation of this file.
00001 
00006 /* Copyright, 2000 Nevrax Ltd.
00007  *
00008  * This file is part of NEVRAX NEL.
00009  * NEVRAX NEL is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2, or (at your option)
00012  * any later version.
00013 
00014  * NEVRAX NEL is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00017  * General Public License for more details.
00018 
00019  * You should have received a copy of the GNU General Public License
00020  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00022  * MA 02111-1307, USA.
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 /*      const IObjectIA::CProcessResult &IAgent::run();
00054         IObjectIA *IAgent::run(const IMessageBase &);*/
00055                 
00056 
00057         void IAgent::Kill()
00058         {
00059 //sint n = _SizeChild;
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 ( /*_AgentList.begin() !=  _AgentList.end()*/ 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         /*const NLAIC::CIdentType &IAgent::getType() const;             
00119         void IAgent::save(NLMISC::IStream &os);
00120         void IAgent::load(NLMISC::IStream &is);*/
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()      // Se charge de l'activation des fils
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 ( /*i_agl != _AgentList.end()*/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                 //const IMailBox::tListMessage &l = mail->getMesseageListe();
00206                 sint n = mail->size();
00207 
00208                 while(/*l.begin() != l.end()*/ 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                                 // We send an Error message because the incoming message isn't processed.
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         /*std::string Shift="-";
00236         sint kShift = 1;*/
00237 
00238         const IObjectIA::CProcessResult &IAgent::run()
00239         {       
00240                 /*nlinfo("%s<%4x> go to run %s with %d childs:",Shift.c_str(),this, (const char *)getType(),_AgentList.size());
00241                 Shift += "\t";
00242                 kShift++;*/
00243 
00244                 runChildren();          // Gestion des fils
00245                 getMail()->run();       // Execution de la boite aux lettres
00246 
00247                 processMessages();      // Traitement de ses propres messages
00248 
00249                 if(haveActivity() && getState().ResultState == processIdle) runActivity();
00250 
00251                 /*kShift --;
00252                 std::string chaine;
00253                 sint i;
00254                 for(i = 0; i < (sint)kShift; i ++)
00255                 {
00256                         chaine += Shift [i];                            
00257                 }
00258                 Shift = chaine;*/
00259 
00260 
00261                 return getState();  
00262         }
00263 
00264         const IObjectIA::CProcessResult &IAgent::runStep()
00265         {
00266                 if(runChildrenStepByStep())
00267                 {
00268                         getMail()->run();       // Execution de la boite aux lettres
00269 
00270                         processMessages();      // Traitement de ses propres messages
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         /*void IBasicAgent::addMsgGroup(IBasicMessageGroup &grp)
00353         {
00354                 getMail()->addGroup( grp );
00355         }
00356 
00357         void IBasicAgent::removeMsgGroup(IBasicMessageGroup &grp)
00358         {
00359                 getMail()->removeGroup( grp );
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                         /*const INombreDefine *n = (const INombreDefine *)m.getFront();
00580                         if(n->getNumber() != 0.0)
00581                         {
00582                                 const CLocalAgentMail *parent = (const CLocalAgentMail *)m.get();
00583                         }*/
00584                         return (IMessageBase *)m.clone();                       
00585                 }
00586                 else
00587                 {
00588 /*                      std::string debugString;
00589                         std::string text;
00590                         getDebugString(debugString);
00591                         text += NLAIC::stringGetBuild("runTell(%s) note implementaited for the '%s' interface for the instence '%s'",(const char *)m.getType(),(const char *)getType(),debugString.c_str());
00592                         throw NLAIE::CExceptionNotImplemented(text.c_str()); */
00593                         return NULL;
00594                 }
00595         }       
00596 }