爲什麼不更新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, 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:[email protected] //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, 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; }
最終效果如下圖