Exppython:
- Fixed a problem with control of the global Python dictionary persistence: Blender.ReleaseGlobalDict(bool) should now work fine. - Trying to fix the sigsegv crashes on Windows: They happen when we try to "print" our objects, like Lamps or Cameras. Following advice from the Python Embedding doc, removed the tp_print method from Camera and also improved its tp_repr one, that will be used as print, repr() and str() for Cameras. If this test works all other objs will be updated accordingly.
This commit is contained in:
@@ -108,7 +108,7 @@ void BPY_start_python(void)
|
|||||||
|
|
||||||
init_syspath();
|
init_syspath();
|
||||||
|
|
||||||
return; /* We could take away all these return; ... */
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -181,11 +181,7 @@ void init_syspath(void)
|
|||||||
else
|
else
|
||||||
printf ("Warning: could not determine argv[0] path\n");
|
printf ("Warning: could not determine argv[0] path\n");
|
||||||
|
|
||||||
if (U.pythondir) { /* XXX not working, U.pythondir is NULL here ?!?*/
|
if (U.pythondir) {
|
||||||
/* maybe it wasn't defined yet at this point in start-up ...*/
|
|
||||||
/* Update: definitely that is the reason. We need to start python
|
|
||||||
* after U.pythondir is defined (better after the other U.xxxx are
|
|
||||||
* too. */
|
|
||||||
p = Py_BuildValue("s", U.pythondir);
|
p = Py_BuildValue("s", U.pythondir);
|
||||||
syspath_append(p); /* append to module search path */
|
syspath_append(p); /* append to module search path */
|
||||||
}
|
}
|
||||||
@@ -323,6 +319,7 @@ void BPY_Err_Handle(Text *text)
|
|||||||
struct _object *BPY_txt_do_python(struct SpaceText* st)
|
struct _object *BPY_txt_do_python(struct SpaceText* st)
|
||||||
{
|
{
|
||||||
PyObject *dict, *ret;
|
PyObject *dict, *ret;
|
||||||
|
PyObject *main_dict = PyModule_GetDict(PyImport_AddModule("__main__"));
|
||||||
|
|
||||||
//printf ("\nIn BPY_txt_do_python\n");
|
//printf ("\nIn BPY_txt_do_python\n");
|
||||||
|
|
||||||
@@ -332,7 +329,7 @@ struct _object *BPY_txt_do_python(struct SpaceText* st)
|
|||||||
* the script with a clean global dictionary or should keep the current one,
|
* the script with a clean global dictionary or should keep the current one,
|
||||||
* possibly already "polluted" by other calls to the Python Interpreter.
|
* possibly already "polluted" by other calls to the Python Interpreter.
|
||||||
* The default is to use a clean one. To change this the script writer must
|
* The default is to use a clean one. To change this the script writer must
|
||||||
* call Blender.releaseGlobalDict(bool), with bool == 0, in the script */
|
* call Blender.ReleaseGlobalDict(bool), with bool == 0, in the script. */
|
||||||
|
|
||||||
if (EXPP_releaseGlobalDict) {
|
if (EXPP_releaseGlobalDict) {
|
||||||
printf("Using a clean Global Dictionary.\n");
|
printf("Using a clean Global Dictionary.\n");
|
||||||
@@ -340,7 +337,7 @@ struct _object *BPY_txt_do_python(struct SpaceText* st)
|
|||||||
dict = CreateGlobalDictionary();
|
dict = CreateGlobalDictionary();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dict = PyModule_GetDict(PyImport_AddModule("__main__"));
|
dict = main_dict; /* must be careful not to free the main_dict */
|
||||||
|
|
||||||
clearScriptLinks ();
|
clearScriptLinks ();
|
||||||
|
|
||||||
@@ -348,7 +345,8 @@ struct _object *BPY_txt_do_python(struct SpaceText* st)
|
|||||||
|
|
||||||
if (!ret) { /* Failed execution of the script */
|
if (!ret) { /* Failed execution of the script */
|
||||||
|
|
||||||
if (EXPP_releaseGlobalDict) ReleaseGlobalDictionary(dict);
|
if (EXPP_releaseGlobalDict && (dict != main_dict))
|
||||||
|
ReleaseGlobalDictionary(dict);
|
||||||
|
|
||||||
BPY_Err_Handle(st->text);
|
BPY_Err_Handle(st->text);
|
||||||
BPY_end_python();
|
BPY_end_python();
|
||||||
@@ -359,22 +357,33 @@ struct _object *BPY_txt_do_python(struct SpaceText* st)
|
|||||||
|
|
||||||
else Py_DECREF (ret);
|
else Py_DECREF (ret);
|
||||||
|
|
||||||
/* From the old BPY_main.c:
|
/* Scripts that use the GUI rely on the persistent global namespace, so
|
||||||
* 'The following lines clear the global name space of the python
|
* they need a workaround: The namespace is released when the GUI is exit.'
|
||||||
* interpreter. This is desired to release objects after execution
|
|
||||||
* of a script (remember that each wrapper object increments the refcount
|
|
||||||
* of the Blender Object.
|
|
||||||
* Exception: scripts that use the GUI rely on the
|
|
||||||
* persistent global namespace, so they need a workaround: The namespace
|
|
||||||
* is released when the GUI is exit.'
|
|
||||||
* See api2_2x/Draw.c: Method_Register() */
|
* See api2_2x/Draw.c: Method_Register() */
|
||||||
|
|
||||||
|
/* Block below: The global dict should only be released if:
|
||||||
|
* - a script didn't defined it to be persistent and
|
||||||
|
* - Draw.Register() is not in use (no GUI) and
|
||||||
|
* - it is not the real __main__ dict (if it is, restart to clean it) */
|
||||||
|
|
||||||
if (EXPP_releaseGlobalDict) {
|
if (EXPP_releaseGlobalDict) {
|
||||||
if (st->flags & ST_CLEAR_NAMESPACE) {
|
if (st->flags & ST_CLEAR_NAMESPACE) { /* False if the GUI is in use */
|
||||||
ReleaseGlobalDictionary(dict);
|
|
||||||
/*garbage_collect(&G.main); Unfinished in the previous implementation */
|
if (dict != main_dict) ReleaseGlobalDictionary(dict);
|
||||||
|
|
||||||
|
else {
|
||||||
|
BPY_end_python(); /* restart to get a fresh __main__ dict */
|
||||||
|
BPY_start_python();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (dict != main_dict) PyDict_Update (main_dict, dict);
|
||||||
|
|
||||||
|
/* Line above: if it should be kept and it's not already the __main__ dict,
|
||||||
|
* merge it into the __main__ one. This happens when to release is the
|
||||||
|
* current behavior and the script changes that with
|
||||||
|
* Blender.ReleaseGlobalDict(0). */
|
||||||
|
|
||||||
/* Edited from old BPY_main.c:
|
/* Edited from old BPY_main.c:
|
||||||
* 'The return value is the global namespace dictionary of the script
|
* 'The return value is the global namespace dictionary of the script
|
||||||
|
@@ -50,7 +50,8 @@ PyTypeObject Camera_Type =
|
|||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
/* methods */
|
/* methods */
|
||||||
(destructor)Camera_dealloc, /* tp_dealloc */
|
(destructor)Camera_dealloc, /* tp_dealloc */
|
||||||
(printfunc)Camera_print, /* tp_print */
|
// (printfunc)Camera_print, /* tp_print */
|
||||||
|
0, /* tp_print */
|
||||||
(getattrfunc)Camera_getAttr, /* tp_getattr */
|
(getattrfunc)Camera_getAttr, /* tp_getattr */
|
||||||
(setattrfunc)Camera_setAttr, /* tp_setattr */
|
(setattrfunc)Camera_setAttr, /* tp_setattr */
|
||||||
(cmpfunc)Camera_compare, /* tp_compare */
|
(cmpfunc)Camera_compare, /* tp_compare */
|
||||||
@@ -582,14 +583,14 @@ static int Camera_compare (BPy_Camera *a, BPy_Camera *b)
|
|||||||
Camera *pa = a->camera, *pb = b->camera;
|
Camera *pa = a->camera, *pb = b->camera;
|
||||||
return (pa == pb) ? 0:-1;
|
return (pa == pb) ? 0:-1;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static int Camera_print(BPy_Camera *self, FILE *fp, int flags)
|
static int Camera_print(BPy_Camera *self, FILE *fp, int flags)
|
||||||
{
|
{
|
||||||
fprintf(fp, "[Camera \"%s\"]", self->camera->id.name+2);
|
fprintf(fp, "[Camera \"%s\"]", self->camera->id.name+2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static PyObject *Camera_repr (BPy_Camera *self)
|
static PyObject *Camera_repr (BPy_Camera *self)
|
||||||
{
|
{
|
||||||
return PyString_FromString(self->camera->id.name+2);
|
return PyString_FromFormat("[Camera \"%s\"]", self->camera->id.name+2);
|
||||||
}
|
}
|
||||||
|
@@ -174,7 +174,7 @@ static PyMethodDef BPy_Camera_methods[] = {
|
|||||||
/* Python Camera_Type callback function prototypes: */
|
/* Python Camera_Type callback function prototypes: */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static void Camera_dealloc (BPy_Camera *self);
|
static void Camera_dealloc (BPy_Camera *self);
|
||||||
static int Camera_print (BPy_Camera *self, FILE *fp, int flags);
|
//static int Camera_print (BPy_Camera *self, FILE *fp, int flags);
|
||||||
static int Camera_setAttr (BPy_Camera *self, char *name, PyObject *v);
|
static int Camera_setAttr (BPy_Camera *self, char *name, PyObject *v);
|
||||||
static int Camera_compare (BPy_Camera *a, BPy_Camera *b);
|
static int Camera_compare (BPy_Camera *a, BPy_Camera *b);
|
||||||
static PyObject *Camera_getAttr (BPy_Camera *self, char *name);
|
static PyObject *Camera_getAttr (BPy_Camera *self, char *name);
|
||||||
|
@@ -167,6 +167,8 @@ static PyObject *M_Material_New(PyObject *self, PyObject *args,
|
|||||||
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
"couldn't create Material Data in Blender"));
|
"couldn't create Material Data in Blender"));
|
||||||
|
|
||||||
|
blmat->id.us = 0; /* was incref'ed by add_material() above */
|
||||||
|
|
||||||
if (pymat == NULL)
|
if (pymat == NULL)
|
||||||
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
|
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
|
||||||
"couldn't create Material Data object"));
|
"couldn't create Material Data object"));
|
||||||
|
@@ -15,6 +15,7 @@ Blender Python
|
|||||||
Submodules:
|
Submodules:
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
- L{Material}
|
||||||
- L{Camera}
|
- L{Camera}
|
||||||
- L{Lamp}
|
- L{Lamp}
|
||||||
- L{BGL}
|
- L{BGL}
|
||||||
|
Reference in New Issue
Block a user