2014-10-14 13:11:37 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the Colobot: Gold Edition source code
|
2015-08-22 14:40:02 +00:00
|
|
|
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
|
|
|
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
2014-10-14 13:11:37 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see http://gnu.org/licenses
|
|
|
|
*/
|
2012-08-07 13:46:04 +00:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// Management of variables of class type
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "CBot.h"
|
2015-11-15 15:49:06 +00:00
|
|
|
|
|
|
|
#include "CBotCall.h"
|
|
|
|
|
2015-11-11 16:42:10 +00:00
|
|
|
#include "CBotInstr/CBotNew.h"
|
2015-11-11 17:07:11 +00:00
|
|
|
#include "CBotInstr/CBotLeftExprVar.h"
|
2015-11-11 20:27:56 +00:00
|
|
|
#include "CBotInstr/CBotTwoOpExpr.h"
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
CBotClass* CBotClass::m_ExClass = nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
|
|
|
CBotClass::CBotClass(const char* name, CBotClass* pPapa, bool bIntrinsic)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
m_pParent = pPapa;
|
|
|
|
m_name = name;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_pVar = nullptr;
|
|
|
|
m_next = nullptr;
|
|
|
|
m_pCalls = nullptr;
|
|
|
|
m_pMethod = nullptr;
|
|
|
|
m_rMaj = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
m_IsDef = true;
|
|
|
|
m_bIntrinsic= bIntrinsic;
|
|
|
|
m_cptLock = 0;
|
|
|
|
m_cptOne = 0;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_nbVar = m_pParent == nullptr ? 0 : m_pParent->m_nbVar;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
for ( int j= 0; j< 5 ; j++ )
|
|
|
|
{
|
2015-08-16 10:43:42 +00:00
|
|
|
m_ProgInLock[j] = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
// is located alone in the list
|
|
|
|
if (m_ExClass) m_ExClass->m_ExPrev = this;
|
|
|
|
m_ExNext = m_ExClass;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_ExPrev = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
m_ExClass = this;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
CBotClass::~CBotClass()
|
|
|
|
{
|
2013-05-26 15:47:54 +00:00
|
|
|
// removes the list of class
|
2012-08-08 20:35:17 +00:00
|
|
|
if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext;
|
|
|
|
else m_ExClass = m_ExNext;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_ExPrev = nullptr;
|
|
|
|
m_ExNext = nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
delete m_pVar;
|
|
|
|
delete m_pCalls;
|
|
|
|
delete m_pMethod;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
delete m_next; // releases all of them on this level
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
CBotClass* CBotClass::Create(const char* name, CBotClass* parent, bool intrinsic)
|
|
|
|
{
|
|
|
|
return new CBotClass(name, parent, intrinsic);
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
|
|
|
void CBotClass::Free()
|
|
|
|
{
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( m_ExClass != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
delete m_ExClass;
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CBotClass::Purge()
|
|
|
|
{
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( this == nullptr ) return;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
delete m_pVar;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_pVar = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
delete m_pCalls;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_pCalls = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
delete m_pMethod;
|
2015-08-16 10:43:42 +00:00
|
|
|
m_pMethod = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
m_IsDef = false;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
m_nbVar = m_pParent == nullptr ? 0 : m_pParent->m_nbVar;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
m_next->Purge();
|
2015-08-16 10:43:42 +00:00
|
|
|
m_next = nullptr; // no longer belongs to this chain
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CBotClass::Lock(CBotProgram* p)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
int i = m_cptLock++;
|
|
|
|
|
|
|
|
if ( i == 0 )
|
|
|
|
{
|
|
|
|
m_cptOne = 1;
|
|
|
|
m_ProgInLock[0] = p;
|
|
|
|
return true;
|
|
|
|
}
|
2013-05-26 15:47:54 +00:00
|
|
|
if ( p == m_ProgInLock[0] )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
m_cptOne++;
|
|
|
|
m_cptLock--; // has already been counted
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( int j = 1 ; j <= i ; j++)
|
|
|
|
{
|
|
|
|
if ( p == m_ProgInLock[j] )
|
|
|
|
{
|
|
|
|
m_cptLock--;
|
|
|
|
return false; // already pending
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( i < 5 ) // max 5 in query
|
|
|
|
{
|
|
|
|
m_ProgInLock[i] = p; // located in a queue
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_cptLock--;
|
|
|
|
|
|
|
|
return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CBotClass::Unlock()
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
if ( --m_cptOne > 0 ) return ;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
int i = --m_cptLock;
|
|
|
|
if ( i<0 )
|
|
|
|
{
|
|
|
|
m_cptLock = 0;
|
|
|
|
return;
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
for ( int j= 0; j< i ; j++ )
|
|
|
|
{
|
|
|
|
m_ProgInLock[j] = m_ProgInLock[j+1];
|
|
|
|
}
|
2015-08-17 20:40:52 +00:00
|
|
|
m_ProgInLock[i] = nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CBotClass::FreeLock(CBotProgram* p)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotClass* pClass = m_ExClass;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( pClass != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2013-05-26 15:47:54 +00:00
|
|
|
if ( p == pClass->m_ProgInLock[0] )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
pClass->m_cptLock -= pClass->m_cptOne;
|
|
|
|
pClass->m_cptOne = 0;
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
for ( int j = 1; j < 5 ; j++ )
|
2013-05-26 15:47:54 +00:00
|
|
|
if ( p == pClass->m_ProgInLock[j] )
|
2012-08-08 20:35:17 +00:00
|
|
|
pClass->m_cptLock--;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
pClass = pClass->m_ExNext;
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CBotClass::AddItem(CBotString name, CBotTypResult type, int mPrivate)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotToken token(name, CBotString());
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotClass* pClass = type.GetClass();
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotVar* pVar = CBotVar::Create( name, type );
|
|
|
|
/// pVar->SetUniqNum(CBotVar::NextUniqNum());
|
|
|
|
pVar->SetPrivate( mPrivate );
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( pClass != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
// pVar->SetClass(pClass);
|
|
|
|
if ( type.Eq(CBotTypClass) )
|
|
|
|
{
|
|
|
|
// adds a new statement for the object initialization
|
|
|
|
pVar->m_InitExpr = new CBotNew() ;
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotToken nom( pClass->GetName() );
|
2012-08-08 20:35:17 +00:00
|
|
|
pVar->m_InitExpr->SetToken(&nom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return AddItem( pVar );
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CBotClass::AddItem(CBotVar* pVar)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
pVar->SetUniqNum(++m_nbVar);
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( m_pVar == nullptr ) m_pVar = pVar;
|
2012-08-08 20:35:17 +00:00
|
|
|
else m_pVar->AddNext(pVar);
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CBotClass::AddNext(CBotClass* pClass)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotClass* p = this;
|
2015-08-16 10:43:42 +00:00
|
|
|
while (p->m_next != nullptr) p = p->m_next;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
p->m_next = pClass;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotString CBotClass::GetName()
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
return m_name;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotClass* CBotClass::GetParent()
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( this == nullptr ) return nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
return m_pParent;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CBotClass::IsChildOf(CBotClass* pClass)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotClass* p = this;
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( p != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
if ( p == pClass ) return true;
|
|
|
|
p = p->m_pParent;
|
|
|
|
}
|
|
|
|
return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotVar* CBotClass::GetVar()
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
return m_pVar;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotVar* CBotClass::GetItem(const char* name)
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotVar* p = m_pVar;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( p != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
if ( p->GetName() == name ) return p;
|
|
|
|
p = p->GetNext();
|
2012-08-08 20:35:17 +00:00
|
|
|
}
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( m_pParent != nullptr ) return m_pParent->GetItem(name);
|
|
|
|
return nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotVar* CBotClass::GetItemRef(int nIdent)
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotVar* p = m_pVar;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( p != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
if ( p->GetUniqNum() == nIdent ) return p;
|
|
|
|
p = p->GetNext();
|
2012-08-08 20:35:17 +00:00
|
|
|
}
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( m_pParent != nullptr ) return m_pParent->GetItemRef(nIdent);
|
|
|
|
return nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CBotClass::IsIntrinsic()
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
return m_bIntrinsic;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CBotClass* CBotClass::Find(CBotToken* &pToken)
|
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
return Find(pToken->GetString());
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CBotClass* CBotClass::Find(const char* name)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotClass* p = m_ExClass;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( p != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
if ( p->GetName() == name ) return p;
|
2012-08-08 20:35:17 +00:00
|
|
|
p = p->m_ExNext;
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
return nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
2013-05-26 15:47:54 +00:00
|
|
|
bool CBotClass::AddFunction(const char* name,
|
2015-07-13 16:40:13 +00:00
|
|
|
bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user),
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar))
|
|
|
|
{
|
|
|
|
// stores pointers to the two functions
|
|
|
|
CBotCallMethode* p = m_pCalls;
|
2015-08-16 10:43:42 +00:00
|
|
|
CBotCallMethode* pp = nullptr;
|
2012-08-08 20:35:17 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( p != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
if ( name == p->GetName() )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( pp == nullptr ) m_pCalls = p->m_next;
|
2012-08-08 20:35:17 +00:00
|
|
|
else pp->m_next = p->m_next;
|
|
|
|
delete p;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pp = p;
|
|
|
|
p = p->m_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = new CBotCallMethode(name, rExec, rCompile);
|
2013-05-26 15:47:54 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
if (m_pCalls == nullptr) m_pCalls = p;
|
2012-08-08 20:35:17 +00:00
|
|
|
else m_pCalls->AddNext(p); // added to the list
|
|
|
|
|
|
|
|
return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CBotClass::AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) )
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
m_rMaj = rMaj;
|
|
|
|
return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// compiles a method associated with an instance of class
|
|
|
|
// the method can be declared by the user or AddFunction
|
|
|
|
|
2013-05-26 15:47:54 +00:00
|
|
|
CBotTypResult CBotClass::CompileMethode(const char* name,
|
|
|
|
CBotVar* pThis, CBotVar** ppParams,
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotCStack* pStack, long& nIdent)
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
nIdent = 0; // forget the previous one if necessary
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
// find the methods declared by AddFunction
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotTypResult r = m_pCalls->CompileCall(name, pThis, ppParams, pStack, nIdent);
|
2012-08-11 18:59:35 +00:00
|
|
|
if ( r.GetType() >= 0) return r;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
// find the methods declared by user
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
r = m_pMethod->CompileCall(name, ppParams, nIdent);
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( r.Eq(TX_UNDEFCALL) && m_pParent != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
return m_pParent->m_pMethod->CompileCall(name, ppParams, nIdent);
|
|
|
|
return r;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// executes a method
|
|
|
|
|
2013-05-26 15:47:54 +00:00
|
|
|
bool CBotClass::ExecuteMethode(long& nIdent, const char* name,
|
|
|
|
CBotVar* pThis, CBotVar** ppParams,
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotVar* &pResult, CBotStack* &pStack,
|
|
|
|
CBotToken* pToken)
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
int ret = m_pCalls->DoCall(nIdent, name, pThis, ppParams, pResult, pStack, pToken);
|
|
|
|
if (ret>=0) return ret;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this);
|
2015-11-21 12:27:40 +00:00
|
|
|
if (ret >= 0) return ret;
|
|
|
|
|
|
|
|
if (m_pParent != nullptr)
|
|
|
|
{
|
|
|
|
ret = m_pParent->m_pCalls->DoCall(nIdent, name, pThis, ppParams, pResult, pStack, pToken);
|
|
|
|
if (ret >= 0) return ret;
|
|
|
|
ret = m_pParent->m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, m_pParent);
|
|
|
|
}
|
2012-08-08 20:35:17 +00:00
|
|
|
return ret;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// restored the execution stack
|
|
|
|
|
|
|
|
void CBotClass::RestoreMethode(long& nIdent, const char* name, CBotVar* pThis,
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotVar** ppParams, CBotStack* &pStack)
|
2012-08-07 13:46:04 +00:00
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
m_pMethod->RestoreCall(nIdent, name, pThis, ppParams, pStack, this);
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CBotClass::SaveStaticState(FILE* pf)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
if (!WriteWord( pf, CBOTVERSION*2)) return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
// saves the state of static variables in classes
|
|
|
|
CBotClass* p = m_ExClass;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( p != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
if (!WriteWord( pf, 1)) return false;
|
|
|
|
// save the name of the class
|
2012-08-11 18:59:35 +00:00
|
|
|
if (!WriteString( pf, p->GetName() )) return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotVar* pv = p->GetVar();
|
2015-08-16 10:43:42 +00:00
|
|
|
while( pv != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
if ( pv->IsStatic() )
|
|
|
|
{
|
|
|
|
if (!WriteWord( pf, 1)) return false;
|
2012-08-11 18:59:35 +00:00
|
|
|
if (!WriteString( pf, pv->GetName() )) return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if ( !pv->Save0State(pf)) return false; // common header
|
|
|
|
if ( !pv->Save1State(pf) ) return false; // saves as the child class
|
|
|
|
if ( !WriteWord( pf, 0)) return false;
|
|
|
|
}
|
2012-08-11 18:59:35 +00:00
|
|
|
pv = pv->GetNext();
|
2012-08-08 20:35:17 +00:00
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if (!WriteWord( pf, 0)) return false;
|
|
|
|
p = p->m_ExNext;
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if (!WriteWord( pf, 0)) return false;
|
|
|
|
return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CBotClass::RestoreStaticState(FILE* pf)
|
|
|
|
{
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotString ClassName, VarName;
|
|
|
|
CBotClass* pClass;
|
|
|
|
unsigned short w;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if (!ReadWord( pf, w )) return false;
|
|
|
|
if ( w != CBOTVERSION*2 ) return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (!ReadWord( pf, w )) return false;
|
|
|
|
if ( w == 0 ) return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if (!ReadString( pf, ClassName )) return false;
|
|
|
|
pClass = Find(ClassName);
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (!ReadWord( pf, w )) return false;
|
|
|
|
if ( w == 0 ) break;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
CBotVar* pVar = nullptr;
|
|
|
|
CBotVar* pv = nullptr;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if (!ReadString( pf, VarName )) return false;
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( pClass != nullptr ) pVar = pClass->GetItem(VarName);
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2013-05-26 15:47:54 +00:00
|
|
|
if (!CBotVar::RestoreState(pf, pv)) return false; // the temp variable
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2015-08-16 10:43:42 +00:00
|
|
|
if ( pVar != nullptr ) pVar->Copy(pv);
|
2012-08-08 20:35:17 +00:00
|
|
|
delete pv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// test if a procedure name is already defined somewhere
|
|
|
|
|
|
|
|
bool CBotClass::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
|
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
CBotString name = pToken->GetString();
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
if ( CBotCall::CheckCall(name) ) return true;
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
CBotFunction* pp = m_pMethod;
|
2015-08-16 10:43:42 +00:00
|
|
|
while ( pp != nullptr )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
2012-08-11 18:59:35 +00:00
|
|
|
if ( pToken->GetString() == pp->GetName() )
|
2012-08-08 20:35:17 +00:00
|
|
|
{
|
|
|
|
// are their parameters exactly the same?
|
|
|
|
if ( pp->CheckParam( pParam ) )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
pp = pp->Next();
|
|
|
|
}
|
2012-08-07 13:46:04 +00:00
|
|
|
|
2012-08-08 20:35:17 +00:00
|
|
|
return false;
|
2012-08-07 13:46:04 +00:00
|
|
|
}
|