Made CBotExternalCallList combatible with class calls
parent
ae544c71ae
commit
ff081aff49
|
@ -351,7 +351,7 @@ CBotTypResult CBotCStack::CompileCall(CBotToken* &p, CBotVar** ppVars, long& nId
|
|||
nIdent = 0;
|
||||
CBotTypResult val(-1);
|
||||
|
||||
val = m_prog->GetExternalCalls()->CompileCall(p, ppVars, this);
|
||||
val = m_prog->GetExternalCalls()->CompileCall(p, nullptr, ppVars, this);
|
||||
if (val.GetType() < 0)
|
||||
{
|
||||
val = m_prog->GetFunctions()->CompileCall(p->GetString(), ppVars, nIdent);
|
||||
|
|
|
@ -37,7 +37,7 @@ bool CBotExternalCallList::AddFunction(const std::string& name, std::unique_ptr<
|
|||
return true;
|
||||
}
|
||||
|
||||
CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar** ppVar, CBotCStack* pStack)
|
||||
CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar* thisVar, CBotVar** ppVar, CBotCStack* pStack)
|
||||
{
|
||||
if (m_list.count(p->GetString()) == 0)
|
||||
return -1;
|
||||
|
@ -45,7 +45,7 @@ CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar** ppVar,
|
|||
CBotExternalCall* pt = m_list[p->GetString()].get();
|
||||
|
||||
std::unique_ptr<CBotVar> args = std::unique_ptr<CBotVar>(MakeListVars(ppVar));
|
||||
CBotTypResult r = pt->Compile(args.get(), m_user);
|
||||
CBotTypResult r = pt->Compile(thisVar, args.get(), m_user);
|
||||
|
||||
// if a class is returned, it is actually a pointer
|
||||
if (r.GetType() == CBotTypClass) r.SetType(CBotTypPointer);
|
||||
|
@ -68,7 +68,7 @@ bool CBotExternalCallList::CheckCall(const std::string& name)
|
|||
return m_list.count(name) > 0;
|
||||
}
|
||||
|
||||
int CBotExternalCallList::DoCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack, const CBotTypResult& rettype)
|
||||
int CBotExternalCallList::DoCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVar, CBotStack* pStack, const CBotTypResult& rettype)
|
||||
{
|
||||
if (token == nullptr)
|
||||
return -1;
|
||||
|
@ -93,10 +93,10 @@ int CBotExternalCallList::DoCall(CBotToken* token, CBotVar** ppVar, CBotStack* p
|
|||
pile2->SetVar(pResult);
|
||||
|
||||
pile->SetError(CBotNoErr, token); // save token for the position in case of error
|
||||
return pt->Run(pStack);
|
||||
return pt->Run(thisVar, pStack);
|
||||
}
|
||||
|
||||
bool CBotExternalCallList::RestoreCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
|
||||
bool CBotExternalCallList::RestoreCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVar, CBotStack* pStack)
|
||||
{
|
||||
if (m_list.count(token->GetString()) == 0)
|
||||
return false;
|
||||
|
@ -123,7 +123,6 @@ CBotExternalCall::~CBotExternalCall()
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBotExternalCallDefault::CBotExternalCallDefault(RuntimeFunc rExec, CompileFunc rCompile)
|
||||
: CBotExternalCall()
|
||||
{
|
||||
m_rExec = rExec;
|
||||
m_rComp = rCompile;
|
||||
|
@ -133,12 +132,12 @@ CBotExternalCallDefault::~CBotExternalCallDefault()
|
|||
{
|
||||
}
|
||||
|
||||
CBotTypResult CBotExternalCallDefault::Compile(CBotVar* args, void* user)
|
||||
CBotTypResult CBotExternalCallDefault::Compile(CBotVar* thisVar, CBotVar* args, void* user)
|
||||
{
|
||||
return m_rComp(args, user);
|
||||
}
|
||||
|
||||
bool CBotExternalCallDefault::Run(CBotStack* pStack)
|
||||
bool CBotExternalCallDefault::Run(CBotVar* thisVar, CBotStack* pStack)
|
||||
{
|
||||
CBotStack* pile = pStack->AddStackEOX(this);
|
||||
if ( pile == EOX ) return true;
|
||||
|
@ -164,3 +163,47 @@ bool CBotExternalCallDefault::Run(CBotStack* pStack)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBotExternalCallDefaultClass::CBotExternalCallDefaultClass(RuntimeFunc rExec, CompileFunc rCompile)
|
||||
{
|
||||
m_rExec = rExec;
|
||||
m_rComp = rCompile;
|
||||
}
|
||||
|
||||
CBotExternalCallDefaultClass::~CBotExternalCallDefaultClass()
|
||||
{
|
||||
}
|
||||
|
||||
CBotTypResult CBotExternalCallDefaultClass::Compile(CBotVar* thisVar, CBotVar* args, void* user)
|
||||
{
|
||||
return m_rComp(nullptr, args);
|
||||
}
|
||||
|
||||
// TODO: Figure out why classes do pStack->SetVar while normal calls do pStack->SetCopyVar
|
||||
bool CBotExternalCallDefaultClass::Run(CBotVar* thisVar, CBotStack* pStack)
|
||||
{
|
||||
CBotStack* pile = pStack->AddStackEOX(this);
|
||||
if ( pile == EOX ) return true;
|
||||
CBotVar* args = pile->GetVar();
|
||||
|
||||
CBotStack* pile2 = pile->AddStack();
|
||||
|
||||
CBotVar* result = pile2->GetVar();
|
||||
|
||||
int exception = CBotNoErr; // TODO: Change to CBotError
|
||||
bool res = m_rExec(thisVar, args, result, exception, pStack->GetPUser());
|
||||
pStack->SetVar(result);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
if (exception != CBotNoErr)
|
||||
{
|
||||
pStack->SetError(static_cast<CBotError>(exception));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -56,18 +56,20 @@ public:
|
|||
/**
|
||||
* \brief Compile the function
|
||||
*
|
||||
* \param "this" variable for class calls, nullptr for normal calls
|
||||
* \param Arguments (only types!) passed to the function
|
||||
* \param User pointer provided to CBotProgram::Compile()
|
||||
*/
|
||||
virtual CBotTypResult Compile(CBotVar* args, void* user) = 0;
|
||||
virtual CBotTypResult Compile(CBotVar* thisVar, CBotVar* args, void* user) = 0;
|
||||
|
||||
/**
|
||||
* \brief Execute the function
|
||||
*
|
||||
* \param thisVar "this" variable for class calls, nullptr for normal calls
|
||||
* \param pStack Stack to execute the function on
|
||||
* \return false to request program interruption, true otherwise
|
||||
*/
|
||||
virtual bool Run(CBotStack* pStack) = 0;
|
||||
virtual bool Run(CBotVar* thisVar, CBotStack* pStack) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -92,8 +94,38 @@ public:
|
|||
*/
|
||||
virtual ~CBotExternalCallDefault();
|
||||
|
||||
virtual CBotTypResult Compile(CBotVar* args, void* user);
|
||||
virtual bool Run(CBotStack* pStack);
|
||||
virtual CBotTypResult Compile(CBotVar* thisVar, CBotVar* args, void* user);
|
||||
virtual bool Run(CBotVar* thisVar, CBotStack* pStack);
|
||||
|
||||
private:
|
||||
RuntimeFunc m_rExec;
|
||||
CompileFunc m_rComp;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Default implementation of CBot external class call, using compilation and runtime functions
|
||||
*/
|
||||
class CBotExternalCallDefaultClass : public CBotExternalCall
|
||||
{
|
||||
public:
|
||||
typedef bool (*RuntimeFunc)(CBotVar* thisVar, CBotVar* args, CBotVar* result, int& exception, void* user);
|
||||
typedef CBotTypResult (*CompileFunc)(CBotVar* thisVar, CBotVar*& args); // TODO: Add user pointer
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
* \param rExec Runtime function
|
||||
* \param rCompile Compilation function
|
||||
* \see CBotClass::AddFunction()
|
||||
*/
|
||||
CBotExternalCallDefaultClass(RuntimeFunc rExec, CompileFunc rCompile);
|
||||
|
||||
/**
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~CBotExternalCallDefaultClass();
|
||||
|
||||
virtual CBotTypResult Compile(CBotVar* thisVar, CBotVar* args, void* user);
|
||||
virtual bool Run(CBotVar* thisVar, CBotStack* pStack);
|
||||
|
||||
private:
|
||||
RuntimeFunc m_rExec;
|
||||
|
@ -124,10 +156,11 @@ public:
|
|||
*
|
||||
* \param p Token representing the function name
|
||||
* \param ppVars List of arguments (only types!)
|
||||
* \param thisVar "this" variable for class calls, nullptr for normal calls
|
||||
* \param pStack Compilation stack
|
||||
* \return CBotTypResult representing the return type of the function (::CBotTypVar), or an error (::CBotError)
|
||||
*/
|
||||
CBotTypResult CompileCall(CBotToken*& p, CBotVar** ppVars, CBotCStack* pStack);
|
||||
CBotTypResult CompileCall(CBotToken*& p, CBotVar* thisVar, CBotVar** ppVars, CBotCStack* pStack);
|
||||
|
||||
/**
|
||||
* \brief Check if function with given name has been defined
|
||||
|
@ -142,22 +175,24 @@ public:
|
|||
* This function sets an error in runtime stack in case of failure
|
||||
*
|
||||
* \param token Token representing the function name
|
||||
* \param thisVar "this" variable for class calls, nullptr for normal calls
|
||||
* \param ppVars List of arguments
|
||||
* \param pStack Runtime stack
|
||||
* \param rettype Return type of the function, as returned by CompileCall()
|
||||
* \return -1 if call failed (no such function), 0 if function requested interruption, 1 on success
|
||||
*/
|
||||
int DoCall(CBotToken* token, CBotVar** ppVars, CBotStack* pStack, const CBotTypResult& rettype);
|
||||
int DoCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVars, CBotStack* pStack, const CBotTypResult& rettype);
|
||||
|
||||
/**
|
||||
* \brief Restore execution status after loading saved state
|
||||
*
|
||||
* \param token Token representing the function name
|
||||
* \param ppVar List of arguments (TODO: unused)
|
||||
* \param "this" variable for class calls, nullptr for normal calls
|
||||
* \param ppVar List of arguments
|
||||
* \param pStack Runtime stack
|
||||
* \return false on failure (e.g. function doesn't exist)
|
||||
*/
|
||||
bool RestoreCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack);
|
||||
bool RestoreCall(CBotToken* token, CBotVar* thisVar, CBotVar** ppVar, CBotStack* pStack);
|
||||
|
||||
/**
|
||||
* \brief Set user pointer to pass to compile functions
|
||||
|
|
|
@ -637,7 +637,7 @@ bool CBotStack::Execute()
|
|||
|
||||
if ( instr == nullptr ) return true; // normal execution request
|
||||
|
||||
if (!instr->Run(pile)) return false; // \TODO exécution à partir de là
|
||||
if (!instr->Run(nullptr, pile)) return false; // \TODO exécution à partir de là
|
||||
|
||||
#if STACKMEM
|
||||
pile->m_next->Delete();
|
||||
|
@ -744,7 +744,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBo
|
|||
|
||||
// first looks by the identifier
|
||||
|
||||
res = m_prog->GetExternalCalls()->DoCall(nullptr, ppVar, this, rettype);
|
||||
res = m_prog->GetExternalCalls()->DoCall(nullptr, nullptr, ppVar, this, rettype);
|
||||
if (res.GetType() >= 0) return res.GetType();
|
||||
|
||||
res = m_prog->GetFunctions()->DoCall(nIdent, "", ppVar, this, token );
|
||||
|
@ -753,7 +753,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBo
|
|||
// if not found (recompile?) seeks by name
|
||||
|
||||
nIdent = 0;
|
||||
res = m_prog->GetExternalCalls()->DoCall(token, ppVar, this, rettype);
|
||||
res = m_prog->GetExternalCalls()->DoCall(token, nullptr, ppVar, this, rettype);
|
||||
if (res.GetType() >= 0) return res.GetType();
|
||||
|
||||
res = m_prog->GetFunctions()->DoCall(nIdent, token->GetString(), ppVar, this, token );
|
||||
|
@ -768,7 +768,7 @@ void CBotStack::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar)
|
|||
{
|
||||
if (m_next == nullptr) return;
|
||||
|
||||
if (m_prog->GetExternalCalls()->RestoreCall(token, ppVar, this))
|
||||
if (m_prog->GetExternalCalls()->RestoreCall(token, nullptr, ppVar, this))
|
||||
return;
|
||||
|
||||
m_prog->GetFunctions()->RestoreCall(nIdent, token->GetString(), ppVar, this);
|
||||
|
|
Loading…
Reference in New Issue