possible (hopeful) fix for the garbage collection bug
This commit is contained in:
@@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
#include "overviewer.h"
|
#include "overviewer.h"
|
||||||
|
|
||||||
|
/* global variables from rendermodes.c -- both are dictionaries */
|
||||||
|
extern PyObject *render_mode_options;
|
||||||
|
extern PyObject *custom_render_modes;
|
||||||
|
|
||||||
PyObject *get_extension_version(PyObject *self, PyObject *args) {
|
PyObject *get_extension_version(PyObject *self, PyObject *args) {
|
||||||
|
|
||||||
return Py_BuildValue("i", OVERVIEWER_EXTENSION_VERSION);
|
return Py_BuildValue("i", OVERVIEWER_EXTENSION_VERSION);
|
||||||
@@ -55,9 +59,22 @@ static PyMethodDef COverviewerMethods[] = {
|
|||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
initc_overviewer(void)
|
initc_overviewer(void)
|
||||||
{
|
{
|
||||||
(void)Py_InitModule("c_overviewer", COverviewerMethods);
|
PyObject *mod = Py_InitModule("c_overviewer", COverviewerMethods);
|
||||||
|
|
||||||
/* for numpy */
|
/* for numpy */
|
||||||
import_array();
|
import_array();
|
||||||
|
|
||||||
|
/* create the render mode data structures, and attatch them to the module
|
||||||
|
* so that the Python garbage collector doesn't freak out
|
||||||
|
*/
|
||||||
|
|
||||||
|
render_mode_options = PyDict_New();
|
||||||
|
PyObject_SetAttrString(mod, "_render_mode_options", render_mode_options);
|
||||||
|
Py_DECREF(render_mode_options);
|
||||||
|
|
||||||
|
custom_render_modes = PyDict_New();
|
||||||
|
PyObject_SetAttrString(mod, "_custom_render_modes", custom_render_modes);
|
||||||
|
Py_DECREF(custom_render_modes);
|
||||||
|
|
||||||
init_endian();
|
init_endian();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ static RenderModeInterface *render_modes[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *render_mode_options = NULL;
|
PyObject *render_mode_options = NULL;
|
||||||
static PyObject *custom_render_modes = NULL;
|
PyObject *custom_render_modes = NULL;
|
||||||
|
|
||||||
/* rendermode encapsulation */
|
/* rendermode encapsulation */
|
||||||
|
|
||||||
@@ -43,8 +43,6 @@ render_mode_create_options(const char *mode) {
|
|||||||
const char *parent = NULL;
|
const char *parent = NULL;
|
||||||
PyObject *base_options, *ret, *parent_options;
|
PyObject *base_options, *ret, *parent_options;
|
||||||
unsigned int i, found_concrete;
|
unsigned int i, found_concrete;
|
||||||
if (render_mode_options == NULL)
|
|
||||||
return PyDict_New();
|
|
||||||
|
|
||||||
base_options = PyDict_GetItemString(render_mode_options, mode);
|
base_options = PyDict_GetItemString(render_mode_options, mode);
|
||||||
if (base_options) {
|
if (base_options) {
|
||||||
@@ -66,7 +64,7 @@ render_mode_create_options(const char *mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check custom mode info if needed */
|
/* check custom mode info if needed */
|
||||||
if (found_concrete == 0 && custom_render_modes != NULL) {
|
if (found_concrete == 0) {
|
||||||
PyObject *custom = PyDict_GetItemString(custom_render_modes, mode);
|
PyObject *custom = PyDict_GetItemString(custom_render_modes, mode);
|
||||||
if (custom) {
|
if (custom) {
|
||||||
custom = PyDict_GetItemString(custom, "parent");
|
custom = PyDict_GetItemString(custom, "parent");
|
||||||
@@ -106,8 +104,6 @@ render_mode_find_interface(const char *mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check for custom modes */
|
/* check for custom modes */
|
||||||
if (custom_render_modes == NULL)
|
|
||||||
return NULL;
|
|
||||||
custom = PyDict_GetItemString(custom_render_modes, mode);
|
custom = PyDict_GetItemString(custom_render_modes, mode);
|
||||||
if (custom == NULL)
|
if (custom == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -236,13 +232,11 @@ PyObject *get_render_modes(PyObject *self, PyObject *args) {
|
|||||||
Py_DECREF(name);
|
Py_DECREF(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (custom_render_modes != NULL) {
|
PyObject *key, *value;
|
||||||
PyObject *key, *value;
|
Py_ssize_t pos = 0;
|
||||||
Py_ssize_t pos = 0;
|
|
||||||
|
while (PyDict_Next(custom_render_modes, &pos, &key, &value)) {
|
||||||
while (PyDict_Next(custom_render_modes, &pos, &key, &value)) {
|
PyList_Append(modes, key);
|
||||||
PyList_Append(modes, key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return modes;
|
return modes;
|
||||||
@@ -329,22 +323,20 @@ PyObject *get_render_mode_info(PyObject *self, PyObject *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (custom_render_modes != NULL) {
|
PyObject *custom = PyDict_GetItemString(custom_render_modes, rendermode);
|
||||||
PyObject *custom = PyDict_GetItemString(custom_render_modes, rendermode);
|
if (custom) {
|
||||||
if (custom) {
|
PyObject *tmp, *copy = PyDict_Copy(custom);
|
||||||
PyObject *tmp, *copy = PyDict_Copy(custom);
|
Py_DECREF(info);
|
||||||
Py_DECREF(info);
|
|
||||||
|
tmp = PyString_FromString(rendermode);
|
||||||
tmp = PyString_FromString(rendermode);
|
PyDict_SetItemString(copy, "name", tmp);
|
||||||
PyDict_SetItemString(copy, "name", tmp);
|
Py_DECREF(tmp);
|
||||||
Py_DECREF(tmp);
|
|
||||||
|
tmp = PyList_New(0);
|
||||||
tmp = PyList_New(0);
|
PyDict_SetItemString(copy, "options", tmp);
|
||||||
PyDict_SetItemString(copy, "options", tmp);
|
Py_DECREF(tmp);
|
||||||
Py_DECREF(tmp);
|
|
||||||
|
return copy;
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(info);
|
Py_DECREF(info);
|
||||||
@@ -365,17 +357,15 @@ PyObject *get_render_mode_inheritance(PyObject *self, PyObject *args) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* take care of the chain of custom modes, if there are any */
|
/* take care of the chain of custom modes, if there are any */
|
||||||
if (custom_render_modes != NULL) {
|
PyObject *custom = PyDict_GetItemString(custom_render_modes, rendermode);
|
||||||
PyObject *custom = PyDict_GetItemString(custom_render_modes, rendermode);
|
while (custom != NULL) {
|
||||||
while (custom != NULL) {
|
PyObject *name = PyString_FromString(rendermode);
|
||||||
PyObject *name = PyString_FromString(rendermode);
|
PyList_Append(parents, name);
|
||||||
PyList_Append(parents, name);
|
Py_DECREF(name);
|
||||||
Py_DECREF(name);
|
|
||||||
|
custom = PyDict_GetItemString(custom, "parent");
|
||||||
custom = PyDict_GetItemString(custom, "parent");
|
rendermode = PyString_AsString(custom);
|
||||||
rendermode = PyString_AsString(custom);
|
custom = PyDict_GetItem(custom_render_modes, custom);
|
||||||
custom = PyDict_GetItem(custom_render_modes, custom);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now handle concrete modes */
|
/* now handle concrete modes */
|
||||||
@@ -423,17 +413,15 @@ PyObject *get_render_mode_children(PyObject *self, PyObject *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (custom_render_modes != NULL) {
|
PyObject *key, *value;
|
||||||
PyObject *key, *value;
|
Py_ssize_t pos = 0;
|
||||||
Py_ssize_t pos = 0;
|
|
||||||
|
while (PyDict_Next(custom_render_modes, &pos, &key, &value)) {
|
||||||
|
PyObject *pyparent = PyDict_GetItemString(value, "parent");
|
||||||
|
const char *parent = PyString_AsString(pyparent);
|
||||||
|
|
||||||
while (PyDict_Next(custom_render_modes, &pos, &key, &value)) {
|
if (strcmp(parent, rendermode) == 0) {
|
||||||
PyObject *pyparent = PyDict_GetItemString(value, "parent");
|
PyList_Append(children, key);
|
||||||
const char *parent = PyString_AsString(pyparent);
|
|
||||||
|
|
||||||
if (strcmp(parent, rendermode) == 0) {
|
|
||||||
PyList_Append(children, key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,9 +473,6 @@ PyObject *set_render_mode_options(PyObject *self, PyObject *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (render_mode_options == NULL)
|
|
||||||
render_mode_options = PyDict_New();
|
|
||||||
|
|
||||||
PyDict_SetItemString(render_mode_options, rendermode, opts);
|
PyDict_SetItemString(render_mode_options, rendermode, opts);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
@@ -498,9 +483,6 @@ PyObject *add_custom_render_mode(PyObject *self, PyObject *args) {
|
|||||||
if (!PyArg_ParseTuple(args, "sO!", &rendermode, &PyDict_Type, &opts))
|
if (!PyArg_ParseTuple(args, "sO!", &rendermode, &PyDict_Type, &opts))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (custom_render_modes == NULL)
|
|
||||||
custom_render_modes = PyDict_New();
|
|
||||||
|
|
||||||
/* first, make sure the parent is set correctly */
|
/* first, make sure the parent is set correctly */
|
||||||
pyparent = PyDict_GetItemString(opts, "parent");
|
pyparent = PyDict_GetItemString(opts, "parent");
|
||||||
if (pyparent == NULL)
|
if (pyparent == NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user