为什么不更新kbe warring的代码解读了,因为在我看来那个demo讲完了实体就没东西可讲了,如果专心的看官方文档和PPT的话demo的代码后面没任何难点了已经,单纯的复制黏贴代码实在太过无聊。程序员一定要做点好玩的事情才行~

好吧,今天开始想法直接改引擎底层,争取把引擎底层直接玩坏(*^__^*)

另外因为平时工作比较忙,这个系列会不定期的更新。

从自己的HelloWorld写起

先来点简单的,baseapp脚本层调用一个自定义的C++函数,输出helloworld!

因为是baseapp的特有C++函数,所以我们需要打开baseapp项目的文件进行修改,这里我选baseapp.h和baseapp.cpp

为避免复制黏贴多余的代码,所以只写核心部分

baseapp.h

  1. class Baseapp : public EntityApp<Base>,
  2. public Singleton<Baseapp>
  3. {
  4. public:
  5. //added by lsm
  6. static PyObject* __py_findAvatarByName(PyObject* self, PyObject* args);
  7. protected:
  8. }

baseapp.cpp

  1. //-------------------------------------------------------------------------------------
  2. bool Baseapp::installPyModules()
  3. {
  4. Base::installScript(getScript().getModule());
  5. Proxy::installScript(getScript().getModule());
  6. GlobalDataClient::installScript(getScript().getModule());
  7.  
  8. registerScript(Base::getScriptType());
  9. registerScript(Proxy::getScriptType());
  10.  
  11. // 将app标记注册到脚本
  12. std::map<uint32, std::string> flagsmaps = createAppFlagsMaps();
  13. std::map<uint32, std::string>::iterator fiter = flagsmaps.begin();
  14. for (; fiter != flagsmaps.end(); ++fiter)
  15. {
  16. if (PyModule_AddIntConstant(getScript().getModule(), fiter->second.c_str(), fiter->first))
  17. {
  18. ERROR_MSG(fmt::format("Baseapp::onInstallPyModules: Unable to set KBEngine.{}.\n", fiter->second));
  19. }
  20. }
  21.  
  22. // 注册创建entity的方法到py
  23. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), time, __py_gametime, METH_VARARGS, );
  24. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBase, __py_createBase, METH_VARARGS, );
  25. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseLocally, __py_createBase, METH_VARARGS, );
  26. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createEntity, __py_createBase, METH_VARARGS, );
  27. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhere, __py_createBaseAnywhere, METH_VARARGS, );
  28. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotely, __py_createBaseRemotely, METH_VARARGS, );
  29. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseFromDBID, __py_createBaseFromDBID, METH_VARARGS, );
  30. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhereFromDBID, __py_createBaseAnywhereFromDBID, METH_VARARGS, );
  31. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotelyFromDBID, __py_createBaseRemotelyFromDBID, METH_VARARGS, );
  32. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), executeRawDatabaseCommand, __py_executeRawDatabaseCommand, METH_VARARGS, );
  33. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), quantumPassedPercent, __py_quantumPassedPercent, METH_VARARGS, );
  34. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), charge, __py_charge, METH_VARARGS, );
  35. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerReadFileDescriptor, PyFileDescriptor::__py_registerReadFileDescriptor, METH_VARARGS, );
  36. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerWriteFileDescriptor, PyFileDescriptor::__py_registerWriteFileDescriptor, METH_VARARGS, );
  37. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterReadFileDescriptor, PyFileDescriptor::__py_deregisterReadFileDescriptor, METH_VARARGS, );
  38. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterWriteFileDescriptor, PyFileDescriptor::__py_deregisterWriteFileDescriptor, METH_VARARGS, );
  39. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), reloadScript, __py_reloadScript, METH_VARARGS, );
  40. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), isShuttingDown, __py_isShuttingDown, METH_VARARGS, );
  41. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), address, __py_address, METH_VARARGS, );
  42. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deleteBaseByDBID, __py_deleteBaseByDBID, METH_VARARGS, );
  43. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), lookUpBaseByDBID, __py_lookUpBaseByDBID, METH_VARARGS, );
  44. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), setAppFlags, __py_setFlags, METH_VARARGS, );
  45. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), getAppFlags, __py_getFlags, METH_VARARGS, );
  46. //addition by lsm
  47. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), testfunc, __py_findAvatarByName, METH_VARARGS, );
  48.  
  49. return EntityApp<Base>::installPyModules();
  50. }
  51.  
  52. //added by lsm
  53. //Email:240782361@qq.com
  54. //Description:某些自用的函数
  55. //-------------------------------------------------------------------------------------
  56. PyObject* Baseapp::__py_findAvatarByName(PyObject* self, PyObject* args)
  57. {
  58. PyObject* pyval = NULL;
  59. std::string strTest = "HelloWorld!This is my first test cpp function!!--Lsm";
  60. pyval = PyUnicode_FromString(strTest.c_str());
  61. return pyval;
  62. }

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

