让我们把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:240782361@qq.com
//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;
}

然后我们就能用官方自带的调试工具验证我们的成果了~!

让我们把KBEngine玩坏吧!如何定制我们自己的C++函数(一)

输出某类实体

一般来说,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;
}

最终效果如下图

让我们把KBEngine玩坏吧!如何定制我们自己的C++函数(一)

原文链接: https://www.cnblogs.com/lsm19870508/p/7028886.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/255434

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午8:50
下一篇 2023年2月14日 上午8:51

相关推荐