# 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  

interpret_object_agent.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/script/interpret_object_agent.h"
00025 #include "nel/ai/c/registry_class.h"
00026 #include "nel/ai/agent/agent_script.h"
00027 #include "nel/ai/script/type_def.h"
00028 #include "nel/ai/script/object_unknown.h"
00029 #include "nel/ai/script/lexsupport.h"
00030 #include "nel/ai/script/libcode.h"
00031 
00032 namespace NLAISCRIPT
00033 {       
00034         const NLAIAGENT::IObjectIA::CProcessResult &CAgentClass::run()
00035         {
00036                 return NLAIAGENT::IObjectIA::ProcessRun;
00037         }
00038 
00039         CAgentClass::CAgentClass(const NLAIAGENT::IVarName &name) : _Components(0),_Inheritance(NULL)
00040         {
00041                 setType(name, *this);   
00042                 _lastRef = -1;
00043                 _RunIndex = -1;
00044                 _ConstructorIndex = -1;
00045                 setBaseMethodCount(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass()))->getBaseMethodCount());
00046                 setBaseObjectInstance(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass())));
00047                 _Base_class = NULL;
00048                 _ConstructorIndex = -1;
00049         }
00050 
00051         CAgentClass::CAgentClass(const NLAIAGENT::IVarName &name, const NLAIAGENT::IVarName &base_class_name) :
00052                 _Components(0),
00053                 _Inheritance( (NLAIAGENT::IVarName *)base_class_name.clone() )
00054         {
00055                 setType(name, *this);
00056                 _lastRef = -1;
00057                 _RunIndex = -1;
00058                 _ConstructorIndex = -1;
00059                 setBaseMethodCount(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass()))->getBaseMethodCount());
00060                 setBaseObjectInstance(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass())));
00061                 _Base_class = NULL;
00062                 _ConstructorIndex = -1;
00063         }
00064         
00065         CAgentClass::CAgentClass( const CAgentClass &a):
00066                                                 _Components(a._Components),_Inheritance(a._Inheritance == NULL ? NULL : (NLAIAGENT::IVarName *)a._Inheritance->clone())
00067         {               
00068                 setType(new NLAIC::CIdentType(a.getType()));
00069                 _lastRef = -1;
00070                 _RunIndex = -1;
00071                 _ConstructorIndex = -1;
00072                 setBaseMethodCount(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass()))->getBaseMethodCount());
00073                 setBaseObjectInstance(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass())));
00074                 _Base_class = a._Base_class;
00075                 _ConstructorIndex = a._ConstructorIndex;
00076         }
00077         
00078         CAgentClass::CAgentClass(const NLAIC::CIdentType &ident):_Components(0),_Inheritance(NULL)
00079         {
00080                 setType(new NLAIC::CIdentType(ident));
00081                 _lastRef = -1;
00082                 _RunIndex = -1;
00083                 _ConstructorIndex = -1;
00084 
00085                 setBaseMethodCount(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass()))->getBaseMethodCount());
00086                 setBaseObjectInstance(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass())));
00087                 _Base_class = NULL;
00088                 _ConstructorIndex = -1;
00089         }
00090 
00091         CAgentClass::CAgentClass():_Components(0),_Inheritance(NULL)
00092         {               
00093                 _lastRef = -1;
00094                 _RunIndex = -1;
00095                 _ConstructorIndex = -1;
00096 
00097                 _Methode.size();                
00098 
00099                 setBaseMethodCount(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass()))->getBaseMethodCount());
00100                 setBaseObjectInstance(((NLAIAGENT::CAgentScript *)(NLAIAGENT::CAgentScript::IdAgentScript.getFactory()->getClass())));
00101                 _Base_class = NULL;
00102                 _ConstructorIndex = -1;
00103         }
00104 
00105         CAgentClass::~CAgentClass()
00106         {
00107                 sint32 i;
00108                 for(i =  0; i < (sint32)_Components.size(); i++)
00109                 {
00110                         CComponent *c = _Components[i];
00111                         if(c->ObjectName) c->ObjectName->release();
00112                         if(c->RegisterName) c->RegisterName->release();
00113                         delete c;
00114                 }
00115 
00116                 for(i = 0; i < (sint32) _StaticComponents.size(); i++ )
00117                         _StaticComponents[i]->release();
00118 
00119                 clearIndirectMsgTable();
00120 
00121                 if(_Inheritance != NULL) 
00122                         _Inheritance->release();
00123 
00124         }
00125 
00126         void CAgentClass::clearIndirectMsgTable()
00127         {
00128                 for (int i = 0; i < (int) _MsgIndirectTable.size(); i++ )
00129                         if ( _MsgIndirectTable[i] != NULL )
00130                                 delete[] _MsgIndirectTable[i];
00131                 _MsgIndirectTable.clear();
00132         }
00133         
00134         bool CAgentClass::isMessageFunc(const CParam &param) const 
00135         {
00136                 if ( param.size() == 1 )
00137                 {
00138                         IOpType &msg_arg = *((IOpType *)param[0]);
00139                         const NLAIC::CIdentType &msg_type = *msg_arg.getConstraintTypeOf();
00140                         CAgentClass *child_class = (CAgentClass *) msg_type.getFactory()->getClass();
00141         
00142                         if ( child_class->isClassInheritedFrom( NLAIAGENT::CStringVarName("Message") ) != -1 )
00143                                 return true;
00144                 }
00145                 return false;
00146         }
00147 
00150         void CAgentClass::buildChildsMessageMap()
00151         {
00152                 
00153                 sint32 i,j;
00154                 sint32 child_index;
00155                 sint32 nb_scripted_components = 0;
00156 
00157 #ifdef NL_DEBUG
00158                 const char *dbg_this_class_name = getClassName()->getString();
00159 #endif
00160                 clearIndirectMsgTable();
00161 
00163                 std::vector<CComponent *> components;
00164                 if ( _VTable.size() )
00165                 {
00166                         for ( i = 0; i < (int) _VTable.size(); i++ )
00167                         {
00168                                 for ( j = 0; j < (int) _VTable[i]->_Components.size(); j++ )
00169                                 {
00170                                         components.push_back( _VTable[i]->_Components[j] );
00171                                 }
00172                         }
00173                 }
00174 
00175 
00177                 for (i =0; i < (int) components.size() ; i++ ) // ... for each of its components ...
00178                 {
00179                         NLAIC::CIdentType c_type( components[ i ]->RegisterName->getString() );
00180                         if( ((const NLAIC::CTypeOfObject &) c_type) & NLAIC::CTypeOfObject::tInterpret ) // ...if it's a scripted agent...
00181                                 nb_scripted_components ++;
00182                 }
00183 
00184                 // For each message processing function of the father, 
00185                 // allocates the table with by default -1, which means the child doesn't process the
00186                 // message.
00187                 for ( i = 0; i < (int) _Methode.size(); i++ )
00188                 {
00189                         CMethodeName &method = getBrancheCode( (int) i );
00190                         if ( isMessageFunc( method.getParam() ) )
00191                         {
00192                                 _MsgIndirectTable.push_back( new sint32[nb_scripted_components ] );
00193                                 for ( child_index = 0; child_index < nb_scripted_components; child_index++ )
00194                                         _MsgIndirectTable[i][child_index] = -1;
00195                         }
00196                         else
00197                                 _MsgIndirectTable.push_back( NULL );
00198                 }
00199                 
00200                 sint32 index_component = 0;
00201                         
00202                 for (i =0; i < (int) components.size() ; i++ ) // ... for each of its components ...
00203                 {
00204                         NLAIC::CIdentType c_type( components[ i ]->RegisterName->getString() );
00205 #ifdef NL_DEBUG
00206                         const char *dbg_class_name = components[ i ]->RegisterName->getString();
00207 #endif
00208                         if( ((const NLAIC::CTypeOfObject &) c_type) & NLAIC::CTypeOfObject::tInterpret ) // ...if it's a scripted agent...
00209                         {
00210                                 CAgentClass *child_class = (CAgentClass *) c_type.getFactory()->getClass();
00211 #ifdef NL_DEBUG
00212                                 sint32 dbg_nb_funcs = child_class->getBrancheCodeSize();
00213 #endif
00214                                 for (child_index =0; child_index < child_class->getBrancheCodeSize(); child_index++ ) // ... for each of its methods...
00215                                 {
00216                                         CMethodeName &method = child_class->getBrancheCode( (int) child_index );
00217 #ifdef NL_DEBUG
00218                                         const char *dbg_meth_name = method.getName().getString();
00219 #endif
00220                                         if ( isMessageFunc( method.getParam() ) )       // ... if it's a message processing function...
00221                                         {
00222                                                 // Looks if the father has a procecessing function for this message
00223                                                 sint32 father_index = findMethod( method.getName(), method.getParam() );
00224                                                 if ( father_index != -1 )
00225                                                 {
00226                                                         // The father processes this message. Puts the index for the child in the table.
00227                                                         _MsgIndirectTable[ father_index ][ index_component ] = child_index;
00228                                                 }
00229                                                 else
00230                                                 {
00231                                                         // Ajoute la méthode chez le père
00232                                                         father_index = addBrancheCode( method.getName(), method.getParam() );
00233                                                         _Methode[ father_index ].Method->setCode((IOpCode *)NULL);
00234                                                         _Methode[ father_index ].Method->setTypeOfMethode( new NLAISCRIPT::COperandVoid() );
00235 
00236                                                 
00237                                                         // Créée le tableau
00238                                                         if ( father_index >= (int) _MsgIndirectTable.size() )
00239                                                         {
00240                                                                 _MsgIndirectTable.push_back( new sint32[ nb_scripted_components ] );
00241                                                                 sint32 x;
00242                                                                 for ( x =0; x < nb_scripted_components; x++) 
00243                                                                         _MsgIndirectTable[ father_index ][x] = -1;
00244                                                         }
00245                                                         _MsgIndirectTable[ father_index ] [ index_component ] = child_index;
00246                                                 }
00247                                         }
00248                                 }
00249                                 index_component++;
00250                         }
00251                 }
00252         }
00253 
00254         sint32 CAgentClass::getChildMessageIndex(const NLAIAGENT::IMessageBase *msg, sint32 child_index )
00255         {
00256                 return _MsgIndirectTable[ msg->getMethodIndex() - getBaseMethodCount() ][child_index];
00257         }
00258 
00259         void CAgentClass::classIsMounted()
00260         {
00261         }
00262         
00264         sint32 CAgentClass::registerComponent(const NLAIAGENT::IVarName &type_name)
00265         {                       
00266 /*#ifdef NL_DEBUG
00267                 std::string dbugS;
00268                 type_name.getDebugString(dbugS);
00269                 NLAIC::Out("registerComponent<%s>\n", dbugS.c_str());
00270 #endif*/
00271                 CComponent *c = new CComponent();
00272                 c->RegisterName = (NLAIAGENT::IVarName *)type_name.clone();
00273                 c->ObjectName = NULL;
00274                 _Components.push_back(c);
00275                 
00276                 return _Components.size() - 1;
00277         }
00278          
00280         sint32 CAgentClass::registerComponent(const NLAIAGENT::IVarName &type_name, const NLAIAGENT::CStringVarName &field_name)
00281         {                       
00282                 CComponent *c = new CComponent();
00283                 c->RegisterName = (NLAIAGENT::IVarName *)type_name.clone();
00284                 c->ObjectName = (NLAIAGENT::IVarName *)field_name.clone();
00285                 _Components.push_back(c);
00286                 return _Components.size() - 1;
00287         }
00288         
00289 
00290         sint32 CAgentClass::getComponentIndex(const NLAIAGENT::IVarName &name) const
00291         {
00292                 for(sint32 i = _Components.size() - 1; i >= 0; i --)
00293                 {
00294 
00295 #ifdef NL_DEBUG
00296                         std::string buffer;
00297                         name.getDebugString( buffer );
00298                         std::string buffer2;
00299                         _Components[i]->ObjectName->getDebugString( buffer2 );
00300 #endif
00301                         if (_Components[i]->ObjectName !=NULL && (*_Components[i]->ObjectName) == name) 
00302                                 return i;
00303                 }
00304                 return -1;
00305         }
00306 
00307         CComponent *CAgentClass::getComponent(const NLAIAGENT::IVarName &name) const
00308         {
00309                 for(sint32 i = _Components.size() - 1; i >= 0; i --)
00310                 {
00311                         if (_Components[i]->ObjectName !=NULL && *_Components[i]->ObjectName == name) 
00312                                 return _Components[i];
00313                 }
00314                 return NULL;
00315         }
00316 
00317 
00318         sint32 CAgentClass::getStaticMemberIndex(const NLAIAGENT::IVarName &name) const
00319         {
00320                 sint32 n = 0;
00321                 const IClassInterpret *classType = getBaseClass();
00322                 while(classType != NULL)
00323                 {
00324                         n += classType->getStaticMemberSize();
00325                         classType = classType->getBaseClass();
00326                 }
00327                 classType = this;
00328                 while(classType != NULL)
00329                 {               
00330                         for(sint32 i = classType->getStaticMemberSize() - 1; i >= 0; i --)
00331                         {
00332                                 if (classType->getComponent(i)->ObjectName != NULL && *classType->getComponent(i)->ObjectName == name) 
00333                                 {                                                                               
00334                                         return i + n;
00335                                 }
00336                         }                       
00337                         classType = classType->getBaseClass();
00338                         if(classType != NULL) n -= classType->getStaticMemberSize();
00339                 }
00340                 
00341                 return -1;
00342         }
00343 
00344         sint32 CAgentClass::getInheritedStaticMemberIndex(const NLAIAGENT::IVarName &name) const
00345         {
00346 
00347 #ifdef NL_DEBUG
00348                 const char *dbg_this_type = (const char *) getType();
00349                 std::string buffer;
00350                 name.getDebugString(buffer);
00351 #endif
00352 
00353 
00354                 sint32 nb_components = 0;
00355                 std::vector<const CAgentClass *>::const_iterator it_bc = _VTable.begin();
00356                 sint32 index;
00357                 while ( it_bc != _VTable.end() && (  ( index = (*it_bc)->getComponentIndex( name ) ) == -1 ) )
00358                 {
00359                         nb_components += (*it_bc)->getStaticMemberSize();
00360                         it_bc++;
00361                 }
00362 
00363                 if ( it_bc != _VTable.end() && index != -1)
00364                         return nb_components + index;
00365                 else
00366                         return -1;
00367         }
00368 
00369         const NLAIAGENT::IObjectIA *CAgentClass::getStaticMember(sint32 index) const
00370         {       
00371                 try
00372                 {
00373                         /*NLAIC::CIdentType id(_Components[i]->RegisterName->getString());
00374                         const NLAIAGENT::IObjectIA *o = (const NLAIAGENT::IObjectIA *)id.getFactory()->getClass();
00375                         return o;*/
00376                         sint32 n = 0;
00377                         const IClassInterpret *classType = getBaseClass();
00378                         while(classType != NULL)
00379                         {
00380                                 n += classType->getStaticMemberSize();
00381                                 classType = classType->getBaseClass();
00382                         }
00383                         classType = this;
00384                         while(classType != NULL)
00385                         {               
00386                                 for(sint32 i = classType->getStaticMemberSize() - 1; i >= 0; i --)
00387                                 {
00388                                         if(index == i + n)
00389                                         {
00390                                                 NLAIC::CIdentType id(classType->getComponent(i)->RegisterName->getString());
00391                                                 const NLAIAGENT::IObjectIA *o = (const NLAIAGENT::IObjectIA *)id.getFactory()->getClass();
00392                                                 return o;
00393                                         }
00394                                         /*if (classType->getComponent(i)->ObjectName != NULL && *classType->getComponent(i)->ObjectName == name) 
00395                                         {                                                                               
00396                                                 return i + n;
00397                                         }*/
00398                                 }                       
00399                                 classType = classType->getBaseClass();
00400                                 if(classType != NULL) n -= classType->getStaticMemberSize();
00401                         }
00402                 }                               
00403                 catch(NLAIE::IException &)
00404                 {
00405                         //throw NLAIE::CExceptionContainer(e.what());
00406                 }
00407                                 
00408                 return NULL;
00409         }
00410 
00411         sint32 CAgentClass::getStaticMemberSize() const
00412         {               
00413                 return _Components.size();
00414         }
00415 
00416         CComponent *CAgentClass::getComponent(sint32 i) const
00417         {
00418                 if ( i < (sint32) _Components.size() ) 
00419                         return _Components[ i ];
00420                 else 
00421                         return NULL;
00422         }
00423 
00424         CMethodeName &CAgentClass::getBrancheCode(sint32 i) const
00425         {
00426 #ifdef NL_DEBUG
00427                 sint kkk = _Methode.size();
00428 #endif
00429                 CMethodeName *a = _Methode[i].Method;
00430                 return  *a;
00431         }
00432 
00433         sint32 CAgentClass::getBrancheCodeSize() const
00434         {
00435                 return _Methode.size();
00436         }
00437 
00438         CMethodeName &CAgentClass::getBrancheCode(sint32 no_base_class, sint32 no_methode) const
00439         {
00440 #ifdef NL_DEBUG
00441                 const NLAIAGENT::IObjectIA *o = _VTable[ no_base_class ];
00442 #endif
00443                 
00444                 return _VTable[ no_base_class ]->getBrancheCode( no_methode );
00445         }
00446 
00447         CMethodeName &CAgentClass::getBrancheCode() const
00448         {
00449                 if(_lastRef < 0) throw NLAIE::CExceptionUnReference("you try to access to an unrefrence index");
00450                 return *_Methode[_lastRef].Method;
00451         }
00452         
00453         sint32 CAgentClass::getMethodIndexSize() const
00454         {
00455                 return (sint32)_Methode.size() + getBaseMethodCount();
00456         }
00457 
00458         sint32 CAgentClass::addBrancheCode(const NLAIAGENT::IVarName &name,const CParam &param)
00459         {       
00460 #ifdef NL_DEBUG
00461         std::string txtClass;
00462         std::string txt;
00463         param.getDebugString(txtClass);
00464         txt = name.getString() + txtClass;
00465         txtClass = getClassName()->getString();
00466 #endif
00467                 sint32 i = findMethod(name,param);              
00468                 if(i >= 0) 
00469                 {                       
00470                         CMethodeName *oldM = _Methode[ i ].Method;
00471                         if(_Methode[ i ].isBasedOnBaseClass())
00472                         {
00473                                 CMethodeName *m = new CMethodeName(name);
00474                                 _Methode[ i ].setMethodBasedOnBaseClassState(false);
00475                                 oldM->release();
00476                                 _Methode[i] = m;
00477                                 m->setParam( param ) ;
00478                                 _lastRef = i;
00479                         }
00480                         else
00481                         {                               
00482 
00483                                 std::string txtP;
00484                                 std::string txt;
00485                                 param.getDebugString(txtP);
00486                                 txt = NLAIC::stringGetBuild("%s%s is all ready defined in '%s'",name.getString(),txtP.c_str(),getClassName()->getString());                             
00487                                 throw NLAIE::CExceptionAllReadyExist((char *)txt.c_str());
00488                         }
00489                 }
00490                 else
00491                 {
00492                         CMethodeName *m = new CMethodeName(name);
00493                         _Methode.push_back( CMethodType( m ));
00494                         m->setParam( param );
00495                         _lastRef = _Methode.size() - 1;
00496                         _Methode.back().setMethodBasedOnBaseClassState(false);
00497                 }
00498 
00499                 static NLAIAGENT::CStringVarName constructor_name("Constructor");
00500                 if ( name == constructor_name )
00501                         _ConstructorIndex = _lastRef;
00502 
00503                 return _lastRef;
00504         }
00505 
00506         NLAIAGENT::tQueue CAgentClass::getPrivateMember(const NLAIAGENT::IVarName *className,const NLAIAGENT::IVarName *methodName,const NLAIAGENT::IObjectIA &param) const
00507         {
00508                 NLAIAGENT::tQueue q;
00509                 const IClassInterpret *classType = this;
00510                 NLAIAGENT::CIdMethod k;
00511 
00512                 for(sint32 i = 0; i < getMethodIndexSize() - getBaseMethodCount(); i ++)
00513                 {
00514                         CMethodeName &m = classType->getBrancheCode(i);
00515 #ifdef NL_DEBUG
00516                         const char *dbg_this_name = m.getName().getString();
00517                         const char *dbg_func_name = methodName->getString();
00518 #endif
00519                         if(m.getName() == *methodName )
00520                         {
00521                                 k.Weight = m.getParam().eval((const CParam &)param);
00522                                 if(k.Weight < 0.0) continue;
00523                                 k.Index = i + getBaseMethodCount();
00524                                 k.Method = &m;                                  
00525                                 IOpType *t = (IOpType *)m.getTypeOfMethode();
00526                                 t->incRef();
00527 
00528                                 if(k.ReturnType != NULL)
00529                                 {
00530                                         k.ReturnType->release();
00531                                 }
00532 
00533                                 k.ReturnType = new CObjectUnknown(t);                                   
00534                                 q.push(k);                                      
00535                         }
00536                 }
00537                 return q;
00538         }
00539 
00540         NLAIAGENT::tQueue CAgentClass::isMember(const NLAIAGENT::IVarName *className,const NLAIAGENT::IVarName *methodName,const NLAIAGENT::IObjectIA &param) const
00541         {
00542 
00543 #ifdef NL_DEBUG
00544                 if ( className != NULL )
00545                         const char *dbg_class_name = className->getString();
00546                 const char *dbg_method_name = methodName->getString();
00547 #endif
00548 
00549                 NLAIAGENT::tQueue q;
00550                 const IClassInterpret *classType = this;
00551                 NLAIAGENT::CIdMethod k;
00552 
00553                 if( className != NULL )
00554                 {
00555                         classType = NULL;
00556                         for(sint32 i = 1; i < (sint32)_VTable.size(); i ++)
00557                         {
00558                                 if(*_VTable[i]->getClassName() == *className)
00559                                 {
00560                                         classType = _VTable[i];
00561                                 }
00562                         }
00563                 }
00564 
00565                 if( classType != NULL )
00566                 {               
00567                         q= getPrivateMember(className,methodName,param);                        
00568                 }
00569 
00570                 if( !q.size() )
00571                 {
00572                         return getBaseObjectInstance()->isMember(className,methodName,param);
00573                 }
00574                 return q;
00575         }
00576 
00577         sint32 CAgentClass::findMethod(const NLAIAGENT::IVarName &name,const CParam &param) const
00578         {                                               
00579                 for(sint32 i = 0 ; i < (sint32)_Methode.size(); i ++)
00580                 {                       
00581 #ifdef NL_DEBUG
00582                         const char *dbg_method_name = _Methode[i].Method->getName().getString();        
00583 #endif²
00584                         CMethodeName *m = _Methode[i].Method;
00585                         const CParam &p = (const CParam &)m->getParam();
00586                         if( m->getName() == name && p == param ) 
00587                                 return i;
00588                 }
00589                 return -1;
00590         }
00591 
00592         void CAgentClass::createBaseClassComponents( std::list<NLAIAGENT::IObjectIA *> &comps) const
00593         {
00594 #ifdef NL_DEBUG
00595                 const char *txt = NULL;
00596                 if(getName() != NULL) txt = getName()->getString();             
00597 #endif                          
00598                 if ( _Inheritance )
00599                 {
00600                         const CAgentClass *base_class = (const CAgentClass *) getBaseClass();
00601                         base_class->createBaseClassComponents( comps );
00602                 }               
00603                 createComponents( comps );
00604 #ifdef NL_DEBUG
00605                 sint32 i = (sint32)comps.size();
00606 #endif          
00607         }
00608 
00609         void CAgentClass::createComponents( std::list<NLAIAGENT::IObjectIA *> &comps) const
00610         {
00611                 NLAIAGENT::IObjectIA *obj;
00612                 for (sint32 i = 0; i < (sint32) _Components.size(); i++)
00613                 {
00614                         CComponent *comp = _Components[i];
00615                         if ( !comp->Static )
00616                         {
00617                                 //sint32 class_index = NLAIC::getRegistry()->getNumIdent( comp->RegisterName->getString() );
00618                                 NLAIC::CIdentType id(comp->RegisterName->getString());
00619                                 sint class_index = id.getIndex();
00620                                 obj = (NLAIAGENT::IObjectIA *) NLAIC::getRegistry()->createInstance( class_index );
00621                         }
00622                         else
00623                         {
00624 #ifdef NL_DEBUG
00625                                 std::string comp_name;
00626                                 comp->RegisterName->getDebugString( comp_name );
00627 
00628                                 std::string comp_type;
00629                                 comp->ObjectName->getDebugString( comp_type );
00630 
00631                                 std::string buf;
00632                                 comp->StaticValue->getDebugString(buf);
00633 #endif
00634                                 obj = comp->StaticValue;
00635                                 comp->StaticValue->incRef();
00636                         }
00637                         comps.push_back( obj );
00638                 }
00639         }
00640 
00641         void CAgentClass::buildVTable()
00642         {               
00643                 _VTable.clear();
00644                 getClassPath(_VTable);
00645                                         
00646                 buildVMethode();
00647         }
00648 
00649         void CAgentClass::buildVMethode()
00650         {
00651 #ifdef NL_DEBUG
00652         char txtClass[2048*8];
00653         strcpy(txtClass,getClassName()->getString());
00654 #endif                                  
00655                 if(sizeVTable() > 1 )
00656                 {       
00657                         const IClassInterpret *t= _VTable[sizeVTable() - 2];
00658                         
00659                         if(t->getMethodIndexSize() > getBaseMethodCount()) 
00660                         {
00661                                 _Methode.resize(t->getMethodIndexSize() - getBaseMethodCount());                        
00662                         
00663                                 int mmax = t->getMethodIndexSize() - getBaseMethodCount();
00664                                 for(sint32 i = 0; i < mmax; i ++)
00665                                 {
00666                                         CMethodeName *m = &t->getBrancheCode(i);
00667 #ifdef NL_DEBUG
00668         std::string txt;
00669         m->getDebugString(txt); 
00670 #endif
00671                                         m->incRef();
00672                                         _Methode[i] = m;
00673                                 }
00674                         }
00675                 }               
00676         }
00677 
00678         sint32 CAgentClass::isClassInheritedFrom(const NLAIAGENT::IVarName &className) const
00679         {               
00680                 for(sint32 i = 0; i < (sint32)_VTable.size(); i ++)
00681                 {
00682 #ifdef NL_DEBUG
00683                 const NLAIAGENT::IObjectIA *o = _VTable[i];
00684 #endif
00685                         const NLAIAGENT::IVarName *thisName = _VTable[i]->getClassName();                       
00686                         if(thisName == NULL) 
00687                         {
00688                                 //thisName = 
00689                                 const NLAIC::CIdentType *id = &_VTable[i]->getType();
00690                                 if(id == NULL)
00691                                 {
00692                                         if(getClassName() != NULL)
00693                                         {
00694                                                 if(*getClassName() == className) return i;
00695                                                 else return -1;
00696                                         }
00697                                         else return -1;
00698                                 }
00699                                 else
00700                                 if(strcmp((const char *)*id , className.getString()) == 0)
00701                                 {
00702                                         return i;
00703                                 }
00704                         }
00705                         else
00706                         {
00707                                 if(*(_VTable[i]->getClassName()) == className)
00708                                 {
00709                                         return i;
00710                                 }
00711                         }
00712                 }               
00713                 return -1;
00714         }
00715 
00716         const IClassInterpret *CAgentClass::getInheritance(sint32 n) const
00717         {
00718                 return _VTable[n];
00719         }
00720 
00721         sint32 CAgentClass::sizeVTable() const
00722         {
00723                 return _VTable.size();
00724         }
00725 
00726         NLAIAGENT::IObjectIA *CAgentClass::buildNewInstance() const
00727         {
00728                 // Création des composants statiques
00729                 std::list<NLAIAGENT::IObjectIA *> components;
00730 
00731                 // Composants des classes de base
00732                 createBaseClassComponents( components );
00733 
00734                 // Création de l'agent
00735                 NLAIAGENT::CAgentScript *instance = new NLAIAGENT::CAgentScript(NULL, NULL, components,  (CAgentClass *) this );
00736 
00737 
00738                 // TODO: add constructor call here!!!!!
00739 
00740                 return instance;
00741         }
00742         
00743         const NLAIC::IBasicType *CAgentClass::clone() const
00744         {
00745                 NLAIC::IBasicType *x = new CAgentClass(*this);
00746                 return x;
00747         }
00748 
00749         const NLAIC::IBasicType *CAgentClass::newInstance() const
00750         {
00751                 NLAIC::IBasicType *x = new CAgentClass();
00752                 return x;
00753         }
00754 
00755         void CAgentClass::getDebugString(std::string &t) const
00756         {
00757                 t += NLAIC::stringGetBuild("<CAgentClass> %s\n", getClassName()->getString() );
00758         }
00759 
00760         void CAgentClass::save(NLMISC::IStream &os)
00761         {
00762                 // Saves static components
00763                 sint32 size = _Components.size();
00764                 os.serial( size );
00765                 sint32 i;
00766                 for ( i = 0; i < (sint32) _Components.size() ; i++ )
00767                 {
00768                         _Components[i]->save( os );
00769                 }
00770                 
00771                 // Saves class methods
00772                 size = _Methode.size();
00773                 os.serial( size );
00774                 for ( i = 0; i < (sint32) _Methode.size(); i++)
00775                 {
00776                         os.serial( (NLAIC::CIdentType &)_Methode[i].Method->getType() );
00777                         _Methode[i].Method->save( os );
00778                 }
00779                 os.serial( (NLAIC::CIdentType &) _Inheritance->getType() );
00780                 _Inheritance->save( os );
00781         }
00782 
00783         void CAgentClass::load(NLMISC::IStream &is)
00784         {
00785                 // Saves static components
00786                 sint32 _NbComponents;
00787                 is.serial( _NbComponents );
00788                 sint32 i;
00789                 for ( i = 0; i < (sint32) _NbComponents ; i++ )
00790                 {
00791                         NLAIC::CIdentTypeAlloc id;
00792                         is.serial( id );
00793                         CComponent *comp = (CComponent *)id.allocClass();
00794                         comp->load(is);
00795                         _Components.push_back( comp );
00796                 }
00797 
00798                 for ( i = 0; i < (sint32) _Methode.size(); i++)
00799                 {
00800                         _Methode[i].Method->release();
00801                 }
00802                 _Methode.clear();
00803 
00804                 // Loads class methods
00805                 sint32 nb_methods;
00806                 is.serial( nb_methods );
00807                 for ( i = 0; i < (sint32) nb_methods; i++)
00808                 {
00809                         NLAIC::CIdentTypeAlloc id;
00810                         is.serial( id );
00811                         CMethodeName *methode = (CMethodeName *)id.allocClass();
00812                         methode->load(is);
00813                         methode->incRef();
00814                         _Methode.push_back( CMethodType(methode));
00815                 }
00816 
00817                 NLAIC::CIdentTypeAlloc id;
00818                 is.serial( id );
00819                 _Inheritance = (NLAIAGENT::IVarName *) id.allocClass();
00820                 _Inheritance->load( is );
00821                 _Inheritance->incRef();
00822         }
00823         
00824         
00825         bool CAgentClass::isEqual(const NLAIAGENT::IBasicObjectIA &a) const
00826         {
00827                 const CAgentClass &i = (const CAgentClass &)a;                  
00828                 return getClassName() == i.getClassName();
00829         }
00830 
00831         const NLAIAGENT::IVarName *CAgentClass::getInheritanceName() const
00832         {
00833                 return _Inheritance;
00834         }
00835         
00836         void CAgentClass::setInheritanceName(const NLAIAGENT::IVarName &name)
00837         {
00838                 if(_Inheritance != NULL)
00839                 {
00840                         _Inheritance->release();                                
00841                 }
00842                 _Inheritance = (NLAIAGENT::IVarName *)name.clone();
00843                 
00844         }
00845 
00846         const IClassInterpret *CAgentClass::getComputeBaseClass()
00847         {
00848                 if ( _Inheritance )
00849                 {
00850                         if(_Base_class == NULL)
00851                         {
00852                                 _Base_class = (IClassInterpret *)( (CClassInterpretFactory *) NLAIC::getRegistry()->getFactory( _Inheritance->getString() ) )->getClass();                              
00853                                 return _Base_class;
00854                         }
00855                         else
00856                         {
00857                                 return _Base_class;
00858                         }
00859                 }
00860                 else
00861                 {                       
00862                         return NULL;
00863                 }
00864         }
00865 
00866         const IClassInterpret *CAgentClass::getBaseClass() const
00867         {
00868                 if ( _Inheritance )
00869                 {
00870                         if(_Base_class == NULL)
00871                         {
00872                                 return (const IClassInterpret *)( (CClassInterpretFactory *) NLAIC::getRegistry()->getFactory( _Inheritance->getString() ) )->getClass();                               
00873                         }
00874                         else
00875                         {
00876                                 return _Base_class;
00877                         }
00878                 }
00879                 else
00880                         return NULL;
00881         }
00882 
00883         // Returns the highest class in the class hiérarchy (SuperClass)
00884         const CAgentClass *CAgentClass::getSuperClass() const
00885         {
00886                 const CAgentClass *base_class = this;
00887                 
00888                 while ( base_class->getBaseClass() )
00889                 {
00890                         base_class = (CAgentClass *) base_class->getBaseClass();
00891                 }
00892                 return base_class;
00893         }
00894 
00896         const void CAgentClass::getClassPath(std::vector<const CAgentClass *> &path) const
00897         {
00898                 const CAgentClass *base_class = (CAgentClass *) getBaseClass();
00899 #ifdef NL_DEBUG
00900                 const char *txt = NULL;
00901                 if(getName() != NULL) txt = getName()->getString();
00902                 else if(getName() != NULL) txt = base_class->getName()->getString();
00903 #endif          
00904                 if ( base_class /*&& !(base_class->getType() == IdAgentClass)*/)
00905                 {
00906                         base_class->getClassPath( path );
00907                 }
00908                 path.push_back( this );
00909         }
00910 
00912         sint32 CAgentClass::getNbBaseClass() const
00913         {
00914                 sint32 dist = 0;
00915                 const CAgentClass *base_class = this;
00916                 while ( base_class->getBaseClass() )
00917                 {
00918                         base_class = (CAgentClass *) base_class->getBaseClass();
00919                         dist++;
00920                 }
00921                 return dist;
00922         }
00923 
00924         const char *CAgentClass::getComponentName(sint32 i) const
00925         {
00926                 sint32 nb_components = 0;
00927                 std::vector<const CAgentClass *>::const_iterator it_bc = _VTable.begin();
00928                 while ( it_bc != _VTable.end() && nb_components <= i )
00929                 {
00930                         nb_components = nb_components + (*it_bc)->getStaticMemberSize();
00931                         it_bc++;
00932                 }
00933                 it_bc--;
00934                 CComponent *component = (*it_bc)->getComponent( i - ( nb_components - (*it_bc)->getStaticMemberSize() ) );
00935                 return component->ObjectName->getString();
00936         }
00937 
00938         sint32 CAgentClass::getRunMethod() const
00939         {
00940                 return _RunIndex;
00941         }
00942 
00943         void CAgentClass::setRunMethod(sint32 index)
00944         {
00945                 _RunIndex = index + getBaseMethodCount();
00946         }
00947 
00948         sint32 CAgentClass::getConstroctorMethod() const
00949         {
00950                 return _ConstructorIndex;
00951         }
00952 
00953         void CAgentClass::setConstroctorMethod(sint32 index)
00954         {
00955                 _ConstructorIndex = index + getBaseMethodCount();
00956         }
00957 
00958         void CAgentClass::initStatics()
00959         {       
00960                 NLAIAGENT::CStringVarName staticinit_func_name("StaticInit");
00961                 sint32 id_func = findMethod( staticinit_func_name, NLAISCRIPT::CParam() );
00962                 if ( id_func != -1 )
00963                 {       
00964                         NLAISCRIPT::CStackPointer stack;
00965                         NLAISCRIPT::CStackPointer heap;
00966                         NLAISCRIPT::CCodeContext codeContext(stack,heap,NULL,this, NLAISCRIPT::CCallPrint::inputOutput);
00967                         codeContext.Self = this;
00968                         NLAISCRIPT::CCodeBrancheRun *o = (NLAISCRIPT::CCodeBrancheRun *)getBrancheCode( id_func ).getCode();
00969                         codeContext.Code = o;
00970                         o->run(codeContext);
00971                 }
00972         }
00973 
00974         bool CAgentClass::setStaticMember(sint32 index, NLAIAGENT::IObjectIA *obj)
00975         {
00976 #ifdef NL_DEBUG
00977                 std::string buf;
00978                 obj->getDebugString(buf);
00979 #endif
00980                 sint32 nb_components = 0;
00981                 std::vector<const CAgentClass *>::const_iterator it_bc = _VTable.begin();
00982                 while ( it_bc != _VTable.end() && nb_components <= index )
00983                 {
00984                         nb_components = nb_components + (*it_bc)->getStaticMemberSize();
00985                         it_bc++;
00986                 }
00987                 it_bc--;
00988                 CComponent *component = (*it_bc)->getComponent( index - ( nb_components - (*it_bc)->getStaticMemberSize() ) );
00989 #ifdef NL_DEBUG
00990                 std::string buf2, buf3;
00991                 component->RegisterName->getDebugString(buf2);
00992                 component->ObjectName->getDebugString(buf3);
00993 #endif
00994 
00995                 if(component->StaticValue != obj ) component->StaticValue = obj;
00996                         return false;
00997                 return true;
00998         }
00999 
01000         void CAgentClass::updateStaticMember(sint32 index, NLAIAGENT::IObjectIA *obj)
01001         {
01002 #ifdef NL_DEBUG
01003                 std::string buf;
01004                 obj->getDebugString(buf);
01005 #endif
01006                 sint32 nb_components = 0;
01007                 std::vector<const CAgentClass *>::const_iterator it_bc = _VTable.begin();
01008                 while ( it_bc != _VTable.end() && nb_components <= index )
01009                 {
01010                         nb_components = nb_components + (*it_bc)->getStaticMemberSize();
01011                         it_bc++;
01012                 }
01013                 it_bc--;
01014                 CComponent *component = (*it_bc)->getComponent( index - ( nb_components - (*it_bc)->getStaticMemberSize() ) );
01015 #ifdef NL_DEBUG
01016                 std::string buf2, buf3;
01017                 component->RegisterName->getDebugString(buf2);
01018                 component->ObjectName->getDebugString(buf3);
01019 #endif
01020 
01021                 (*component->StaticValue) = *obj;
01022         }
01023 
01024         NLAIAGENT::IObjectIA *CAgentClass::getStaticComponentValue(std::string &c_name)
01025         {
01026                 CComponent *component = getComponent( NLAIAGENT::CStringVarName( c_name.c_str() ) );
01027                 return component->StaticValue;
01028         }
01029 }