zoukankan      html  css  js  c++  java
  • 让我们把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.{}.
    ", 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;
    }

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

    输出某类实体

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

    最终效果如下图

  • 相关阅读:
    回顾[2007-09-03 12:58:03]
    关于知音[2007-08-17 20:56:06]
    今天晚上吃散伙饭[2007-06-18 00:24:36]
    上次所料不错[2007-06-13 15:44:47]
    今天真没劲[2007-06-10 17:50:25]
    关于昨晚的梦[2007-05-07 12:12:06]
    iOS 自定义键盘
    iOSQuart2D绘图之UIImage简单使用
    iOS 两种不同的图片无限轮播
    iOS 简单引导界面
  • 原文地址:https://www.cnblogs.com/lsm19870508/p/7028886.html
Copyright © 2011-2022 走看看