Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/python/mathutils/mathutils.c')
-rw-r--r--source/blender/python/mathutils/mathutils.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index dcb6d7f3bc6..ef5339c3aa3 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -47,8 +47,7 @@ static int mathutils_array_parse_fast(float *array,
i = size;
do {
i--;
- if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&
- PyErr_Occurred()) {
+ if (((array[i] = PyFloat_AsDouble(item = value_fast_items[i])) == -1.0f) && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"%.200s: sequence index %d expected a number, "
"found '%.200s' type, ",
@@ -317,7 +316,7 @@ int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const
i = size;
while (i > 0) {
i--;
- if (((array[i] = PyC_Long_AsI32((item = value_fast_items[i]))) == -1) && PyErr_Occurred()) {
+ if (((array[i] = PyC_Long_AsI32(item = value_fast_items[i])) == -1) && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "%.200s: sequence index %d expected an int", error_prefix, i);
size = -1;
break;
@@ -698,6 +697,18 @@ int BaseMathObject_clear(BaseMathObject *self)
return 0;
}
+/** Only to validate assumptions when debugging. */
+#ifndef NDEBUG
+static bool BaseMathObject_is_tracked(BaseMathObject *self)
+{
+ PyObject *cb_user = self->cb_user;
+ self->cb_user = (void *)(uintptr_t)-1;
+ bool is_tracked = PyObject_GC_IsTracked((PyObject *)self);
+ self->cb_user = cb_user;
+ return is_tracked;
+}
+#endif /* NDEBUG */
+
void BaseMathObject_dealloc(BaseMathObject *self)
{
/* only free non wrapped */
@@ -706,11 +717,46 @@ void BaseMathObject_dealloc(BaseMathObject *self)
}
if (self->cb_user) {
+ BLI_assert(BaseMathObject_is_tracked(self) == true);
PyObject_GC_UnTrack(self);
BaseMathObject_clear(self);
}
+ else if (!BaseMathObject_CheckExact(self)) {
+ /* Sub-classed types get an extra track (in Pythons internal `subtype_dealloc` function). */
+ BLI_assert(BaseMathObject_is_tracked(self) == true);
+ PyObject_GC_UnTrack(self);
+ BLI_assert(BaseMathObject_is_tracked(self) == false);
+ }
+
+ Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks sub-types. */
+}
+
+int BaseMathObject_is_gc(BaseMathObject *self)
+{
+ return self->cb_user != NULL;
+}
+
+PyObject *_BaseMathObject_new_impl(PyTypeObject *root_type, PyTypeObject *base_type)
+{
+ PyObject *obj;
+ if (ELEM(base_type, NULL, root_type)) {
+ obj = _PyObject_GC_New(root_type);
+ if (obj) {
+ BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == false);
+ }
+ }
+ else {
+ /* Calls Generic allocation function which always tracks
+ * (because `root_type` is flagged for GC). */
+ obj = base_type->tp_alloc(base_type, 0);
+ if (obj) {
+ BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == true);
+ PyObject_GC_UnTrack(obj);
+ BLI_assert(BaseMathObject_is_tracked((BaseMathObject *)obj) == false);
+ }
+ }
- Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); /* breaks subtypes. */
+ return obj;
}
/*----------------------------MODULE INIT-------------------------*/
@@ -720,14 +766,14 @@ static struct PyMethodDef M_Mathutils_methods[] = {
static struct PyModuleDef M_Mathutils_module_def = {
PyModuleDef_HEAD_INIT,
- "mathutils", /* m_name */
- M_Mathutils_doc, /* m_doc */
- 0, /* m_size */
- M_Mathutils_methods, /* m_methods */
- NULL, /* m_slots */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
+ /*m_name*/ "mathutils",
+ /*m_doc*/ M_Mathutils_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ M_Mathutils_methods,
+ /*m_slots*/ NULL,
+ /*m_traverse*/ NULL,
+ /*m_clear*/ NULL,
+ /*m_free*/ NULL,
};
/* submodules only */