让我们把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%都不行,不是报这个错就是那个错,可 ...
随机推荐
- 针对nginx的内核优化
关于内核参数的优化: net.ipv4.tcp_max_tw_buckets = 6000timewait的数量,默认是180000.net.ipv4.ip_local_port_range = 10 ...
- 韩顺平循序渐进学JAVA从入门到精通 视频全套,需要的联系我
0讲-开山篇.avi 10讲-访问修饰符.重载.覆盖.avi 11讲-约瑟夫问题.avi 12讲-多态.avi 13讲-抽象类.接口.avi 14讲-final.作业评讲.avi 15讲-作业.测试题 ...
- Python学习——输入和输出
(转自:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014316434841 ...
- 7. IIS短文件/文件夹漏洞(汇总整理)
漏洞的成因与分析: 1)利用“~”字符猜解暴露短文件/文件夹名. 2).Net Framework的拒绝服务攻击. 现在看大部分的分析讨论都是第一个的.第二个比较少.这里简单复述一下其他研究人员的分析 ...
- Centos7安装lnmp环境
系统版本:centos7 64位 PHP版本:PHP 7.0.21 Nginx版本:1.8.1 MySQL版本:5.5.17 注:1.所有安装都必须放在 /usr/local/src文件夹下 2.添加 ...
- LOJ6235 区间素数个数(min_25筛)
题目链接:LOJ 题目大意:看到题目名字应该都知道是啥了吧. $1\le N\le 10^{11}$. 阉割版 min_25 筛.发现答案实际上就是 min_25 筛中 $g(N,pl)$ 的值.(取 ...
- React.Component(V16.8.6)
组件的生命周期 挂载 当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下: constructor() static getDerivedStateFromProps() render() ...
- CodeForces 116C 【BFS】
思路: 求所有树的最大高度? 注意:所有树从树根开始? #include <bits/stdc++.h> using namespace std; typedef long long LL ...
- KONG -- 图形化管理(Kong Dashboard)
前面安装的 KONG 的版本是社区版的 1.0.2,官方的 KONG Manager 好像只有企业版才提供.在 github 上找了一个开源的图形化管理应用 -- Kong Dashboard (ht ...
- python numpy 判断ndarray 中是否有 nan
numpy.isnan(myarray).any() 下面讨论了哪一种方法的速度最快 reference: stackoverflow.com/questions/911871/detect-if-a ...