讓我們把KBEngine玩壞吧!如何定製我們自己的C++函數(一)

爲什麼不更新kbe warring的代碼解讀了,因爲在我看來那個demo講完了實體就沒東西可講了,如果專心的看官方文檔和PPT的話demo的代碼後面沒任何難點了已經,單純的複製黏貼代碼實在太過無聊。程序員一定要做點好玩的事情才行~

好吧,今天開始想法直接改引擎底層,爭取把引擎底層直接玩壞(*^__^*) 

另外因爲平時工作比較忙,這個系列會不定期的更新。

從自己的HelloWorld寫起

先來點簡單的,baseapp腳本層調用一個自定義的C++函數,輸出helloworld!

因爲是baseapp的特有C++函數,所以我們需要打開baseapp項目的文件進行修改,這裏我選baseapp.h和baseapp.cpp

爲避免複製黏貼多餘的代碼,所以只寫核心部分

baseapp.h

複製代碼

class Baseapp :    public EntityApp<Base>, 
                public Singleton<Baseapp>
{
public:
    //added by lsm
    static PyObject* __py_findAvatarByName(PyObject* self, PyObject* args);
protected:
}

複製代碼

baseapp.cpp

複製代碼

//-------------------------------------------------------------------------------------
bool Baseapp::installPyModules()
{
    Base::installScript(getScript().getModule());
    Proxy::installScript(getScript().getModule());
    GlobalDataClient::installScript(getScript().getModule());

    registerScript(Base::getScriptType());
    registerScript(Proxy::getScriptType());

    // 將app標記註冊到腳本
    std::map<uint32, std::string> flagsmaps = createAppFlagsMaps();
    std::map<uint32, std::string>::iterator fiter = flagsmaps.begin();
    for (; fiter != flagsmaps.end(); ++fiter)
    {
        if (PyModule_AddIntConstant(getScript().getModule(), fiter->second.c_str(), fiter->first))
        {
            ERROR_MSG(fmt::format("Baseapp::onInstallPyModules: Unable to set KBEngine.{}.\n", fiter->second));
        }
    }

    // 註冊創建entity的方法到py 
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        time,                            __py_gametime,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBase,                        __py_createBase,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBaseLocally,                __py_createBase,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createEntity,                    __py_createBase,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         createBaseAnywhere,                __py_createBaseAnywhere,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBaseRemotely,                __py_createBaseRemotely,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         createBaseFromDBID,                __py_createBaseFromDBID,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         createBaseAnywhereFromDBID,        __py_createBaseAnywhereFromDBID,                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBaseRemotelyFromDBID,        __py_createBaseRemotelyFromDBID,                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         executeRawDatabaseCommand,        __py_executeRawDatabaseCommand,                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         quantumPassedPercent,            __py_quantumPassedPercent,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         charge,                            __py_charge,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         registerReadFileDescriptor,        PyFileDescriptor::__py_registerReadFileDescriptor,            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         registerWriteFileDescriptor,    PyFileDescriptor::__py_registerWriteFileDescriptor,            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         deregisterReadFileDescriptor,    PyFileDescriptor::__py_deregisterReadFileDescriptor,        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         deregisterWriteFileDescriptor,    PyFileDescriptor::__py_deregisterWriteFileDescriptor,        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        reloadScript,                    __py_reloadScript,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        isShuttingDown,                    __py_isShuttingDown,                                        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        address,                        __py_address,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        deleteBaseByDBID,                __py_deleteBaseByDBID,                                        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        lookUpBaseByDBID,                __py_lookUpBaseByDBID,                                        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         setAppFlags,                    __py_setFlags,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         getAppFlags,                    __py_getFlags,                                                METH_VARARGS,            0);
    //addition by lsm
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        testfunc,                        __py_findAvatarByName,                                        METH_VARARGS,            0);
        
    return EntityApp<Base>::installPyModules();
}

//added by lsm
//Email:[email protected]
//Description:某些自用的函數
//-------------------------------------------------------------------------------------
PyObject* Baseapp::__py_findAvatarByName(PyObject* self, PyObject* args)
{
    PyObject* pyval = NULL;
    std::string strTest = "HelloWorld!This is my first test cpp function!!--Lsm";
    pyval = PyUnicode_FromString(strTest.c_str());
    return pyval;
}

複製代碼

然後我們就能用官方自帶的調試工具驗證我們的成果了~!

 

輸出某類實體

一般來說,C++效率是python的50-1000倍,所以如果遇到比較耗時的操作我們需要放到C++部分進行運算。另外引擎自己提供的api有些時候不能滿足我們自己的需求,這個時候就需要我們來實現自己的需求了。

寫點稍微有用的,kbe自帶的api沒有辦法直接輸出某類實體,那麼我們製作一個自己的api,輸出某類實體。

和上個方法類似,首先頭文件定義

Baseapp.h

複製代碼

class Baseapp :    public EntityApp<Base>, 
                public Singleton<Baseapp>
{
public:
    //added by lsm
    static PyObject* __py_testfunc(PyObject* self, PyObject* args);
    static PyObject* __py_findEntityByName(PyObject* self, PyObject* args);
protected:
}

