让我们把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, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBase, __py_createBase, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseLocally, __py_createBase, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createEntity, __py_createBase, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhere, __py_createBaseAnywhere, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotely, __py_createBaseRemotely, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseFromDBID, __py_createBaseFromDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhereFromDBID, __py_createBaseAnywhereFromDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotelyFromDBID, __py_createBaseRemotelyFromDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), executeRawDatabaseCommand, __py_executeRawDatabaseCommand, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), quantumPassedPercent, __py_quantumPassedPercent, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), charge, __py_charge, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerReadFileDescriptor, PyFileDescriptor::__py_registerReadFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerWriteFileDescriptor, PyFileDescriptor::__py_registerWriteFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterReadFileDescriptor, PyFileDescriptor::__py_deregisterReadFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterWriteFileDescriptor, PyFileDescriptor::__py_deregisterWriteFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), reloadScript, __py_reloadScript, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), isShuttingDown, __py_isShuttingDown, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), address, __py_address, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deleteBaseByDBID, __py_deleteBaseByDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), lookUpBaseByDBID, __py_lookUpBaseByDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), setAppFlags, __py_setFlags, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), getAppFlags, __py_getFlags, METH_VARARGS, );
- //addition by lsm
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), testfunc, __py_findAvatarByName, METH_VARARGS, );
- 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.{}.\n", fiter->second));
- }
- }
- // 注册创建entity的方法到py
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), time, __py_gametime, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBase, __py_createBase, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseLocally, __py_createBase, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createEntity, __py_createBase, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhere, __py_createBaseAnywhere, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotely, __py_createBaseRemotely, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseFromDBID, __py_createBaseFromDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhereFromDBID, __py_createBaseAnywhereFromDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotelyFromDBID, __py_createBaseRemotelyFromDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), executeRawDatabaseCommand, __py_executeRawDatabaseCommand, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), quantumPassedPercent, __py_quantumPassedPercent, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), charge, __py_charge, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerReadFileDescriptor, PyFileDescriptor::__py_registerReadFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerWriteFileDescriptor, PyFileDescriptor::__py_registerWriteFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterReadFileDescriptor, PyFileDescriptor::__py_deregisterReadFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterWriteFileDescriptor, PyFileDescriptor::__py_deregisterWriteFileDescriptor, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), reloadScript, __py_reloadScript, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), isShuttingDown, __py_isShuttingDown, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), address, __py_address, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deleteBaseByDBID, __py_deleteBaseByDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), lookUpBaseByDBID, __py_lookUpBaseByDBID, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), setAppFlags, __py_setFlags, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), getAppFlags, __py_getFlags, METH_VARARGS, );
- //addition by lsm
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), testfunc, __py_testfunc, METH_VARARGS, );
- APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), findEntityByName, __py_findEntityByName, METH_VARARGS, );
- return EntityApp<Base>::installPyModules();
- }
下面是方法的具体实现
- PyObject* Baseapp::__py_findEntityByName(PyObject* self, PyObject* args)
- {
- //首先读取参数
- int argCount = (int)PyTuple_Size(args);
- if (argCount != )
- {
- PyErr_Format(PyExc_TypeError, "KBEngine::findEntityByName(): args is error!");
- PyErr_PrintEx();
- return ;
- }
- char* entity_name = NULL;
- if (PyArg_ParseTuple(args, "s", &entity_name) == -)
- {
- PyErr_Format(PyExc_TypeError, "KBEngine::findEntityByName(): args is error!");
- PyErr_PrintEx();
- return ;
- }
- //获取实体列表
- Entities<Base>::ENTITYS_MAP& entities = Baseapp::getSingletonPtr()->pEntities()->getEntities();
- Entities<Base>::ENTITYS_MAP::const_iterator iter = entities.begin();
- //先遍历获取返回值大小
- int entity_size = ;
- while (iter != entities.end())
- {
- PyObject* entity = static_cast<PyObject*>(iter->second.get());
- //如果名字和实体名相同
- if (strcmp(entity->ob_type->tp_name, entity_name) == ) {
- entity_size++;
- }
- iter++;
- }
- //第二次遍历获取具体返回值
- iter = entities.begin();
- PyObject* pyList = PyList_New(entity_size);
- int i = ;
- while (iter != entities.end())
- {
- PyObject * pTuple = PyTuple_New();
- PyObject* entityID = PyLong_FromLong(iter->first);
- PyObject* entity = static_cast<PyObject*>(iter->second.get());
- //如果名字和实体名相同
- if (strcmp(entity->ob_type->tp_name, entity_name) == ) {
- Py_INCREF(entity);
- PyTuple_SET_ITEM(pTuple, , entityID);
- PyTuple_SET_ITEM(pTuple, , entity);
- PyList_SET_ITEM(pyList, i, pTuple);
- i++;
- }
- iter++;
- }
- return pyList;
- }
最终效果如下图
让我们把KBEngine玩坏吧!如何定制我们自己的C++函数(一)的更多相关文章
- 漫谈可视化Prefuse(四)---被玩坏的Prefuse API
这个双12,别人都在抢红包.逛淘宝.上京东,我选择再续我的“漫谈可视化”系列(好了,不装了,其实是郎中羞涩...) 上篇<漫谈可视化Prefuse(三)---Prefuse API数据结构阅读有 ...
- JS魔法堂:被玩坏的innerHTML、innerText、textContent和value属性
一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替,但它两者 ...
- 玩坏JVM很简单--toString的递归调用
在JVM的内存管理机制下很少发生内存溢出的情况.至少我碰见的少,好像在SSH我多次发布项目时候出现过一次.今天看见一个特简单的方法让内存溢出(好吧,我似乎作死了--!): public class I ...
- Github 恶搞教程(一起『玩坏』自己的 Github 吧)
最近在伯乐在线读到一篇趣文,<如何在 Github『正确』做贡献>,里面各种能人恶搞 Github 的『Public contributions』,下面截取几个小伙伴的战绩: 顺藤摸瓜,发 ...
- .CO域名快被这帮搞IT的玩坏了……
鉴于近来国内访问Google的服务受阻,greatfire.org于前天推出了其基于亚马逊AWS的Google搜索镜像网站,地址是sinaapp.co.该网站随后因多家海外媒体的报道和众多微博大V的转 ...
- [转]被玩坏的innerHTML、innerText、textContent和value属性
一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它,一般情况下我们可以使用textContent来代替,但它两者是否就能完全等同呢?在坑爹的表单元素(如input ...
- 千亿VR市场 将被国内厂商玩坏多少?
将被国内厂商玩坏多少?" title="千亿VR市场 将被国内厂商玩坏多少?"> 智能硬件行业在不断寻求新的突破口,当智能手机.平板.电视.家电等都司空见惯之后,能 ...
- 千万别把WIFI玩坏了!关于WIFI的新鲜玩法和商业模式探讨
使用WIFI作为无线上网接入,也许大家都比较习以为常的.但是你们知道吗,其实WIFI还有很多种玩法:基于WIFI的身份识别,WIFI感知,WIFI Direct等等.今天我们会着重介绍一种WIFI的有 ...
- 无语啊,sublime给我弄乱玩,玩坏了,而且安装插件也安装不了
国内的什么插件地址都TMMD失效了,没办法,只能翻"强"到外面找了,而且找了很多也用不了,所以收藏一个为了预防以后不行有补救的方法: 百度的99%都不行,不是报这个错就是那个错,可 ...
随机推荐
- VIsual Studio 2010 常用快捷键
1.Ctrl+S 保存 2.Ctrl+F: 查找 3.Ctrl+H: 替换 4.Ctrl+E,S: 查看空白 5.Ctrl+K+C: 注释选定内容 6.Ctrl+K+U: 取消选定注释内容 7.C ...
- 元素(Element)和结点(Node)的区别(org.w3c.dom)
1.元素(Element)和结点(Node)的区别, 元素是一个小范围的定义,必须是含有完整信息的结点才是一个元素,例如 - . 但是一个结点不一定是一个元素,而一个元素一定是一个结点. 什么是nod ...
- 【总结整理】JQuery小技巧
var item=$("#content").find(".item");//效率最高 var item=$("#content .item" ...
- Windows 8 64位系统 在VS2010 32位软件上 搭建 PCL点云库 开发环境
Windows 8 64位系统 在VS2010 32位软件上 搭建 PCL点云库 开发环境 下载PCL For windows 软件包 到这个网站下载PCL-All-In-One Installer: ...
- Java学习之多态(Polymorphism)
多态==晚绑定 不要把函数重载理解为多态. 因为多态是一种运行期的行为,不是编译期的行为. 多态:父类型的引用可以指向子类型的对象. 比如 Parent p = new Child(); 当使用多态方 ...
- 诺基亚 920T - 我的非凡系列手机始终显示旋转齿轮而无响应,我该如何让手机停止显示旋转齿轮?
有时,在 OTA 更新 (或重置手机) 后,设备可能始终显示“旋转齿轮”而无响应. 如果“旋转齿轮”在屏幕上显示的时间超过 60 分钟,则需要执行恢复操作. 您可以尝试下面这些简单的解决方法: 按住电 ...
- 解决IIS出现的问题
- python学习笔记11 ----线程、进程、协程
进程.线程.协程的概念 进程和线程是操作系统中两个很重要的概念,对于一般的程序,可能有若干个进程,每一个进程有若干个同时执行的线程.进程是资源管理的最小单位,线程是程序执行的最小单位(线程可共享同一进 ...
- SQL Server列属性修改
0.创建表 create table Users(Id int,Name nvarchar(32) not null,Phone nvarchar(16),Email nvarchar(128)) 1 ...
- [CentOS7] 设置开机启动方式(图形界面或命令行)
由于CenOS之前一直都是通过修改inittab文件来修改开机启动模式,于是 通过 vim /etc/inittab 打开inittab来查看 如上所示,CentOS 7由于使用systemd而不是i ...