Make all CBotStack data members non-static

fix-squashed-planets
melex750 2021-06-11 22:48:50 -04:00
parent a279541198
commit 27466a4223
6 changed files with 92 additions and 104 deletions

View File

@ -243,13 +243,6 @@ CBotVar* CBotProgram::GetStackVars(std::string& functionName, int level)
return m_stack->GetStackVars(functionName, level); return m_stack->GetStackVars(functionName, level);
} }
////////////////////////////////////////////////////////////////////////////////
void CBotProgram::SetTimer(int n)
{
CBotStack::SetTimer( n );
}
////////////////////////////////////////////////////////////////////////////////
CBotError CBotProgram::GetError() CBotError CBotProgram::GetError()
{ {
return m_error; return m_error;

View File

@ -202,14 +202,6 @@ public:
*/ */
void Stop(); void Stop();
/**
* \brief Sets the number of steps (parts of instructions) to execute in Run() before suspending the program execution
* \param n new timer value
*
* FIXME: Seems to be currently kind of broken (see issue #410)
*/
static void SetTimer(int n);
/** /**
* \brief Add a function that can be called from CBot * \brief Add a function that can be called from CBot
* *

View File

@ -39,16 +39,24 @@ namespace CBot
const int DEFAULT_TIMER = 100; const int DEFAULT_TIMER = 100;
int CBotStack::m_initimer = DEFAULT_TIMER; struct CBotStack::Data
int CBotStack::m_timer = 0; {
CBotVar* CBotStack::m_retvar = nullptr; int initimer = DEFAULT_TIMER;
CBotError CBotStack::m_error = CBotNoErr; int timer = 0;
int CBotStack::m_start = 0;
int CBotStack::m_end = 0; CBotError error = CBotNoErr;
std::string CBotStack::m_labelBreak=""; int errStart = 0;
void* CBotStack::m_pUser = nullptr; int errEnd = 0;
std::string labelBreak = "";
CBotProgram* baseProg = nullptr;
CBotStack* topStack = nullptr;
void* pUser = nullptr;
std::unique_ptr<CBotVar> retvar;
};
////////////////////////////////////////////////////////////////////////////////
CBotStack* CBotStack::AllocateStack() CBotStack* CBotStack::AllocateStack()
{ {
CBotStack* p; CBotStack* p;
@ -73,7 +81,8 @@ CBotStack* CBotStack::AllocateStack()
pp ++; pp ++;
} }
m_error = CBotNoErr; // avoids deadlocks because m_error is static p->m_data = new CBotStack::Data;
p->m_data->topStack = p;
return p; return p;
} }
@ -97,6 +106,7 @@ void CBotStack::Delete()
CBotStack* p = m_prev; CBotStack* p = m_prev;
bool bOver = m_bOver; bool bOver = m_bOver;
if ( m_prev == nullptr ) delete m_data;
// clears the freed block // clears the freed block
memset(this, 0, sizeof(CBotStack)); memset(this, 0, sizeof(CBotStack));
@ -123,6 +133,7 @@ CBotStack* CBotStack::AddStack(CBotInstr* instr, BlockVisibilityType bBlock)
while ( p->m_prev != nullptr ); while ( p->m_prev != nullptr );
m_next = p; // chain an element m_next = p; // chain an element
p->m_data = m_data;
p->m_block = bBlock; p->m_block = bBlock;
p->m_instr = instr; p->m_instr = instr;
p->m_prog = m_prog; p->m_prog = m_prog;
@ -166,6 +177,7 @@ CBotStack* CBotStack::AddStack2(BlockVisibilityType bBlock)
while ( p->m_prev != nullptr ); while ( p->m_prev != nullptr );
m_next2 = p; // chain an element m_next2 = p; // chain an element
p->m_data = m_data;
p->m_prev = this; p->m_prev = this;
p->m_block = bBlock; p->m_block = bBlock;
p->m_prog = m_prog; p->m_prog = m_prog;
@ -220,18 +232,32 @@ bool CBotStack::ReturnKeep(CBotStack* pfils)
bool CBotStack::StackOver() bool CBotStack::StackOver()
{ {
if (!m_bOver) return false; if (!m_bOver) return false;
m_error = CBotErrStackOver; m_data->error = CBotErrStackOver;
return true; return true;
} }
//////////////////////////////////////////////////////////////////////////////// CBotError CBotStack::GetError(int& start, int& end)
{
start = m_data->errStart;
end = m_data->errEnd;
return m_data->error;
}
CBotError CBotStack::GetError()
{
return m_data->error;
}
bool CBotStack::IsOk()
{
return m_data->error == CBotNoErr;
}
void CBotStack::Reset() void CBotStack::Reset()
{ {
m_timer = m_initimer; // resets the timer m_data->timer = m_data->initimer; // resets the timer
m_error = CBotNoErr; m_data->error = CBotNoErr;
// m_start = 0; m_data->labelBreak.clear();
// m_end = 0;
m_labelBreak.clear();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -258,35 +284,35 @@ CBotStack* CBotStack::RestoreStackEOX(CBotExternalCall* instr)
// routine for execution step by step // routine for execution step by step
bool CBotStack::IfStep() bool CBotStack::IfStep()
{ {
if ( m_initimer > 0 || m_step++ > 0 ) return false; if (m_data->initimer > 0 || m_step++ > 0) return false;
return true; return true;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CBotStack::BreakReturn(CBotStack* pfils, const std::string& name) bool CBotStack::BreakReturn(CBotStack* pfils, const std::string& name)
{ {
if ( m_error>=0 ) return false; // normal output if (m_data->error >= CBotNoErr) return false; // normal output
if ( m_error==CBotError(-3) ) return false; // normal output (return current) if (m_data->error == CBotError(-3)) return false; // normal output (return current)
if (!m_labelBreak.empty() && (name.empty() || m_labelBreak != name)) if (!m_data->labelBreak.empty() && (name.empty() || m_data->labelBreak != name))
return false; // it's not for me return false; // it's not for me
m_error = CBotNoErr; m_data->error = CBotNoErr;
m_labelBreak.clear(); m_data->labelBreak.clear();
return Return(pfils); return Return(pfils);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CBotStack::IfContinue(int state, const std::string& name) bool CBotStack::IfContinue(int state, const std::string& name)
{ {
if ( m_error != CBotError(-2) ) return false; if (m_data->error != CBotError(-2)) return false;
if (!m_labelBreak.empty() && (name.empty() || m_labelBreak != name)) if (!m_data->labelBreak.empty() && (name.empty() || m_data->labelBreak != name))
return false; // it's not for me return false; // it's not for me
m_state = state; // where again? m_state = state; // where again?
m_error = CBotNoErr; m_data->error = CBotNoErr;
m_labelBreak.clear(); m_data->labelBreak.clear();
if (m_next != nullptr) m_next->Delete(); // purge above stack if (m_next != nullptr) m_next->Delete(); // purge above stack
return true; return true;
} }
@ -294,11 +320,11 @@ bool CBotStack::IfContinue(int state, const std::string& name)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotStack::SetBreak(int val, const std::string& name) void CBotStack::SetBreak(int val, const std::string& name)
{ {
m_error = static_cast<CBotError>(-val); // reacts as an Exception m_data->error = static_cast<CBotError>(-val); // reacts as an Exception
m_labelBreak = name; m_data->labelBreak = name;
if (val == 3) // for a return if (val == 3) // for a return
{ {
m_retvar = m_var; m_data->retvar.reset(m_var);
m_var = nullptr; m_var = nullptr;
} }
} }
@ -307,12 +333,11 @@ void CBotStack::SetBreak(int val, const std::string& name)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CBotStack::GetRetVar(bool bRet) bool CBotStack::GetRetVar(bool bRet)
{ {
if (m_error == CBotError(-3)) if (m_data->error == CBotError(-3))
{ {
if ( m_var ) delete m_var; if ( m_var ) delete m_var;
m_var = m_retvar; m_var = m_data->retvar.release();
m_retvar = nullptr; m_data->error = CBotNoErr;
m_error = CBotNoErr;
return true; return true;
} }
return bRet; // interrupted by something other than return return bRet; // interrupted by something other than return
@ -322,7 +347,7 @@ bool CBotStack::GetRetVar(bool bRet)
CBotVar* CBotStack::FindVar(CBotToken*& pToken, bool bUpdate) CBotVar* CBotStack::FindVar(CBotToken*& pToken, bool bUpdate)
{ {
CBotStack* p = this; CBotStack* p = this;
std::string name = pToken->GetString(); const auto& name = pToken->GetString();
while (p != nullptr) while (p != nullptr)
{ {
@ -332,7 +357,7 @@ CBotVar* CBotStack::FindVar(CBotToken*& pToken, bool bUpdate)
if (pp->GetName() == name) if (pp->GetName() == name)
{ {
if ( bUpdate ) if ( bUpdate )
pp->Update(m_pUser); pp->Update(m_data->pUser);
return pp; return pp;
} }
@ -375,7 +400,7 @@ CBotVar* CBotStack::FindVar(long ident, bool bUpdate)
if (pp->GetUniqNum() == ident) if (pp->GetUniqNum() == ident)
{ {
if ( bUpdate ) if ( bUpdate )
pp->Update(m_pUser); pp->Update(m_data->pUser);
return pp; return pp;
} }
@ -410,8 +435,8 @@ bool CBotStack::SetState(int n, int limite)
{ {
m_state = n; m_state = n;
m_timer--; // decrement the timer m_data->timer--; // decrement the timer
return ( m_timer > limite ); // interrupted if timer pass return (m_data->timer > limite); // interrupted if timer pass
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -419,46 +444,46 @@ bool CBotStack::IncState(int limite)
{ {
m_state++; m_state++;
m_timer--; // decrement the timer m_data->timer--; // decrement the timer
return ( m_timer > limite ); // interrupted if timer pass return (m_data->timer > limite); // interrupted if timer pass
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotStack::SetError(CBotError n, CBotToken* token) void CBotStack::SetError(CBotError n, CBotToken* token)
{ {
if (n != CBotNoErr && m_error != CBotNoErr) return; // does not change existing error if (n != CBotNoErr && m_data->error != CBotNoErr) return; // does not change existing error
m_error = n; m_data->error = n;
if (token != nullptr) if (token != nullptr)
{ {
m_start = token->GetStart(); m_data->errStart = token->GetStart();
m_end = token->GetEnd(); m_data->errEnd = token->GetEnd();
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotStack::ResetError(CBotError n, int start, int end) void CBotStack::ResetError(CBotError n, int start, int end)
{ {
m_error = n; m_data->error = n;
m_start = start; m_data->errStart = start;
m_end = end; m_data->errEnd = end;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotStack::SetPosError(CBotToken* token) void CBotStack::SetPosError(CBotToken* token)
{ {
m_start = token->GetStart(); m_data->errStart = token->GetStart();
m_end = token->GetEnd(); m_data->errEnd = token->GetEnd();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CBotStack::SetTimer(int n) void CBotStack::SetTimer(int n)
{ {
m_initimer = n; m_data->initimer = n;
} }
int CBotStack::GetTimer() int CBotStack::GetTimer()
{ {
return m_initimer; return m_data->initimer;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -542,26 +567,25 @@ void CBotStack::SetProgram(CBotProgram* p)
{ {
m_prog = p; m_prog = p;
m_func = IsFunction::YES; m_func = IsFunction::YES;
if (this == m_data->topStack) m_data->baseProg = p;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotProgram* CBotStack::GetProgram(bool bFirst) CBotProgram* CBotStack::GetProgram(bool bFirst)
{ {
if ( ! bFirst ) return m_prog; if ( ! bFirst ) return m_prog;
CBotStack* p = this; return m_data->baseProg;
while ( p->m_prev != nullptr ) p = p->m_prev;
return p->m_prog;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void* CBotStack::GetUserPtr() void* CBotStack::GetUserPtr()
{ {
return m_pUser; return m_data->pUser;
} }
void CBotStack::SetUserPtr(void* user) void CBotStack::SetUserPtr(void* user)
{ {
m_pUser = user; m_data->pUser = user;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -82,9 +82,6 @@ public:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/** \name Error management /** \name Error management
*
* BE CAREFUL - errors are stored in static variables!
* \todo Refactor that
*/ */
//@{ //@{
@ -94,24 +91,21 @@ public:
* \param[out] end Ending position in code of the error * \param[out] end Ending position in code of the error
* \return Error number * \return Error number
*/ */
CBotError GetError(int& start, int& end) { start = m_start; end = m_end; return m_error; } CBotError GetError(int& start, int& end);
/** /**
* \brief Get last error * \brief Get last error
* \return Error number * \return Error number
* \see GetError(int&, int&) for error position in code * \see GetError(int&, int&) for error position in code
*/ */
CBotError GetError() { return m_error; } CBotError GetError();
/** /**
* \brief Check if there was an error * \brief Check if there was an error
* \return false if an error occurred * \return false if an error occurred
* \see GetError() * \see GetError()
*/ */
bool IsOk() bool IsOk();
{
return m_error == CBotNoErr;
}
/** /**
* \brief Set execution error unless it's already set unless you are trying to reset it * \brief Set execution error unless it's already set unless you are trying to reset it
@ -357,7 +351,7 @@ public:
/** /**
* \todo Document * \todo Document
* *
* Copies the result value from static m_retvar (m_var at a moment of SetBreak(3)) to this stack result * Copies the result value from m_data->retvar (m_var at a moment of SetBreak(3)) to this stack result
*/ */
bool GetRetVar(bool bRet); bool GetRetVar(bool bRet);
@ -446,11 +440,11 @@ public:
* *
* \todo Full documentation of the timer * \todo Full documentation of the timer
*/ */
static void SetTimer(int n); void SetTimer(int n);
/** /**
* \brief Get the current configured maximum number of "timer ticks" (parts of instructions) to execute * \brief Get the current configured maximum number of "timer ticks" (parts of instructions) to execute
*/ */
static int GetTimer(); int GetTimer();
/** /**
* \brief Get current position in the program * \brief Get current position in the program
@ -476,10 +470,10 @@ private:
int m_state; int m_state;
int m_step; int m_step;
static CBotError m_error;
static int m_start; struct Data;
static int m_end;
static CBotVar* m_retvar; // result of a return CBotStack::Data* m_data;
CBotVar* m_var; // result of the operations CBotVar* m_var; // result of the operations
CBotVar* m_listVar; // variables declared at this level CBotVar* m_listVar; // variables declared at this level
@ -489,11 +483,6 @@ private:
//! CBotProgram instance the execution is in in this stack level //! CBotProgram instance the execution is in in this stack level
CBotProgram* m_prog; CBotProgram* m_prog;
static int m_initimer;
static int m_timer;
static std::string m_labelBreak;
static void* m_pUser;
//! The corresponding instruction //! The corresponding instruction
CBotInstr* m_instr; CBotInstr* m_instr;
//! If this stack level holds a function call //! If this stack level holds a function call

View File

@ -380,14 +380,7 @@ void CBotVarClass::DecrementUse()
{ {
m_CptUse++; // does not return to the destructor m_CptUse++; // does not return to the destructor
// m_error is static in the stack CBotStack* pile = CBotStack::AllocateStack();
// saves the value for return
CBotError err;
int start, end;
CBotStack* pile = nullptr;
err = pile->GetError(start,end); // stack == nullptr it does not bother!
pile = CBotStack::AllocateStack(); // clears the error
CBotVar* ppVars[1]; CBotVar* ppVars[1];
ppVars[0] = nullptr; ppVars[0] = nullptr;
@ -401,8 +394,6 @@ void CBotVarClass::DecrementUse()
while ( pile->IsOk() && !m_pClass->ExecuteMethode(ident, pThis, ppVars, CBotTypResult(CBotTypVoid), pile, &token)) ; // waits for the end while ( pile->IsOk() && !m_pClass->ExecuteMethode(ident, pThis, ppVars, CBotTypResult(CBotTypVoid), pile, &token)) ; // waits for the end
pile->ResetError(err, start,end);
pile->Delete(); pile->Delete();
delete pThis; delete pThis;
m_CptUse--; m_CptUse--;

View File

@ -3411,7 +3411,6 @@ private:
void CScriptFunctions::Init() void CScriptFunctions::Init()
{ {
CBotProgram::SetTimer(100);
CBotProgram::Init(); CBotProgram::Init();
for (int i = 0; i < OBJECT_MAX; i++) for (int i = 0; i < OBJECT_MAX; i++)