複製代碼

Baseapp.cpp

複製代碼

//-------------------------------------------------------------------------------------
bool Baseapp::installPyModules()
{
    Base::installScript(getScript().getModule());
    Proxy::installScript(getScript().getModule());
    GlobalDataClient::installScript(getScript().getModule());

    registerScript(Base::getScriptType());
    registerScript(Proxy::getScriptType());

    // 將app標記註冊到腳本
    std::map<uint32, std::string> flagsmaps = createAppFlagsMaps();
    std::map<uint32, std::string>::iterator fiter = flagsmaps.begin();
    for (; fiter != flagsmaps.end(); ++fiter)
    {
        if (PyModule_AddIntConstant(getScript().getModule(), fiter->second.c_str(), fiter->first))
        {
            ERROR_MSG(fmt::format("Baseapp::onInstallPyModules: Unable to set KBEngine.{}.\n", fiter->second));
        }
    }

    // 註冊創建entity的方法到py 
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        time,                            __py_gametime,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBase,                        __py_createBase,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBaseLocally,                __py_createBase,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createEntity,                    __py_createBase,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         createBaseAnywhere,                __py_createBaseAnywhere,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBaseRemotely,                __py_createBaseRemotely,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         createBaseFromDBID,                __py_createBaseFromDBID,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         createBaseAnywhereFromDBID,        __py_createBaseAnywhereFromDBID,                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        createBaseRemotelyFromDBID,        __py_createBaseRemotelyFromDBID,                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         executeRawDatabaseCommand,        __py_executeRawDatabaseCommand,                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         quantumPassedPercent,            __py_quantumPassedPercent,                                    METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         charge,                            __py_charge,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         registerReadFileDescriptor,        PyFileDescriptor::__py_registerReadFileDescriptor,            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         registerWriteFileDescriptor,    PyFileDescriptor::__py_registerWriteFileDescriptor,            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         deregisterReadFileDescriptor,    PyFileDescriptor::__py_deregisterReadFileDescriptor,        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         deregisterWriteFileDescriptor,    PyFileDescriptor::__py_deregisterWriteFileDescriptor,        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        reloadScript,                    __py_reloadScript,                                            METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        isShuttingDown,                    __py_isShuttingDown,                                        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        address,                        __py_address,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        deleteBaseByDBID,                __py_deleteBaseByDBID,                                        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        lookUpBaseByDBID,                __py_lookUpBaseByDBID,                                        METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         setAppFlags,                    __py_setFlags,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),         getAppFlags,                    __py_getFlags,                                                METH_VARARGS,            0);
    //addition by lsm
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        testfunc,                        __py_testfunc,                                                METH_VARARGS,            0);
    APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(),        findEntityByName,                __py_findEntityByName,                                        METH_VARARGS,            0);
        
    return EntityApp<Base>::installPyModules();
}

複製代碼

下面是方法的具體實現

複製代碼

PyObject* Baseapp::__py_findEntityByName(PyObject* self, PyObject* args)
{
    //首先讀取參數
    int argCount = (int)PyTuple_Size(args);
    if (argCount != 1)
    {
        PyErr_Format(PyExc_TypeError, "KBEngine::findEntityByName(): args is error!");
        PyErr_PrintEx(0);
        return 0;
    }

    char* entity_name = NULL;

    if (PyArg_ParseTuple(args, "s", &entity_name) == -1)
    {
        PyErr_Format(PyExc_TypeError, "KBEngine::findEntityByName(): args is error!");
        PyErr_PrintEx(0);
        return 0;
    }
    //獲取實體列表
    Entities<Base>::ENTITYS_MAP& entities = Baseapp::getSingletonPtr()->pEntities()->getEntities();
    Entities<Base>::ENTITYS_MAP::const_iterator iter = entities.begin();
    //先遍歷獲取返回值大小
    int entity_size = 0;
    while (iter != entities.end())
    {
        PyObject* entity = static_cast<PyObject*>(iter->second.get());
        //如果名字和實體名相同
        if (strcmp(entity->ob_type->tp_name, entity_name) == 0) {
            entity_size++;
        }
        iter++;
    }
    //第二次遍歷獲取具體返回值
    iter = entities.begin();
    PyObject* pyList = PyList_New(entity_size);
    int i = 0;
    while (iter != entities.end())
    {
        PyObject * pTuple = PyTuple_New(2);
        PyObject* entityID = PyLong_FromLong(iter->first);
        PyObject* entity = static_cast<PyObject*>(iter->second.get());
        //如果名字和實體名相同
        if (strcmp(entity->ob_type->tp_name, entity_name) == 0) {
            Py_INCREF(entity);
            PyTuple_SET_ITEM(pTuple, 0, entityID);
            PyTuple_SET_ITEM(pTuple, 1, entity);
            PyList_SET_ITEM(pyList, i, pTuple);
            i++;
        }
        iter++;
    }

    return pyList;
}

複製代碼

最終效果如下圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章