输出某类实体

一般来说,C++效率是python的50-1000倍,所以如果遇到比较耗时的操作我们需要放到C++部分进行运算。另外引擎自己提供的api有些时候不能满足我们自己的需求,这个时候就需要我们来实现自己的需求了。

写点稍微有用的,kbe自带的api没有办法直接输出某类实体,那么我们制作一个自己的api,输出某类实体。

和上个方法类似,首先头文件定义

Baseapp.h

  1. class Baseapp : public EntityApp<Base>,
  2. public Singleton<Baseapp>
  3. {
  4. public:
  5. //added by lsm
  6. static PyObject* __py_testfunc(PyObject* self, PyObject* args);
  7. static PyObject* __py_findEntityByName(PyObject* self, PyObject* args);
  8. protected:
  9. }

Baseapp.cpp

  1. //-------------------------------------------------------------------------------------
  2. bool Baseapp::installPyModules()
  3. {
  4. Base::installScript(getScript().getModule());
  5. Proxy::installScript(getScript().getModule());
  6. GlobalDataClient::installScript(getScript().getModule());
  7.  
  8. registerScript(Base::getScriptType());
  9. registerScript(Proxy::getScriptType());
  10.  
  11. // 将app标记注册到脚本
  12. std::map<uint32, std::string> flagsmaps = createAppFlagsMaps();
  13. std::map<uint32, std::string>::iterator fiter = flagsmaps.begin();
  14. for (; fiter != flagsmaps.end(); ++fiter)
  15. {
  16. if (PyModule_AddIntConstant(getScript().getModule(), fiter->second.c_str(), fiter->first))
  17. {
  18. ERROR_MSG(fmt::format("Baseapp::onInstallPyModules: Unable to set KBEngine.{}.\n", fiter->second));
  19. }
  20. }
  21.  
  22. // 注册创建entity的方法到py
  23. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), time, __py_gametime, METH_VARARGS, );
  24. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBase, __py_createBase, METH_VARARGS, );
  25. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseLocally, __py_createBase, METH_VARARGS, );
  26. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createEntity, __py_createBase, METH_VARARGS, );
  27. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhere, __py_createBaseAnywhere, METH_VARARGS, );
  28. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotely, __py_createBaseRemotely, METH_VARARGS, );
  29. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseFromDBID, __py_createBaseFromDBID, METH_VARARGS, );
  30. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseAnywhereFromDBID, __py_createBaseAnywhereFromDBID, METH_VARARGS, );
  31. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), createBaseRemotelyFromDBID, __py_createBaseRemotelyFromDBID, METH_VARARGS, );
  32. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), executeRawDatabaseCommand, __py_executeRawDatabaseCommand, METH_VARARGS, );
  33. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), quantumPassedPercent, __py_quantumPassedPercent, METH_VARARGS, );
  34. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), charge, __py_charge, METH_VARARGS, );
  35. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerReadFileDescriptor, PyFileDescriptor::__py_registerReadFileDescriptor, METH_VARARGS, );
  36. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), registerWriteFileDescriptor, PyFileDescriptor::__py_registerWriteFileDescriptor, METH_VARARGS, );
  37. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterReadFileDescriptor, PyFileDescriptor::__py_deregisterReadFileDescriptor, METH_VARARGS, );
  38. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deregisterWriteFileDescriptor, PyFileDescriptor::__py_deregisterWriteFileDescriptor, METH_VARARGS, );
  39. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), reloadScript, __py_reloadScript, METH_VARARGS, );
  40. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), isShuttingDown, __py_isShuttingDown, METH_VARARGS, );
  41. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), address, __py_address, METH_VARARGS, );
  42. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), deleteBaseByDBID, __py_deleteBaseByDBID, METH_VARARGS, );
  43. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), lookUpBaseByDBID, __py_lookUpBaseByDBID, METH_VARARGS, );
  44. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), setAppFlags, __py_setFlags, METH_VARARGS, );
  45. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), getAppFlags, __py_getFlags, METH_VARARGS, );
  46. //addition by lsm
  47. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), testfunc, __py_testfunc, METH_VARARGS, );
  48. APPEND_SCRIPT_MODULE_METHOD(getScript().getModule(), findEntityByName, __py_findEntityByName, METH_VARARGS, );
  49.  
  50. return EntityApp<Base>::installPyModules();
  51. }

