Refactored CBotVarClass instance list to std::set

dev-time-step
krzys-h 2015-12-31 16:54:13 +01:00
parent dcc29442bd
commit a70381e1c8
6 changed files with 54 additions and 74 deletions

View File

@ -49,15 +49,15 @@ CBotClass::CBotClass(const std::string& name,
CBotClass* parent, CBotClass* parent,
bool bIntrinsic) bool bIntrinsic)
{ {
m_pParent = parent; m_parent = parent;
m_name = name; m_name = name;
m_pVar = nullptr; m_pVar = nullptr;
m_pCalls = nullptr; m_pCalls = nullptr;
m_pMethod = nullptr; m_pMethod = nullptr;
m_rMaj = nullptr; m_rUpdate = nullptr;
m_IsDef = true; m_IsDef = true;
m_bIntrinsic= bIntrinsic; m_bIntrinsic= bIntrinsic;
m_nbVar = m_pParent == nullptr ? 0 : m_pParent->m_nbVar; m_nbVar = m_parent == nullptr ? 0 : m_parent->m_nbVar;
m_publicClasses.insert(this); m_publicClasses.insert(this);
} }
@ -99,7 +99,7 @@ void CBotClass::Purge()
m_pMethod = nullptr; m_pMethod = nullptr;
m_IsDef = false; m_IsDef = false;
m_nbVar = m_pParent == nullptr ? 0 : m_pParent->m_nbVar; m_nbVar = m_parent == nullptr ? 0 : m_parent->m_nbVar;
m_next->Purge(); m_next->Purge();
m_next = nullptr; // no longer belongs to this chain m_next = nullptr; // no longer belongs to this chain
@ -198,7 +198,7 @@ std::string CBotClass::GetName()
CBotClass* CBotClass::GetParent() CBotClass* CBotClass::GetParent()
{ {
if ( this == nullptr ) return nullptr; if ( this == nullptr ) return nullptr;
return m_pParent; return m_parent;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -208,7 +208,7 @@ bool CBotClass::IsChildOf(CBotClass* pClass)
while ( p != nullptr ) while ( p != nullptr )
{ {
if ( p == pClass ) return true; if ( p == pClass ) return true;
p = p->m_pParent; p = p->m_parent;
} }
return false; return false;
} }
@ -229,7 +229,7 @@ CBotVar* CBotClass::GetItem(const std::string& name)
if ( p->GetName() == name ) return p; if ( p->GetName() == name ) return p;
p = p->GetNext(); p = p->GetNext();
} }
if ( m_pParent != nullptr ) return m_pParent->GetItem(name); if (m_parent != nullptr ) return m_parent->GetItem(name);
return nullptr; return nullptr;
} }
@ -243,7 +243,7 @@ CBotVar* CBotClass::GetItemRef(int nIdent)
if ( p->GetUniqNum() == nIdent ) return p; if ( p->GetUniqNum() == nIdent ) return p;
p = p->GetNext(); p = p->GetNext();
} }
if ( m_pParent != nullptr ) return m_pParent->GetItemRef(nIdent); if (m_parent != nullptr ) return m_parent->GetItemRef(nIdent);
return nullptr; return nullptr;
} }
@ -301,9 +301,9 @@ bool CBotClass::AddFunction(const std::string& name,
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CBotClass::AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) ) bool CBotClass::SetUpdateFunc(void rUpdate(CBotVar* thisVar, void* user))
{ {
m_rMaj = rMaj; m_rUpdate = rUpdate;
return true; return true;
} }
@ -324,8 +324,8 @@ CBotTypResult CBotClass::CompileMethode(const std::string& name,
// find the methods declared by user // find the methods declared by user
r = m_pMethod->CompileCall(name, ppParams, nIdent); r = m_pMethod->CompileCall(name, ppParams, nIdent);
if ( r.Eq(CBotErrUndefCall) && m_pParent != nullptr ) if ( r.Eq(CBotErrUndefCall) && m_parent != nullptr )
return m_pParent->m_pMethod->CompileCall(name, ppParams, nIdent); return m_parent->m_pMethod->CompileCall(name, ppParams, nIdent);
return r; return r;
} }
@ -344,11 +344,11 @@ bool CBotClass::ExecuteMethode(long& nIdent,
ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this); ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this);
if (ret >= 0) return ret; if (ret >= 0) return ret;
if (m_pParent != nullptr) if (m_parent != nullptr)
{ {
ret = m_pParent->m_pCalls->DoCall(name, pThis, ppParams, pResult, pStack, pToken); ret = m_parent->m_pCalls->DoCall(name, pThis, ppParams, pResult, pStack, pToken);
if (ret >= 0) return ret; if (ret >= 0) return ret;
ret = m_pParent->m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, m_pParent); ret = m_parent->m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, m_parent);
} }
return ret; return ret;
} }
@ -493,7 +493,7 @@ CBotClass* CBotClass::Compile1(CBotToken* &p, CBotCStack* pStack)
} }
} }
CBotClass* classe = (pOld == nullptr) ? new CBotClass(name, pPapa) : pOld; CBotClass* classe = (pOld == nullptr) ? new CBotClass(name, pPapa) : pOld;
classe->Purge(); // emptythe old definitions classe->Purge(); // empty the old definitions // TODO: Doesn't this remove all classes of the current program?
classe->m_IsDef = false; // current definition classe->m_IsDef = false; // current definition
if ( !IsOfType( p, ID_OPBLK) ) if ( !IsOfType( p, ID_OPBLK) )
@ -615,11 +615,11 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
pThis->SetUniqNum(-2); pThis->SetUniqNum(-2);
pile->AddVar(pThis); pile->AddVar(pThis);
if ( m_pParent ) if (m_parent)
{ {
// makes "super" known // makes "super" known
CBotToken TokenSuper(std::string("super"), std::string()); CBotToken TokenSuper(std::string("super"), std::string());
CBotVar* pThis = CBotVar::Create(TokenSuper, CBotTypResult( CBotTypClass, m_pParent ) ); CBotVar* pThis = CBotVar::Create(TokenSuper, CBotTypResult(CBotTypClass, m_parent) );
pThis->SetUniqNum(-3); pThis->SetUniqNum(-3);
pile->AddVar(pThis); pile->AddVar(pThis);
} }
@ -641,7 +641,7 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
pile->AddVar(pcopy); pile->AddVar(pcopy);
pv = pv->GetNext(); pv = pv->GetNext();
} }
my = my->m_pParent; my = my->m_parent;
} }
// compiles a method // compiles a method
@ -745,13 +745,13 @@ CBotClass* CBotClass::Compile(CBotToken* &p, CBotCStack* pStack)
pStack->SetError( CBotErrNotClass, p ); pStack->SetError( CBotErrNotClass, p );
return nullptr; return nullptr;
} }
pOld->m_pParent = pPapa; pOld->m_parent = pPapa;
} }
else else
{ {
if (pOld != nullptr) if (pOld != nullptr)
{ {
pOld->m_pParent = nullptr; pOld->m_parent = nullptr;
} }
} }
IsOfType( p, ID_OPBLK); // necessarily IsOfType( p, ID_OPBLK); // necessarily
@ -768,4 +768,9 @@ CBotClass* CBotClass::Compile(CBotToken* &p, CBotCStack* pStack)
return nullptr; return nullptr;
} }
void CBotClass::Update(CBotVar* var, void* user)
{
m_rUpdate(var, user);
}
} // namespace CBot } // namespace CBot

