[colobot] 195/377: More extensible external call interface

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 8e01a208c1f12ce4297d89985d5d605cb653e729
Author: krzys-h <krzys_h at interia.pl>
Date:   Thu Dec 24 11:57:34 2015 +0100

    More extensible external call interface
---
 src/CBot/CBotCStack.cpp                         |   6 +-
 src/CBot/CBotCall.h                             | 124 ----------------
 src/CBot/CBotCallMethode.cpp                    |  59 +-------
 src/CBot/CBotCallMethode.h                      |  24 +---
 src/CBot/CBotClass.cpp                          |  12 +-
 src/CBot/CBotEnums.h                            |   4 +-
 src/CBot/{CBotCall.cpp => CBotExternalCall.cpp} | 107 +++++++-------
 src/CBot/CBotExternalCall.h                     | 179 ++++++++++++++++++++++++
 src/CBot/CBotProgram.cpp                        |  13 +-
 src/CBot/CBotStack.cpp                          |  16 +--
 src/CBot/CBotStack.h                            |   8 +-
 src/CBot/CMakeLists.txt                         |   2 +-
 12 files changed, 267 insertions(+), 287 deletions(-)

diff --git a/src/CBot/CBotCStack.cpp b/src/CBot/CBotCStack.cpp
index a524260..4866abb 100644
--- a/src/CBot/CBotCStack.cpp
+++ b/src/CBot/CBotCStack.cpp
@@ -22,7 +22,7 @@
 #include "CBot/CBotCStack.h"
 
 #include "CBot/CBotToken.h"
-#include "CBot/CBotCall.h"
+#include "CBotExternalCall.h"
 
 #include "CBot/CBotVar/CBotVar.h"
 