下面是方法的具体实现

  1. PyObject* Baseapp::__py_findEntityByName(PyObject* self, PyObject* args)
  2. {
  3. //首先读取参数
  4. int argCount = (int)PyTuple_Size(args);
  5. if (argCount != )
  6. {
  7. PyErr_Format(PyExc_TypeError, "KBEngine::findEntityByName(): args is error!");
  8. PyErr_PrintEx();
  9. return ;
  10. }
  11.  
  12. char* entity_name = NULL;
  13.  
  14. if (PyArg_ParseTuple(args, "s", &entity_name) == -)
  15. {
  16. PyErr_Format(PyExc_TypeError, "KBEngine::findEntityByName(): args is error!");
  17. PyErr_PrintEx();
  18. return ;
  19. }
  20. //获取实体列表
  21. Entities<Base>::ENTITYS_MAP& entities = Baseapp::getSingletonPtr()->pEntities()->getEntities();
  22. Entities<Base>::ENTITYS_MAP::const_iterator iter = entities.begin();
  23. //先遍历获取返回值大小
  24. int entity_size = ;
  25. while (iter != entities.end())
  26. {
  27. PyObject* entity = static_cast<PyObject*>(iter->second.get());
  28. //如果名字和实体名相同
  29. if (strcmp(entity->ob_type->tp_name, entity_name) == ) {
  30. entity_size++;
  31. }
  32. iter++;
  33. }
  34. //第二次遍历获取具体返回值
  35. iter = entities.begin();
  36. PyObject* pyList = PyList_New(entity_size);
  37. int i = ;
  38. while (iter != entities.end())
  39. {
  40. PyObject * pTuple = PyTuple_New();
  41. PyObject* entityID = PyLong_FromLong(iter->first);
  42. PyObject* entity = static_cast<PyObject*>(iter->second.get());
  43. //如果名字和实体名相同
  44. if (strcmp(entity->ob_type->tp_name, entity_name) == ) {
  45. Py_INCREF(entity);
  46. PyTuple_SET_ITEM(pTuple, , entityID);
  47. PyTuple_SET_ITEM(pTuple, , entity);
  48. PyList_SET_ITEM(pyList, i, pTuple);
  49. i++;
  50. }
  51. iter++;
  52. }
  53.  
  54. return pyList;
  55. }

最终效果如下图