View File

@ -105,9 +105,6 @@ class CBotCStack;
class CBotClass : public CBotLinkedList<CBotClass> class CBotClass : public CBotLinkedList<CBotClass>
{ {
public: public:
//! Mark if is set or not
bool m_IsDef;
/*! /*!
* \brief CBotClass Constructor. Once a class is created, it is known around * \brief CBotClass Constructor. Once a class is created, it is known around
* CBot intrinsic mode gives a class that is not managed by pointers. * CBot intrinsic mode gives a class that is not managed by pointers.
@ -149,12 +146,12 @@ public:
CBotTypResult rCompile(CBotVar* pThis, CBotVar*& pVar)); CBotTypResult rCompile(CBotVar* pThis, CBotVar*& pVar));
/*! /*!
* \brief AddUpdateFunc Defines routine to be called to update the elements * \brief SetUpdateFunc Defines routine to be called to update the elements
* of the class. * of the class.
* \param rMaj * \param rMaj
* \return * \return
*/ */
bool AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) ); bool SetUpdateFunc(void rUpdate(CBotVar* thisVar, void* user));
// //
/*! /*!
@ -363,17 +360,22 @@ public:
*/ */
bool CheckCall(CBotProgram* program, CBotDefParam* pParam, CBotToken*& pToken); bool CheckCall(CBotProgram* program, CBotDefParam* pParam, CBotToken*& pToken);
void Update(CBotVar* var, void* user);
private: private:
//! List of all public classes //! List of all public classes
static std::set<CBotClass*> m_publicClasses; static std::set<CBotClass*> m_publicClasses;
//! Parent class.
CBotClass* m_pParent; //! true if this class is fully compiled, false if only precompiled
//! Name of this class. bool m_IsDef;
//! Name of this class
std::string m_name; std::string m_name;
//! Number of variables in the chain. //! Parent class
CBotClass* m_parent;
//! Number of variables in the chain
int m_nbVar; int m_nbVar;
//! Intrinsic class. //! Intrinsic class
bool m_bIntrinsic; bool m_bIntrinsic;
//! Linked list of all class fields //! Linked list of all class fields
CBotVar* m_pVar; CBotVar* m_pVar;
@ -381,8 +383,7 @@ private:
CBotCallMethode* m_pCalls; CBotCallMethode* m_pCalls;
//! Linked list of all class methods //! Linked list of all class methods
CBotFunction* m_pMethod; CBotFunction* m_pMethod;
void (*m_rMaj) ( CBotVar* pThis, void* pUser ); void (*m_rUpdate)(CBotVar* thisVar, void* user);
friend class CBotVarClass;
//! How many times the program currently holding the lock called Lock() //! How many times the program currently holding the lock called Lock()
int m_lockCurrentCount = 0; int m_lockCurrentCount = 0;

