Skip to content

Commit 3e3d0c4

Browse files
committed
Update py_entitydef.cpp
kbengine#612
1 parent de22655 commit 3e3d0c4

File tree

1 file changed

+143
-6
lines changed

1 file changed

+143
-6
lines changed

kbe/src/lib/entitydef/py_entitydef.cpp

Lines changed: 143 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,9 @@ static bool loadAllScriptForComponentType(COMPONENT_TYPE loadComponentType)
11811181

11821182
if (rootPath.size() == 0)
11831183
{
1184-
ERROR_MSG(fmt::format("PyEntityDef::loadAllScripts(): Could not find kbengine.xml\n"));
1184+
ERROR_MSG(fmt::format("PyEntityDef::loadAllScriptForComponentType(): get scripts path error! loadComponentType={}\n",
1185+
COMPONENT_NAME_EX(loadComponentType)));
1186+
11851187
return false;
11861188
}
11871189

@@ -1236,6 +1238,7 @@ static bool loadAllScriptForComponentType(COMPONENT_TYPE loadComponentType)
12361238
if (!pyModule)
12371239
{
12381240
SCRIPT_ERROR_CHECK();
1241+
return false;
12391242
}
12401243
else
12411244
{
@@ -1251,14 +1254,148 @@ static bool loadAllScriptForComponentType(COMPONENT_TYPE loadComponentType)
12511254
}
12521255