@@ -351,7 +351,7 @@ CBotTypResult CBotCStack::CompileCall(CBotToken* &p, CBotVar** ppVars, long& nId
     nIdent = 0;
     CBotTypResult val(-1);
 
-    val = CBotCall::CompileCall(p, ppVars, this, nIdent);
+    val = CBotExternalCallList::CompileCall(p, ppVars, this);
     if (val.GetType() < 0)
     {
         val = m_prog->GetFunctions()->CompileCall(p->GetString(), ppVars, nIdent);
@@ -371,7 +371,7 @@ bool CBotCStack::CheckCall(CBotToken* &pToken, CBotDefParam* pParam)
 {
     std::string    name = pToken->GetString();
 
-    if ( CBotCall::CheckCall(name) ) return true;
+    if ( CBotExternalCallList::CheckCall(name) ) return true;
 
     CBotFunction*    pp = m_prog->GetFunctions();
     while ( pp != nullptr )
diff --git a/src/CBot/CBotCall.h b/src/CBot/CBotCall.h
deleted file mode 100644
index 122a17e..0000000
--- a/src/CBot/CBotCall.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * This file is part of the Colobot: Gold Edition source code
- * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
- * http://epsitec.ch; http://colobot.info; http://github.com/colobot
- *
- * 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
- */
-
-#pragma once
-
-#include "CBot/CBotUtils.h"
-#include "CBot/CBotEnums.h"
-#include "CBot/CBotDefines.h"
-
-#include <string>
-#include <map>
-#include <memory>
-
-class CBotStack;
-class CBotCStack;
-class CBotVar;
-class CBotTypResult;
-class CBotToken;
-
-/**
- * \brief Class used for external calls
- *
- * \see CBotProgram::AddFunction() for information on how to add your functions to this list
- */
-class CBotCall : public CBotLinkedList<CBotCall>
-{
-public:
-    typedef bool (*RuntimeFunc)(CBotVar* args, CBotVar* result, int& exception, void* user);
-    typedef CBotTypResult (*CompileFunc)(CBotVar*& args, void* user);
-
-    /**
-     * \brief Constructor
-     * \param name Function name
-     * \param rExec Runtime function
-     * \param rCompile Compilation function
-     * \see CBotProgram::AddFunction()
-     */
-    CBotCall(const std::string& name, RuntimeFunc rExec, CompileFunc rCompile);
-
-    /**
-     * \brief Destructor
-     */
-    ~CBotCall();
-
-    /**
-     * \brief Add a new function to the list
-     * \param name Function name
-     * \param rExec Runtime function
-     * \param rCompile Compilation function
-     * \return true
-     */
-    static bool AddFunction(const std::string& name, RuntimeFunc rExec, CompileFunc rCompile);
-
-    /**
-     * \brief Find and call compile function
-     *
-     * \todo Document
-     */
-    static CBotTypResult CompileCall(CBotToken* &p, CBotVar** ppVars, CBotCStack* pStack, long& nIdent);
-
-    /**
-     * \brief Check if function with given name has been defined
-     * \param name Name to check
-     * \return true if function was defined
-     */
-    static bool CheckCall(const std::string& name);
-
-    /**
-     * \brief Find and call runtime function
-     *
-     * \todo Document
-     */
-    static int DoCall(long& nIdent, CBotToken* token, CBotVar** ppVars, CBotStack* pStack, CBotTypResult& rettype);
-
-    /**
-     * \brief Execute the runtime function
-     * \param pStack Stack to execute the function on
-     * \return false if function requested interruption, true otherwise
-     */
-    bool Run(CBotStack* pStack);
-
-    /**
-     * \brief Restore execution status after loading saved state
-     *
-     * \todo Document
-     */
-    static bool RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack);
-
-    /**
-     * \brief Set user pointer to pass to compile/runtime functions
-     * \param pUser User pointer
-     */
-    static void SetUserPtr(void* pUser);
-
-    /**
-     * \brief Reset the list of registered functions
-     */
-    static void Clear();
-
-private:
-    static std::map<std::string, std::unique_ptr<CBotCall>> m_list;
-    static void* m_user;
-
-    long m_ident;
-    std::string m_name;
-    RuntimeFunc m_rExec;
-    CompileFunc m_rComp;
-};
diff --git a/src/CBot/CBotCallMethode.cpp b/src/CBot/CBotCallMethode.cpp
index a947dee..474b1cf 100644
--- a/src/CBot/CBotCallMethode.cpp
+++ b/src/CBot/CBotCallMethode.cpp
@@ -39,7 +39,6 @@ CBotCallMethode::CBotCallMethode(const std::string& name,
     m_name       = name;
     m_rExec      = rExec;
     m_rComp      = rCompile;
-    m_nFuncIdent = CBotVar::NextUniqNum();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -48,14 +47,10 @@ CBotCallMethode::~CBotCallMethode()
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotTypResult CBotCallMethode::CompileCall(const std::string& name,
-                                           CBotVar* pThis,
-                                           CBotVar** ppVar,
-                                           CBotCStack* pStack,
-                                           long& nIdent)
+CBotTypResult CBotCallMethode::CompileCall(const std::string& name, CBotVar* pThis, CBotVar** ppVar,
+                                           CBotCStack* pStack)
 {
     CBotCallMethode*    pt = this;
-    nIdent = 0;
 
     while ( pt != nullptr )
     {
@@ -70,7 +65,6 @@ CBotTypResult CBotCallMethode::CompileCall(const std::string& name,
                 if (pVar2) pStack->SetError(static_cast<CBotError>(ret), pVar2->GetToken());
             }
             delete pVar;
-            nIdent = pt->m_nFuncIdent;
             return r;
         }
         pt = pt->m_next;
@@ -79,55 +73,11 @@ CBotTypResult CBotCallMethode::CompileCall(const std::string& name,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string CBotCallMethode::GetName()
-{
-    return  m_name;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-int CBotCallMethode::DoCall(long& nIdent,
-                            const std::string& name,
-                            CBotVar* pThis,
-                            CBotVar** ppVars,
-                            CBotVar*& pResult,
-                            CBotStack* pStack,
-                            CBotToken* pToken)
+int CBotCallMethode::DoCall(const std::string& name, CBotVar* pThis, CBotVar** ppVars, CBotVar*& pResult,
+                            CBotStack* pStack, CBotToken* pToken)
 {
     CBotCallMethode*    pt = this;
 
-    // search by the identifier
-
-    if ( nIdent ) while ( pt != nullptr )
-    {
-        if ( pt->m_nFuncIdent == nIdent )
-        {
-            // lists the parameters depending on the contents of the stack (pStackVar)
-
-            CBotVar*    pVar = MakeListVars(ppVars, true);
-            CBotVar*    pVarToDelete = pVar;
-
-            // then calls the routine external to the module
-
-            int         Exception = 0; // TODO: Change this to CBotError
-            int res = pt->m_rExec(pThis, pVar, pResult, Exception, pStack->GetPUser());
-            pStack->SetVar(pResult);
-
-            if (res == false)
-            {
-                if (Exception!=0)
-                {
-//                  pStack->SetError(Exception, pVar->GetToken());
-                    pStack->SetError(static_cast<CBotError>(Exception), pToken);
-                }
-                delete pVarToDelete;
-                return false;
-            }
-            delete pVarToDelete;
-            return true;
-        }
-        pt = pt->m_next;
-    }
-
     // search by name
 
     while ( pt != nullptr )
@@ -154,7 +104,6 @@ int CBotCallMethode::DoCall(long& nIdent,
                 return false;
             }
             delete pVarToDelete;
-            nIdent = pt->m_nFuncIdent;
             return true;
         }
         pt = pt->m_next;
diff --git a/src/CBot/CBotCallMethode.h b/src/CBot/CBotCallMethode.h
index 6eefd3f..85d9985 100644
--- a/src/CBot/CBotCallMethode.h
+++ b/src/CBot/CBotCallMethode.h
@@ -60,11 +60,8 @@ public:
      * \param nIdent
      * \return
      */
-    CBotTypResult CompileCall(const std::string& name,
-                              CBotVar* pThis,
-                              CBotVar** ppVars,
-                              CBotCStack* pStack,
-                              long& nIdent);
+    CBotTypResult CompileCall(const std::string& name, CBotVar* pThis, CBotVar** ppVars,
+                              CBotCStack* pStack);
 
     /*!
      * \brief DoCall
@@ -77,26 +74,13 @@ public:
      * \param pFunc
      * \return
      */
-    int DoCall(long& nIdent,
-               const std::string& name,
-               CBotVar* pThis,
-               CBotVar** ppVars,
-               CBotVar*& pResult,
-               CBotStack* pStack,
-               CBotToken* pFunc);
-
-    /*!
-     * \brief GetName
-     * \return
-     */
-    std::string GetName();
+    int DoCall(const std::string& name, CBotVar* pThis, CBotVar** ppVars, CBotVar*& pResult,
+               CBotStack* pStack, CBotToken* pFunc);
 
 private:
     std::string m_name;
     bool (*m_rExec) (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user);
     CBotTypResult (*m_rComp) (CBotVar* pThis, CBotVar* &pVar);
     friend class CBotClass;
-    long m_nFuncIdent;
-
 };
 
diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp
index 7694742..32ce167 100644
--- a/src/CBot/CBotClass.cpp
+++ b/src/CBot/CBotClass.cpp
@@ -28,7 +28,7 @@
 #include "CBot/CBotInstr/CBotListArray.h"
 #include "CBot/CBotInstr/CBotEmpty.h"
 
-#include "CBot/CBotCall.h"
+#include "CBotExternalCall.h"
 #include "CBot/CBotStack.h"
 #include "CBot/CBotCStack.h"
 #include "CBot/CBotUtils.h"
@@ -337,7 +337,7 @@ bool CBotClass::AddFunction(const std::string& name,
 
     while ( p != nullptr )
     {
-        if ( name == p->GetName() )
+        if ( name == p->m_name )
         {
             if ( pp == nullptr ) m_pCalls = p->m_next;
             else              pp->m_next = p->m_next;
@@ -374,7 +374,7 @@ CBotTypResult CBotClass::CompileMethode(const std::string& name,
 
     // find the methods declared by AddFunction
 
-    CBotTypResult r = m_pCalls->CompileCall(name, pThis, ppParams, pStack, nIdent);
+    CBotTypResult r = m_pCalls->CompileCall(name, pThis, ppParams, pStack);
     if ( r.GetType() >= 0) return r;
 
     // find the methods declared by user
@@ -394,7 +394,7 @@ bool CBotClass::ExecuteMethode(long& nIdent,
                                CBotStack*& pStack,
                                CBotToken* pToken)
 {
-    int ret = m_pCalls->DoCall(nIdent, name, pThis, ppParams, pResult, pStack, pToken);
+    int ret = m_pCalls->DoCall(name, pThis, ppParams, pResult, pStack, pToken);
     if (ret>=0) return ret;
 
     ret = m_pMethod->DoCall(nIdent, name, pThis, ppParams, pStack, pToken, this);
@@ -402,7 +402,7 @@ bool CBotClass::ExecuteMethode(long& nIdent,
 
     if (m_pParent != nullptr)
     {
-        ret = m_pParent->m_pCalls->DoCall(nIdent, name, pThis, ppParams, pResult, pStack, pToken);
+        ret = m_pParent->m_pCalls->DoCall(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);
     }
@@ -500,7 +500,7 @@ bool CBotClass::CheckCall(CBotToken* &pToken,
 {
     std::string  name = pToken->GetString();
 
-    if ( CBotCall::CheckCall(name) ) return true;
+    if ( CBotExternalCallList::CheckCall(name) ) return true;
 
     CBotFunction*   pp = m_pMethod;
     while ( pp != nullptr )
diff --git a/src/CBot/CBotEnums.h b/src/CBot/CBotEnums.h
index e453ee3..6174439 100644
--- a/src/CBot/CBotEnums.h
+++ b/src/CBot/CBotEnums.h
@@ -49,7 +49,9 @@ enum CBotType
     CBotTypPointer      = 12, //!< Pointer to a class (::CBotTypClass or ::CBotTypIntrinsic)
     CBotTypNullPointer  = 13, //!< Null pointer
     CBotTypClass        = 15, //!< Class instance
-    CBotTypIntrinsic    = 16  //!< Intrinsic class instance
+    CBotTypIntrinsic    = 16, //!< Intrinsic class instance
+
+    CBotTypMAX = 20
 };
 
 /**
diff --git a/src/CBot/CBotCall.cpp b/src/CBot/CBotExternalCall.cpp
similarity index 61%
rename from src/CBot/CBotCall.cpp
rename to src/CBot/CBotExternalCall.cpp
index a141d55..864c26a 100644
--- a/src/CBot/CBotCall.cpp
+++ b/src/CBot/CBotExternalCall.cpp
@@ -17,7 +17,7 @@
  * along with this program. If not, see http://gnu.org/licenses
  */
 
-#include "CBot/CBotCall.h"
+#include "CBotExternalCall.h"
 
 #include "CBot/CBotToken.h"
 #include "CBot/CBotStack.h"
@@ -27,49 +27,34 @@
 #include "CBot/CBotVar/CBotVar.h"
 
 
-std::map<std::string, std::unique_ptr<CBotCall>> CBotCall::m_list = std::map<std::string, std::unique_ptr<CBotCall>>();
-void* CBotCall::m_user = nullptr;
+std::map<std::string, std::unique_ptr<CBotExternalCall>> CBotExternalCallList::m_list{};
+void* CBotExternalCallList::m_user = nullptr;
 
-CBotCall::CBotCall(const std::string& name, RuntimeFunc rExec, CompileFunc rCompile)
-{
-    m_name  = name;
-    m_rExec = rExec;
-    m_rComp = rCompile;
-    m_ident = CBotVar::NextUniqNum();
-}
-
-CBotCall::~CBotCall()
-{
-}
-
-void CBotCall::Clear()
+void CBotExternalCallList::Clear()
 {
     m_list.clear();
 }
 
-bool CBotCall::AddFunction(const std::string& name, RuntimeFunc rExec, CompileFunc rCompile)
+bool CBotExternalCallList::AddFunction(const std::string& name, std::unique_ptr<CBotExternalCall> call)
 {
-    m_list[name] = std::unique_ptr<CBotCall>(new CBotCall(name, rExec, rCompile));
+    m_list[name] = std::move(call);
     return true;
 }
 
-CBotTypResult CBotCall::CompileCall(CBotToken* &p, CBotVar** ppVar, CBotCStack* pStack, long& nIdent)
+CBotTypResult CBotExternalCallList::CompileCall(CBotToken*& p, CBotVar** ppVar, CBotCStack* pStack)
 {
-    nIdent = 0;
     if (m_list.count(p->GetString()) == 0)
         return -1;
 
-    CBotCall* pt = m_list[p->GetString()].get();
-    nIdent = pt->m_ident;
+    CBotExternalCall* pt = m_list[p->GetString()].get();
 
     std::unique_ptr<CBotVar> args = std::unique_ptr<CBotVar>(MakeListVars(ppVar));
-    CBotVar* var = args.get(); // TODO: This shouldn't be a reference
-    CBotTypResult r = pt->m_rComp(var, m_user);
+    CBotTypResult r = pt->Compile(args.get(), m_user);
 
     // if a class is returned, it is actually a pointer
     if (r.GetType() == CBotTypClass) r.SetType(CBotTypPointer);
 
-    if (r.GetType() > 20) // error?
+    if (r.GetType() > CBotTypMAX) // error?
     {
         pStack->SetError(static_cast<CBotError>(r.GetType()), p);
     }
@@ -77,46 +62,26 @@ CBotTypResult CBotCall::CompileCall(CBotToken* &p, CBotVar** ppVar, CBotCStack*
     return r;
 }
 
-void CBotCall::SetUserPtr(void* pUser)
+void CBotExternalCallList::SetUserPtr(void* pUser)
 {
     m_user = pUser;
 }
 
-bool CBotCall::CheckCall(const std::string& name)
+bool CBotExternalCallList::CheckCall(const std::string& name)
 {
     return m_list.count(name) > 0;
 }
 
-int CBotCall::DoCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack, CBotTypResult& rettype)
+int CBotExternalCallList::DoCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack, const CBotTypResult& rettype)
 {
-    CBotCall*   pt = nullptr;
-
-    if (nIdent > 0)
-    {
-        for (const auto& it : m_list)
-        {
-            if (it.second->m_ident == nIdent)
-            {
-                pt = it.second.get();
-            }
-        }
-    }
-
-    if (pt == nullptr)
-    {
-        if (token != nullptr)
-        {
-            if (m_list.count(token->GetString()) > 0)
-            {
-                pt = m_list[token->GetString()].get();
-                nIdent = pt->m_ident;
-            }
-        }
-    }
+    if (token == nullptr)
+        return -1;
 
-    if (pt == nullptr)
+    if (m_list.count(token->GetString()) == 0)
         return -1;
 
+    CBotExternalCall* pt = m_list[token->GetString()].get();
+
     CBotStack*  pile = pStack->AddStackEOX(pt);
     if (pile == EOX) return true;
 
@@ -133,16 +98,14 @@ int CBotCall::DoCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack*
 
     pile->SetError(CBotNoErr, token); // save token for the position in case of error
     return pt->Run(pStack);
-
 }
 
-bool CBotCall::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
+bool CBotExternalCallList::RestoreCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack)
 {
     if (m_list.count(token->GetString()) == 0)
         return false;
 
-    CBotCall* pt = m_list[token->GetString()].get();
-    nIdent = pt->m_ident;
+    CBotExternalCall* pt = m_list[token->GetString()].get();
 
     CBotStack*  pile = pStack->RestoreStackEOX(pt);
     if ( pile == nullptr ) return true;
@@ -151,7 +114,35 @@ bool CBotCall::RestoreCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBot
     return true;
 }
 
-bool CBotCall::Run(CBotStack* pStack)
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+CBotExternalCall::CBotExternalCall()
+{
+}
+
+CBotExternalCall::~CBotExternalCall()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+CBotExternalCallDefault::CBotExternalCallDefault(RuntimeFunc rExec, CompileFunc rCompile)
+: CBotExternalCall()
+{
+    m_rExec = rExec;
+    m_rComp = rCompile;
+}
+
+CBotExternalCallDefault::~CBotExternalCallDefault()
+{
+}
+
+CBotTypResult CBotExternalCallDefault::Compile(CBotVar* args, void* user)
+{
+    return m_rComp(args, user);
+}
+
+bool CBotExternalCallDefault::Run(CBotStack* pStack)
 {
     CBotStack*  pile = pStack->AddStackEOX(this);
     if ( pile == EOX ) return true;
diff --git a/src/CBot/CBotExternalCall.h b/src/CBot/CBotExternalCall.h
new file mode 100644
index 0000000..62b25b2
--- /dev/null
+++ b/src/CBot/CBotExternalCall.h
@@ -0,0 +1,179 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * 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
+ */
+
+#pragma once
+
+#include "CBot/CBotUtils.h"
+#include "CBot/CBotEnums.h"
+#include "CBot/CBotDefines.h"
+
+#include <string>
+#include <map>
+#include <memory>
+
+class CBotStack;
+class CBotCStack;
+class CBotVar;
+class CBotTypResult;
+class CBotToken;
+
+/**
+ * \brief Interface for external CBot calls
+ *
+ * \see CBotExternalCallList
+ * \see CBotExternalCallDefault
+ */
+class CBotExternalCall
+{
+public:
+    /**
+     * \brief Constructor
+     * \see CBotProgram::AddFunction()
+     */
+    CBotExternalCall();
+
+    /**
+     * \brief Destructor
+     */
+    virtual ~CBotExternalCall();
+
+    /**
+     * \brief Compile the function
+     *
+     * \param Arguments (only types!) passed to the function
+     * \param User pointer provided to CBotProgram::Compile()
+     */
+    virtual CBotTypResult Compile(CBotVar* args, void* user) = 0;
+
+    /**
+     * \brief Execute the function
+     *
+     * \param pStack Stack to execute the function on
+     * \return false to request program interruption, true otherwise
+     */
+    virtual bool Run(CBotStack* pStack) = 0;
+};
+
+/**
+ * \brief Default implementation of CBot external call, using compilation and runtime functions
+ */
+class CBotExternalCallDefault : public CBotExternalCall
+{
+public:
+    typedef bool (*RuntimeFunc)(CBotVar* args, CBotVar* result, int& exception, void* user);
+    typedef CBotTypResult (*CompileFunc)(CBotVar*& args, void* user);
+
+    /**
+     * \brief Constructor
+     * \param rExec Runtime function
+     * \param rCompile Compilation function
+     * \see CBotProgram::AddFunction()
+     */
+    CBotExternalCallDefault(RuntimeFunc rExec, CompileFunc rCompile);
+
+    /**
+     * \brief Destructor
+     */
+    virtual ~CBotExternalCallDefault();
+
+    virtual CBotTypResult Compile(CBotVar* args, void* user);
+    virtual bool Run(CBotStack* pStack);
+
+private:
+    RuntimeFunc m_rExec;
+    CompileFunc m_rComp;
+};
+
+
+/**
+ * \brief Class for mangaging CBot external calls
+ *
+ * \see CBotProgram::AddFunction() for information on how to add your functions to this list
+ */
+class CBotExternalCallList
+{
+public:
+    /**
+     * \brief Add a new function to the list
+     * \param name Function name
+     * \param call Function to add
+     * \return true
+     */
+    static bool AddFunction(const std::string& name, std::unique_ptr<CBotExternalCall> call);
+
+    /**
+     * \brief Find and call compile function
+     *
+     * This function sets an error in compilation stack in case of failure
+     *
+     * \param p Token representing the function name
+     * \param ppVars List of arguments (only types!)
+     * \param pStack Compilation stack
+     * \return CBotTypResult representing the return type of the function (::CBotTypVar), or an error (::CBotError)
+     */
+    static CBotTypResult CompileCall(CBotToken*& p, CBotVar** ppVars, CBotCStack* pStack);
+
+    /**
+     * \brief Check if function with given name has been defined
+     * \param name Name to check
+     * \return true if function was defined
+     */
+    static bool CheckCall(const std::string& name);
+
+    /**
+     * \brief Find and call runtime function
+     *
+     * This function sets an error in runtime stack in case of failure
+     *
+     * \param token Token representing the function name
+     * \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
+     */
+    static int DoCall(CBotToken* token, 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 pStack Runtime stack
+     * \return false on failure (e.g. function doesn't exist)
+     */
+    static bool RestoreCall(CBotToken* token, CBotVar** ppVar, CBotStack* pStack);
+
+    /**
+     * \brief Set user pointer to pass to compile functions
+     *
+     * This is for compile functions only, runtime functions use CBotStack::GetPUser()
+     *
+     * \param pUser User pointer
+     */
+    static void SetUserPtr(void* pUser);
+
+    /**
+     * \brief Reset the list of registered functions
+     */
+    static void Clear();
+
+private:
+    static std::map<std::string, std::unique_ptr<CBotExternalCall>> m_list;
+    static void* m_user;
+};
\ No newline at end of file
diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp
index 8961d9e..19c629e 100644
--- a/src/CBot/CBotProgram.cpp
+++ b/src/CBot/CBotProgram.cpp
@@ -19,7 +19,7 @@
 
 #include "CBot/CBotVar/CBotVar.h"
 
-#include "CBot/CBotCall.h"
+#include "CBotExternalCall.h"
 #include "CBot/CBotStack.h"
 #include "CBot/CBotCStack.h"
 #include "CBot/CBotClass.h"
@@ -77,7 +77,7 @@ bool CBotProgram::Compile(const std::string& program, std::vector<std::string>&
     CBotToken* p = tokens.get()->GetNext();                 // skips the first token (separator)
 
     pStack->SetProgram(this);                               // defined used routines
-    CBotCall::SetUserPtr(pUser);
+    CBotExternalCallList::SetUserPtr(pUser);
 
     // Step 2. Find all function and class definitions
     while ( pStack->IsOk() && p != nullptr && p->GetType() != 0)
@@ -312,8 +312,7 @@ bool CBotProgram::AddFunction(const std::string& name,
                               bool rExec(CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser),
                               CBotTypResult rCompile(CBotVar*& pVar, void* pUser))
 {
-    // stores pointers to the two functions
-    return CBotCall::AddFunction(name, rExec, rCompile);
+    return CBotExternalCallList::AddFunction(name, std::unique_ptr<CBotExternalCall>(new CBotExternalCallDefault(rExec, rCompile)));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -435,7 +434,7 @@ void CBotProgram::Init()
 ////////////////////////////////////////////////////////////////////////////////
 void CBotProgram::Free()
 {
-    CBotToken::ClearDefineNum() ;
-    CBotCall::Clear() ;
-    CBotClass::Free() ;
+    CBotToken::ClearDefineNum();
+    CBotExternalCallList::Clear();
+    CBotClass::Free();
 }
\ No newline at end of file
diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp
index 3387ef4..62accc2 100644
--- a/src/CBot/CBotStack.cpp
+++ b/src/CBot/CBotStack.cpp
@@ -19,7 +19,7 @@
 
 // Modules inlcude
 #include "CBot/CBotStack.h"
-#include "CBot/CBotCall.h"
+#include "CBotExternalCall.h"
 
 #include "CBot/CBotInstr/CBotFunction.h"
 
@@ -153,7 +153,7 @@ CBotStack* CBotStack::AddStack(CBotInstr* instr, UnknownEnumBlock bBlock)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotStack* CBotStack::AddStackEOX(CBotCall* instr, UnknownEnumBlock bBlock)
+CBotStack* CBotStack::AddStackEOX(CBotExternalCall* instr, UnknownEnumBlock bBlock)
 {
     if (m_next != nullptr)
     {
@@ -292,7 +292,7 @@ CBotStack* CBotStack::AddStack(CBotInstr* instr, bool bBlock)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotStack* CBotStack::AddStackEOX(CBotCall* instr, bool bBlock)
+CBotStack* CBotStack::AddStackEOX(CBotExternalCall* instr, bool bBlock)
 {
     if (m_next != nullptr)
     {
@@ -378,7 +378,7 @@ CBotStack* CBotStack::RestoreStack(CBotInstr* instr)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-CBotStack* CBotStack::RestoreStackEOX(CBotCall* instr)
+CBotStack* CBotStack::RestoreStackEOX(CBotExternalCall* instr)
 {
     CBotStack*     p = RestoreStack();
     p->m_call = instr;
@@ -619,7 +619,7 @@ void CBotStack::SetTimer(int n)
 ////////////////////////////////////////////////////////////////////////////////
 bool CBotStack::Execute()
 {
-    CBotCall*        instr = nullptr;                        // the most highest instruction
+    CBotExternalCall*        instr = nullptr;                        // the most highest instruction
     CBotStack*        pile;
 
     CBotStack*        p = this;
@@ -744,7 +744,7 @@ bool CBotStack::ExecuteCall(long& nIdent, CBotToken* token, CBotVar** ppVar, CBo
 
     // first looks by the identifier
 
-    res = CBotCall::DoCall(nIdent, nullptr, ppVar, this, rettype );
+    res = CBotExternalCallList::DoCall(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 = CBotCall::DoCall(nIdent, token, ppVar, this, rettype );
+    res = CBotExternalCallList::DoCall(token, 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 ( !CBotCall::RestoreCall(nIdent, token, ppVar, this) )
+    if ( !CBotExternalCallList::RestoreCall(token, ppVar, this))
         m_prog->GetFunctions()->RestoreCall(nIdent, token->GetString(), ppVar, this );
 }
 
diff --git a/src/CBot/CBotStack.h b/src/CBot/CBotStack.h
index ba82338..0c780fa 100644
--- a/src/CBot/CBotStack.h
+++ b/src/CBot/CBotStack.h
@@ -32,7 +32,7 @@
 
 // Forward declaration
 class CBotInstr;
-class CBotCall;
+class CBotExternalCall;
 class CBotVar;
 class CBotProgram;
 class CBotToken;
@@ -174,9 +174,9 @@ public:
 
 
     CBotStack*        AddStack(CBotInstr* instr = nullptr, UnknownEnumBlock bBlock = UnknownEnumBlock::UNKNOWN_FALSE);    // extends the stack
-    CBotStack*        AddStackEOX(CBotCall* instr = nullptr, UnknownEnumBlock bBlock = UnknownEnumBlock::UNKNOWN_FALSE);    // extends the stack
+    CBotStack*        AddStackEOX(CBotExternalCall* instr = nullptr, UnknownEnumBlock bBlock = UnknownEnumBlock::UNKNOWN_FALSE);    // extends the stack
     CBotStack*        RestoreStack(CBotInstr* instr = nullptr);
-    CBotStack*        RestoreStackEOX(CBotCall* instr = nullptr);
+    CBotStack*        RestoreStackEOX(CBotExternalCall* instr = nullptr);
 
     CBotStack*        AddStack2(UnknownEnumBlock bBlock = UnknownEnumBlock::UNKNOWN_FALSE);                        // extends the stack
     bool            Return(CBotStack* pFils);                            // transmits the result over
@@ -258,7 +258,7 @@ private:
 
     CBotInstr*        m_instr;                    // the corresponding instruction
     IsFunctionParam  m_bFunc;                    // an input of a function?
-    CBotCall*        m_call;                        // recovery point in a extern call
+    CBotExternalCall*        m_call;                        // recovery point in a extern call
     friend class    CBotTry;
 };
 
diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt
index 0a89055..62a944f 100644
--- a/src/CBot/CMakeLists.txt
+++ b/src/CBot/CMakeLists.txt
@@ -6,7 +6,7 @@ set(SOURCES
         CBotStack.cpp
         CBotCStack.cpp
         CBotToken.cpp
-        CBotCall.cpp
+        CBotExternalCall.cpp
         CBotDefParam.cpp
         CBotCallMethode.cpp
         CBotTypResult.cpp

-- 
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