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:
-rw-r--r--source/blender/blenkernel/intern/library.c10
-rw-r--r--source/blender/python/BPY_extern.h2
-rw-r--r--source/blender/python/intern/bpy_rna.c49
-rw-r--r--source/blender/python/intern/bpy_rna.h3
4 files changed, 57 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index bb6d3c490d0..b2e0bb20f55 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -109,6 +109,10 @@
#include "BKE_gpencil.h"
#include "BKE_fcurve.h"
+#ifdef WITH_PYTHON
+#include "BPY_extern.h"
+#endif
+
#define MAX_IDPUP 60 /* was 24 */
/* GS reads the memory pointed at in a specific ordering.
@@ -721,7 +725,11 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata
void free_libblock(ListBase *lb, void *idv)
{
ID *id= idv;
-
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
switch( GS(id->name) ) { /* GetShort from util.h */
case ID_SCE:
free_scene((Scene *)id);
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index f4899849702..7901957e5e4 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -93,6 +93,8 @@ void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result);
void BPY_context_set(struct bContext *C);
+void BPY_id_release(struct ID *id);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 561cc289e62..bc216207821 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -94,17 +94,54 @@ static int pyrna_prop_validity_check(BPy_PropertyRNA *self)
return -1;
}
-/*
-static void pyrna_struct_invalidate(BPy_StructRNA *self)
+static void pyrna_invalidate(BPy_DummyPointerRNA *self)
{
- self->ptr.type= NULL;
+ self->ptr.type= NULL; /* this is checked for validity */
+ self->ptr.id.data= NULL; /* should not be needed but prevent bad pointer access, just incase */
+}
+
+#ifdef USE_PYRNA_INVALIDATE_GC
+#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
+
+/* only for sizeof() */
+struct gc_generation {
+ PyGC_Head head;
+ int threshold;
+ int count;
+} gc_generation;
+
+static void id_release_gc(struct ID *id)
+{
+ unsigned int j;
+ // unsigned int i= 0;
+ for(j=0; j<3; j++) {
+ /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */
+ PyGC_Head *gen= (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
+ PyGC_Head *g = gen->gc.gc_next;
+ while ((g= g->gc.gc_next) != gen) {
+ PyObject *ob= FROM_GC(g);
+ if(PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
+ BPy_DummyPointerRNA *ob_ptr= (BPy_DummyPointerRNA *)ob;
+ if(ob_ptr->ptr.id.data == id) {
+ pyrna_invalidate(ob_ptr);
+ // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
+ // i++;
+ }
+ }
+ }
+ }
+ // printf("id_release_gc freed '%s': %d\n", id->name, i);
}
+#endif
+
-static void pyrna_prop_invalidate(BPy_PropertyRNA *self)
+void BPY_id_release(struct ID *id)
{
- self->ptr.type= NULL;
+ (void)id;
+#ifdef USE_PYRNA_INVALIDATE_GC
+ id_release_gc(id);
+#endif
}
-*/
#ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes= FALSE;
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index fe30529f680..8d9fabf5627 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -44,6 +44,9 @@ extern PyTypeObject pyrna_prop_collection_Type;
#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
+/* method to invalidate removed py data, XXX, slow to remove objects, otherwise no overhead */
+// #define USE_PYRNA_INVALIDATE_GC
+
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
// #define USE_WEAKREFS