12531256
//-------------------------------------------------------------------------------------
1254-
static bool loadAllScripts()
1257+
static bool execPython(COMPONENT_TYPE componentType)
12551258
{
1256-
if (g_componentType != BASEAPP_TYPE && g_componentType != CELLAPP_TYPE)
1257-
return true;
1259+
std::pair<std::wstring, std::wstring> pyPaths = getComponentPythonPaths(componentType);
1260+
if (pyPaths.first.size() == 0)
1261+
{
1262+
ERROR_MSG(fmt::format("PyEntityDef::execPython(): PythonApp({}) paths error!\n", COMPONENT_NAME_EX(componentType)));
1263+
return false;
1264+
}
1265+
1266+
APPEND_PYSYSPATH(pyPaths.second);
1267+
1268+
PyObject* kbeModuleOld = PyImport_AddModule("KBEngine");
1269+
if (kbeModuleOld == NULL)
1270+
{
1271+
KBE_ASSERT(false);
1272+
return false;
1273+
}
1274+
1275+
PyObject* modulesOld = PySys_GetObject("modules");
1276+
1277+
PyObjectPtr entityType(PyObject_GetAttrString(kbeModuleOld, "Entity"), PyObjectPtr::STEAL_REF);
1278+
PyObjectPtr entityComponentType(PyObject_GetAttrString(kbeModuleOld, "EntityComponent"), PyObjectPtr::STEAL_REF);
1279+
1280+
PyThreadState* pCurInterpreter = PyThreadState_Get();
1281+
PyThreadState* pNewInterpreter = Py_NewInterpreter();
1282+
1283+
if (!pNewInterpreter)
1284+
{
1285+
ERROR_MSG(fmt::format("PyEntityDef::execPython(): Py_NewInterpreter()!\n"));
1286+
SCRIPT_ERROR_CHECK();
1287+
return false;
1288+
}
1289+
1290+
PySys_SetPath(pyPaths.second.c_str());
1291+
1292+
PyObject* modulesNew = PySys_GetObject("modules");
1293+
PyDict_Merge(modulesNew, Script::getSingleton().getSysInitModules(), 0);
1294+
1295+
{
1296+
PyObject *key, *value;
1297+
Py_ssize_t pos = 0;
1298+
1299+
while (PyDict_Next(modulesOld, &pos, &key, &value))
1300+
{
1301+
const char* typeName = PyUnicode_AsUTF8AndSize(key, NULL);
1302+
1303+
if (std::string(typeName) == "KBEngine")
1304+
continue;
1305+
1306+
PyObject* pyDoc = PyObject_GetAttrString(value, "__doc__");
1307+
1308+
if (pyDoc)
1309+
{
1310+
const char* doc = PyUnicode_AsUTF8AndSize(pyDoc, NULL);
1311+
1312+
if (doc && std::string(doc).find("KBEngine") != std::string::npos)
1313+
PyDict_SetItemString(modulesNew, typeName, value);
1314+
1315+
if (PyErr_Occurred())
1316+
PyErr_Clear();
1317+
1318+
Py_XDECREF(pyDoc);
1319+
}
1320+
else
1321+
{
1322+
SCRIPT_ERROR_CHECK();
1323+
}
1324+
}
1325+
}
1326+
1327+
PyObject *m = PyImport_AddModule("__main__");
1328+
1329+
// 添加一个脚本基础模块
1330+
PyObject* kbeModule = PyImport_AddModule("KBEngine");
1331+
KBE_ASSERT(kbeModule);
1332+
1333+
const char* componentName = COMPONENT_NAME_EX(componentType);
1334+
if (PyModule_AddStringConstant(kbeModule, "component", componentName))
1335+
{
1336+
ERROR_MSG(fmt::format("PyEntityDef::execPython(): Unable to set KBEngine.component to {}\n",
1337+
componentName));
1338+
1339+
return false;
1340+
}
12581341

1259-
bool otherPartSuccess = loadAllScriptForComponentType(g_componentType);
1260-
if (!otherPartSuccess)
1342+
// 将模块对象加入main
1343+
PyObject_SetAttrString(m, "KBEngine", kbeModule);
1344+
1345+
PyModule_AddObject(kbeModule, "EntityComponent", entityComponentType.get());
1346+
PyModule_AddObject(kbeModule, "Entity", entityType.get());
1347+
1348+
if(componentType == BASEAPP_TYPE)
1349+
PyModule_AddObject(kbeModule, "Proxy", entityType.get());
1350+
1351+
if (pNewInterpreter != PyThreadState_Swap(pCurInterpreter))
1352+
{
1353+
KBE_ASSERT(false);
1354+
return false;
1355+
}
1356+
1357+
PyThreadState_Swap(pNewInterpreter);
1358+
1359+
bool otherPartSuccess = loadAllScriptForComponentType(componentType);
1360+
1361+
if (pNewInterpreter != PyThreadState_Swap(pCurInterpreter))
1362+
{
1363+
KBE_ASSERT(false);
12611364
return false;
1365+
}
1366+
1367+
// 此处不能使用Py_EndInterpreter,会导致Math、Def等模块析构
1368+
PyInterpreterState_Clear(pNewInterpreter->interp);
1369+
PyInterpreterState_Delete(pNewInterpreter->interp);
1370+
return otherPartSuccess;
1371+
}
1372+
1373+
//-------------------------------------------------------------------------------------
1374+
static bool loadAllScripts()
1375+
{
1376+
std::vector< COMPONENT_TYPE > loadOtherComponentTypes;
1377+
1378+
if (g_componentType == CELLAPP_TYPE || g_componentType == BASEAPP_TYPE)
1379+
{
1380+
bool otherPartSuccess = loadAllScriptForComponentType(g_componentType);
1381+
if (!otherPartSuccess)
1382+
return false;
1383+
1384+
loadOtherComponentTypes.push_back((g_componentType == BASEAPP_TYPE) ? CELLAPP_TYPE : BASEAPP_TYPE);
1385+
}
1386+
else
1387+
{
1388+
loadOtherComponentTypes.push_back(BASEAPP_TYPE);
1389+
loadOtherComponentTypes.push_back(CELLAPP_TYPE);
1390+
}
1391+
1392+
for (std::vector< COMPONENT_TYPE >::iterator iter = loadOtherComponentTypes.begin(); iter != loadOtherComponentTypes.end(); ++iter)
1393+
{
1394+
COMPONENT_TYPE componentType = (*iter);
1395+
1396+
if (!execPython(componentType))
1397+
return false;
1398+
}
12621399

12631400
return true;
12641401
}

0 commit comments

Comments
 (0)