Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Campbell Barton 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00032 #include <Python.h> 00033 00034 #include "bpy_util.h" 00035 00036 #include "WM_api.h" 00037 00038 #include "BLI_utildefines.h" 00039 00040 static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw)) 00041 { 00042 /* close down enough of blender at least not to crash */ 00043 struct bContext *C = BPy_GetContext(); 00044 00045 WM_exit_ext(C, 0); 00046 00047 Py_RETURN_NONE; 00048 } 00049 00050 static PyMethodDef meth_bpy_atexit = {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL}; 00051 static PyObject *func_bpy_atregister = NULL; /* borrowed referebce, atexit holds */ 00052 00053 static void atexit_func_call(const char *func_name, PyObject *atexit_func_arg) 00054 { 00055 /* note - no error checking, if any of these fail we'll get a crash 00056 * this is intended, but if its problematic it could be changed 00057 * - campbell */ 00058 00059 PyObject *atexit_mod = PyImport_ImportModuleLevel((char *)"atexit", NULL, NULL, NULL, 0); 00060 PyObject *atexit_func = PyObject_GetAttrString(atexit_mod, func_name); 00061 PyObject *args = PyTuple_New(1); 00062 PyObject *ret; 00063 00064 PyTuple_SET_ITEM(args, 0, atexit_func_arg); 00065 Py_INCREF(atexit_func_arg); /* only incref so we dont dec'ref along with 'args' */ 00066 00067 ret = PyObject_CallObject(atexit_func, args); 00068 00069 Py_DECREF(atexit_mod); 00070 Py_DECREF(atexit_func); 00071 Py_DECREF(args); 00072 00073 if (ret) { 00074 Py_DECREF(ret); 00075 } 00076 else { /* should never happen */ 00077 PyErr_Print(); 00078 } 00079 } 00080 00081 void BPY_atexit_register(void) 00082 { 00083 /* atexit module owns this new function reference */ 00084 BLI_assert(func_bpy_atregister == NULL); 00085 00086 func_bpy_atregister = (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL); 00087 atexit_func_call("register", func_bpy_atregister); 00088 } 00089 00090 void BPY_atexit_unregister(void) 00091 { 00092 BLI_assert(func_bpy_atregister != NULL); 00093 00094 atexit_func_call("unregister", func_bpy_atregister); 00095 func_bpy_atregister = NULL; /* don't really need to set but just incase */ 00096 }