View File

@ -162,7 +162,7 @@ public:
/** /**
* \brief Fetch a variable by its token * \brief Fetch a variable by its token
* \param pToken Token upon which search is performed * \param pToken Token upon which search is performed
* \param bUpdate true to automatically call update function for classes, see CBotClass::AddUpdateFunc() * \param bUpdate true to automatically call update function for classes, see CBotClass::SetUpdateFunc()
* \return Found variable, nullptr if not found * \return Found variable, nullptr if not found
*/ */
CBotVar* FindVar(CBotToken*& pToken, bool bUpdate); CBotVar* FindVar(CBotToken*& pToken, bool bUpdate);
@ -185,7 +185,7 @@ public:
* This is faster than comparing names * This is faster than comparing names
* *
* \param ident Unique identifier of a variable * \param ident Unique identifier of a variable
* \param bUpdate true to automatically call update function for classes, see CBotClass::AddUpdateFunc() * \param bUpdate true to automatically call update function for classes, see CBotClass::SetUpdateFunc()
* \return Found variable, nullptr if not found * \return Found variable, nullptr if not found
*/ */
CBotVar* FindVar(long ident, bool bUpdate); CBotVar* FindVar(long ident, bool bUpdate);
@ -194,7 +194,7 @@ public:
* \brief Find variable by its token and returns a copy of it * \brief Find variable by its token and returns a copy of it
* *
* \param pToken Token upon which search is performed * \param pToken Token upon which search is performed
* \param bUpdate true to automatically call update function for classes, see CBotClass::AddUpdateFunc() * \param bUpdate true to automatically call update function for classes, see CBotClass::SetUpdateFunc()
* \return Found variable, nullptr if not found * \return Found variable, nullptr if not found
*/ */
CBotVar* CopyVar(CBotToken& pToken, bool bUpdate = false); CBotVar* CopyVar(CBotToken& pToken, bool bUpdate = false);

View File

