为什么不更新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; }
最终效果如下图