|
|
@@ -151,8 +151,10 @@ P3DPythonRun::
|
|
|
// Access: Public
|
|
|
// Description: Runs the embedded Python process. This method does
|
|
|
// not return until the plugin is ready to exit.
|
|
|
+//
|
|
|
+// Returns the exit status, which will be 0 on success.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-bool P3DPythonRun::
|
|
|
+int P3DPythonRun::
|
|
|
run_python() {
|
|
|
#if defined(_WIN32) && defined(USE_DEBUG_PYTHON)
|
|
|
// On Windows, in a debug build, we have to preload sys.dll_suffix =
|
|
|
@@ -170,7 +172,7 @@ run_python() {
|
|
|
if (panda3d_module == NULL) {
|
|
|
nout << "Failed to create panda3d module:\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Set the __path__ such that it can find panda3d/core.pyd, etc.
|
|
|
@@ -188,7 +190,7 @@ run_python() {
|
|
|
if (vfsimporter == NULL) {
|
|
|
nout << "Failed to import _vfsimporter:\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
Py_DECREF(vfsimporter);
|
|
|
|
|
|
@@ -197,7 +199,7 @@ run_python() {
|
|
|
if (vfsimporter_module == NULL) {
|
|
|
nout << "Failed to import VFSImporter:\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// And register the VFSImporter.
|
|
|
@@ -205,7 +207,7 @@ run_python() {
|
|
|
if (result == NULL) {
|
|
|
nout << "Failed to call VFSImporter.register():\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
Py_DECREF(result);
|
|
|
Py_DECREF(vfsimporter_module);
|
|
|
@@ -217,12 +219,12 @@ run_python() {
|
|
|
PT(Multifile) mf = new Multifile;
|
|
|
if (!mf->open_read(_archive_file)) {
|
|
|
nout << "Could not read " << _archive_file << "\n";
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
|
|
if (!vfs->mount(mf, dir, VirtualFileSystem::MF_read_only)) {
|
|
|
nout << "Could not mount " << _archive_file << "\n";
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// And finally, we can import the startup module.
|
|
|
@@ -230,7 +232,7 @@ run_python() {
|
|
|
if (app_runner_module == NULL) {
|
|
|
nout << "Failed to import direct.p3d.AppRunner\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Get the pointers to the objects needed within the module.
|
|
|
@@ -238,7 +240,7 @@ run_python() {
|
|
|
if (app_runner_class == NULL) {
|
|
|
nout << "Failed to get AppRunner class\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Construct an instance of AppRunner.
|
|
|
@@ -246,7 +248,7 @@ run_python() {
|
|
|
if (_runner == NULL) {
|
|
|
nout << "Failed to construct AppRunner instance\n";
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
Py_DECREF(app_runner_class);
|
|
|
|
|
|
@@ -262,35 +264,35 @@ run_python() {
|
|
|
_undefined_object_class = PyObject_GetAttrString(javascript_module, "UndefinedObject");
|
|
|
if (_undefined_object_class == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// And the "Undefined" instance.
|
|
|
_undefined = PyObject_GetAttrString(javascript_module, "Undefined");
|
|
|
if (_undefined == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Get the ConcreteStruct class.
|
|
|
_concrete_struct_class = PyObject_GetAttrString(javascript_module, "ConcreteStruct");
|
|
|
if (_concrete_struct_class == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Get the BrowserObject class.
|
|
|
_browser_object_class = PyObject_GetAttrString(javascript_module, "BrowserObject");
|
|
|
if (_browser_object_class == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Get the global TaskManager.
|
|
|
_taskMgr = PyObject_GetAttrString(app_runner_module, "taskMgr");
|
|
|
if (_taskMgr == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
Py_DECREF(app_runner_module);
|
|
|
@@ -320,12 +322,12 @@ run_python() {
|
|
|
#endif
|
|
|
if (p3dpython == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
PyObject *request_func = PyObject_GetAttrString(p3dpython, "request_func");
|
|
|
if (request_func == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Now pass that func pointer back to our AppRunner instance, so it
|
|
|
@@ -333,7 +335,7 @@ run_python() {
|
|
|
result = PyObject_CallMethod(_runner, (char *)"setRequestFunc", (char *)"N", request_func);
|
|
|
if (result == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
Py_DECREF(result);
|
|
|
|
|
|
@@ -353,7 +355,7 @@ run_python() {
|
|
|
PyObject *check_comm = PyObject_GetAttrString(p3dpython, "check_comm");
|
|
|
if (check_comm == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
// Add it to the task manager. We do this instead of constructing a
|
|
|
@@ -361,7 +363,7 @@ run_python() {
|
|
|
result = PyObject_CallMethod(_taskMgr, (char *)"add", (char *)"Ns", check_comm, "check_comm");
|
|
|
if (result == NULL) {
|
|
|
PyErr_Print();
|
|
|
- return false;
|
|
|
+ return 1;
|
|
|
}
|
|
|
Py_DECREF(result);
|
|
|
|
|
|
@@ -369,18 +371,30 @@ run_python() {
|
|
|
// taskMgr.run()).
|
|
|
PyObject *done = PyObject_CallMethod(_runner, (char *)"run", (char *)"");
|
|
|
if (done == NULL) {
|
|
|
+ int status = 1;
|
|
|
+
|
|
|
// An uncaught application exception, and not handled by
|
|
|
- // appRunner.exceptionHandler.
|
|
|
- PyErr_Print();
|
|
|
+ // appRunner.exceptionHandler. If it is a SystemExit, extract
|
|
|
+ // the exit status that we should return.
|
|
|
+ if (PyErr_Occurred() == PyExc_SystemExit) {
|
|
|
+ PyObject *ptype, *ptraceback;
|
|
|
+ PySystemExitObject *value = NULL;
|
|
|
+ PyErr_Fetch(&ptype, (PyObject **)&value, &ptraceback);
|
|
|
+ if (value != NULL) {
|
|
|
+ status = (int)PyInt_AsLong(value->code);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ PyErr_Print();
|
|
|
+ }
|
|
|
|
|
|
if (_interactive_console) {
|
|
|
// Give an interactive user a chance to explore the exception.
|
|
|
run_interactive_console();
|
|
|
- return true;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
// We're done.
|
|
|
- return false;
|
|
|
+ return status;
|
|
|
}
|
|
|
|
|
|
// A normal exit from the taskManager. We're presumably done.
|
|
|
@@ -390,7 +404,7 @@ run_python() {
|
|
|
run_interactive_console();
|
|
|
}
|
|
|
|
|
|
- return true;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|