@ -33,7 +33,7 @@ namespace CBot
{ {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotVarClass* CBotVarClass::m_ExClass = nullptr; std::set<CBotVarClass*> CBotVarClass::m_instances{};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type) CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type)
@ -66,10 +66,7 @@ CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type)
m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum(); m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum();
// add to the list // add to the list
if (m_ExClass != nullptr) m_ExClass->m_ExPrev = this; m_instances.insert(this);
m_ExNext = m_ExClass;
m_ExPrev = nullptr;
m_ExClass = this;
CBotClass* pClass = type.GetClass(); CBotClass* pClass = type.GetClass();
CBotClass* pClass2 = pClass->GetParent(); CBotClass* pClass2 = pClass->GetParent();
@ -79,7 +76,7 @@ CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type)
m_pParent = new CBotVarClass(name, CBotTypResult(type.GetType(),pClass2) ); //, nIdent); m_pParent = new CBotVarClass(name, CBotTypResult(type.GetType(),pClass2) ); //, nIdent);
} }
SetClass( pClass ); //, nIdent ); SetClass( pClass );
} }
@ -92,17 +89,8 @@ CBotVarClass::~CBotVarClass( )
if ( m_pParent ) delete m_pParent; if ( m_pParent ) delete m_pParent;
m_pParent = nullptr; m_pParent = nullptr;
// frees the indirect object if necessary
// if ( m_Indirect != nullptr )
// m_Indirect->DecrementUse();
// removes the class list // removes the class list
if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext; m_instances.erase(this);
else m_ExClass = m_ExNext;
if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev;
m_ExPrev = nullptr;
m_ExNext = nullptr;
delete m_pVar; delete m_pVar;
} }
@ -242,20 +230,13 @@ CBotClass* CBotVarClass::GetClass()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotVarClass::Maj(void* pUser) void CBotVarClass::Maj(void* pUser)
{ {
/* if (!bContinu && m_pMyThis != nullptr)
m_pMyThis->Maj(pUser, true);*/
// an update routine exist?
if ( m_pClass->m_rMaj == nullptr ) return;
// retrieves the user pointer according to the class // retrieves the user pointer according to the class
// or according to the parameter passed to CBotProgram::Run() // or according to the parameter passed to CBotProgram::Run()
if ( m_pUserPtr != nullptr) pUser = m_pUserPtr; if ( m_pUserPtr != nullptr) pUser = m_pUserPtr;
if ( pUser == OBJECTDELETED || if ( pUser == OBJECTDELETED ||
pUser == OBJECTCREATED ) return; pUser == OBJECTCREATED ) return;
m_pClass->m_rMaj( this, pUser ); m_pClass->Update(this, pUser);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -328,8 +309,6 @@ CBotVar* CBotVarClass::GetItemList()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string CBotVarClass::GetValString() std::string CBotVarClass::GetValString()
{ {
// if ( m_Indirect != nullptr) return m_Indirect->GetValString();
std::string res; std::string res;
if ( m_pClass != nullptr ) // not used for an array if ( m_pClass != nullptr ) // not used for an array
@ -440,12 +419,9 @@ CBotVarClass* CBotVarClass::GetPointer()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotVarClass* CBotVarClass::Find(long id) CBotVarClass* CBotVarClass::Find(long id)
{ {
CBotVarClass* p = m_ExClass; for (CBotVarClass* p : m_instances)
while ( p != nullptr )
{ {
if ( p->m_ItemIdent == id ) return p; if (p->m_ItemIdent == id) return p;
p = p->m_ExNext;
} }
return nullptr; return nullptr;

View File

@ -21,6 +21,8 @@
#include "CBot/CBotVar/CBotVar.h" #include "CBot/CBotVar/CBotVar.h"
#include <set>
namespace CBot namespace CBot
{ {
@ -93,12 +95,8 @@ public:
void ConstructorSet() override; void ConstructorSet() override;
private: private:
//! Doubly linked list of all class instances - first //! List of all class instances - first
static CBotVarClass* m_ExClass; static std::set<CBotVarClass*> m_instances;
//! Doubly linked list of all class instances - next
CBotVarClass* m_ExNext;
//! Doubly linked list of all class instances - previous
CBotVarClass* m_ExPrev;
//! Class definition //! Class definition
CBotClass* m_pClass; CBotClass* m_pClass;
//! Parent class instance //! Parent class instance

View File

@ -3427,7 +3427,7 @@ CBotVar* CScriptFunctions::CreateObjectVar(CObject* obj)
CBotClass* bc = CBotClass::Find("object"); CBotClass* bc = CBotClass::Find("object");
if ( bc != nullptr ) if ( bc != nullptr )
{ {
bc->AddUpdateFunc(CScriptFunctions::uObject); bc->SetUpdateFunc(CScriptFunctions::uObject);
} }
CBotVar* botVar = CBotVar::Create("", CBotTypResult(CBotTypClass, "object")); CBotVar* botVar = CBotVar::Create("", CBotTypResult(CBotTypClass, "object"));