让我们把KBEngine玩坏吧!如何定制我们自己的C++函数(一)的更多相关文章

  1. 漫谈可视化Prefuse(四)---被玩坏的Prefuse API

    这个双12,别人都在抢红包.逛淘宝.上京东,我选择再续我的“漫谈可视化”系列(好了,不装了,其实是郎中羞涩...) 上篇<漫谈可视化Prefuse(三)---Prefuse API数据结构阅读有 ...

  2. JS魔法堂:被玩坏的innerHTML、innerText、textContent和value属性

    一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替,但它两者 ...

  3. 玩坏JVM很简单--toString的递归调用

    在JVM的内存管理机制下很少发生内存溢出的情况.至少我碰见的少,好像在SSH我多次发布项目时候出现过一次.今天看见一个特简单的方法让内存溢出(好吧,我似乎作死了--!): public class I ...

  4. Github 恶搞教程(一起『玩坏』自己的 Github 吧)

    最近在伯乐在线读到一篇趣文,<如何在 Github『正确』做贡献>,里面各种能人恶搞 Github 的『Public contributions』,下面截取几个小伙伴的战绩: 顺藤摸瓜,发 ...

  5. .CO域名快被这帮搞IT的玩坏了……

    鉴于近来国内访问Google的服务受阻,greatfire.org于前天推出了其基于亚马逊AWS的Google搜索镜像网站,地址是sinaapp.co.该网站随后因多家海外媒体的报道和众多微博大V的转 ...

  6. [转]被玩坏的innerHTML、innerText、textContent和value属性

    一.前言 由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它,一般情况下我们可以使用textContent来代替,但它两者是否就能完全等同呢?在坑爹的表单元素(如input ...

  7. 千亿VR市场 将被国内厂商玩坏多少?

    将被国内厂商玩坏多少?" title="千亿VR市场 将被国内厂商玩坏多少?"> 智能硬件行业在不断寻求新的突破口,当智能手机.平板.电视.家电等都司空见惯之后,能 ...

  8. 千万别把WIFI玩坏了!关于WIFI的新鲜玩法和商业模式探讨

    使用WIFI作为无线上网接入,也许大家都比较习以为常的.但是你们知道吗,其实WIFI还有很多种玩法:基于WIFI的身份识别,WIFI感知,WIFI Direct等等.今天我们会着重介绍一种WIFI的有 ...

  9. 无语啊,sublime给我弄乱玩,玩坏了,而且安装插件也安装不了

    国内的什么插件地址都TMMD失效了,没办法,只能翻"强"到外面找了,而且找了很多也用不了,所以收藏一个为了预防以后不行有补救的方法: 百度的99%都不行,不是报这个错就是那个错,可 ...

随机推荐

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

  2. 元素(Element)和结点(Node)的区别(org.w3c.dom)

    1.元素(Element)和结点(Node)的区别, 元素是一个小范围的定义,必须是含有完整信息的结点才是一个元素,例如 - . 但是一个结点不一定是一个元素,而一个元素一定是一个结点. 什么是nod ...

  3. 【总结整理】JQuery小技巧

    var item=$("#content").find(".item");//效率最高 var item=$("#content .item" ...

  4. Windows 8 64位系统 在VS2010 32位软件上 搭建 PCL点云库 开发环境

    Windows 8 64位系统 在VS2010 32位软件上 搭建 PCL点云库 开发环境 下载PCL For windows 软件包 到这个网站下载PCL-All-In-One Installer: ...

  5. Java学习之多态(Polymorphism)

    多态==晚绑定 不要把函数重载理解为多态. 因为多态是一种运行期的行为,不是编译期的行为. 多态:父类型的引用可以指向子类型的对象. 比如 Parent p = new Child(); 当使用多态方 ...

  6. 诺基亚 920T - 我的非凡系列手机始终显示旋转齿轮而无响应,我该如何让手机停止显示旋转齿轮?

    有时,在 OTA 更新 (或重置手机) 后,设备可能始终显示“旋转齿轮”而无响应. 如果“旋转齿轮”在屏幕上显示的时间超过 60 分钟,则需要执行恢复操作. 您可以尝试下面这些简单的解决方法: 按住电 ...

  7. 解决IIS出现的问题

  8. python学习笔记11 ----线程、进程、协程

    进程.线程.协程的概念 进程和线程是操作系统中两个很重要的概念,对于一般的程序,可能有若干个进程,每一个进程有若干个同时执行的线程.进程是资源管理的最小单位,线程是程序执行的最小单位(线程可共享同一进 ...

  9. SQL Server列属性修改

    0.创建表 create table Users(Id int,Name nvarchar(32) not null,Phone nvarchar(16),Email nvarchar(128)) 1 ...

  10. [CentOS7] 设置开机启动方式(图形界面或命令行)

    由于CenOS之前一直都是通过修改inittab文件来修改开机启动模式,于是 通过 vim /etc/inittab 打开inittab来查看 如上所示,CentOS 7由于使用systemd而不是i ...