[colobot] 197/377: Made CBotExternalCallList combatible with class calls

Didier Raboud odyx at moszumanska.debian.org
Wed Mar 30 13:34:15 UTC 2016


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian/master
in repository colobot.

commit ff081aff499edfcce4a562fe1e89e03a104d46b5
Author: krzys-h <krzys_h at interia.pl>
Date:   Thu Dec 24 12:57:37 2015 +0100

    Made CBotExternalCallList combatible with class calls
---
 src/CBot/CBotCStack.cpp       |  2 +-
 src/CBot/CBotExternalCall.cpp | 59 +++++++++++++++++++++++++++++++++++++------
 src/CBot/CBotExternalCall.h   | 51 +++++++++++++++++++++++++++++++------
 src/CBot/CBotStack.cpp        |  8 +++---
 4 files changed, 99 insertions(+), 21 deletions(-)

diff --git a/src/CBot/CBotCStack.cpp b/src/CBot/CBotCStack.cpp
index c8bf457..a024bb3 100644
--- a/src/CBot/CBotCStack.cpp
+++ b/src/CBot/CBotCStack.cpp
@@ -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);
diff --git a/src/CBot/CBotExternalCall.cpp b/src/CBot/CBotExternalCall.cpp
index 1d88c3b..46ccf3e 100644
--- a/src/CBot/CBotExternalCall.cpp
+++ b/src/CBot/CBotExternalCall.cpp
@@ -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;
+}
\ No newline at end of file
diff --git a/src/CBot/CBotExternalCall.h b/src/CBot/CBotExternalCall.h
index 95ff4b6..12b768b 100644
--- a/src/CBot/CBotExternalCall.h
+++ b/src/CBot/CBotExternalCall.h
@@ -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
diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp
index 2b2672b..6764177 100644
--- a/src/CBot/CBotStack.cpp
+++ b/src/CBot/CBotStack.cpp
@@ -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);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list