Fix (unreported) fully broken bpy.data.user_map() helper.

The introduction of python instancing for ID data in 2.80 completely
broke the 'smart & efficient' hack of using a same py object as key for
initial quick check, since rebuilding the RNAPointer in the
BPy_StructRNA would actually affect the py instance of the first ID used
to generate that py object...

TL;DR: No need for this complex and unclear optimization anymore, since
we do not actually rebuild a whole py object anymore every time we call
`pyrna_id_CreatePyObject()` from a same ID pointer.
This commit is contained in:
Bastien Montagne
2020-02-13 16:14:45 +01:00
parent c9c013f53b
commit 3ec3c5b557

View File

@@ -55,10 +55,6 @@
#include "bpy_rna.h" #include "bpy_rna.h"
typedef struct IDUserMapData { typedef struct IDUserMapData {
/** Place-holder key only used for lookups to avoid creating new data only for lookups
* (never return its contents) */
PyObject *py_id_key_lookup_only;
/** We loop over data-blocks that this ID points to (do build a reverse lookup table) */ /** We loop over data-blocks that this ID points to (do build a reverse lookup table) */
PyObject *py_id_curr; PyObject *py_id_curr;
ID *id_curr; ID *id_curr;
@@ -102,28 +98,20 @@ static int foreach_libblock_id_user_map_callback(LibraryIDLinkCallbackData *cb_d
return IDWALK_RET_NOP; return IDWALK_RET_NOP;
} }
/* pyrna_struct_hash() uses ptr.data only, PyObject *key = pyrna_id_CreatePyObject(*id_p);
* but pyrna_struct_richcmp() uses also ptr.type,
* so we need to create a valid PointerRNA here...
*/
PyObject *key = data->py_id_key_lookup_only;
RNA_id_pointer_create(*id_p, &((BPy_StructRNA *)key)->ptr);
PyObject *set; PyObject *set;
if ((set = PyDict_GetItem(data->user_map, key)) == NULL) { if ((set = PyDict_GetItem(data->user_map, key)) == NULL) {
/* limit to key's added already */ /* limit to key's added already */
if (data->is_subset) { if (data->is_subset) {
return IDWALK_RET_NOP; return IDWALK_RET_NOP;
} }
/* Cannot use our placeholder key here! */
key = pyrna_id_CreatePyObject(*id_p);
set = PySet_New(NULL); set = PySet_New(NULL);
PyDict_SetItem(data->user_map, key, set); PyDict_SetItem(data->user_map, key, set);
Py_DECREF(set); Py_DECREF(set);
Py_DECREF(key);
} }
Py_DECREF(key);
if (data->py_id_curr == NULL) { if (data->py_id_curr == NULL) {
data->py_id_curr = pyrna_id_CreatePyObject(data->id_curr); data->py_id_curr = pyrna_id_CreatePyObject(data->id_curr);
@@ -232,34 +220,23 @@ static PyObject *bpy_user_map(PyObject *UNUSED(self), PyObject *args, PyObject *
} }
} }
/* One-time init, ID is just used as placeholder here, we abuse this in iterator callback
* to avoid having to rebuild a complete bpyrna object each time for the key searching
* (where only ID pointer value is used). */
if (data_cb.py_id_key_lookup_only == NULL) {
data_cb.py_id_key_lookup_only = pyrna_id_CreatePyObject(id);
}
if (!data_cb.is_subset && if (!data_cb.is_subset &&
/* We do not want to pre-add keys of flitered out types. */ /* We do not want to pre-add keys of flitered out types. */
(key_types_bitmap == NULL || id_check_type(id, key_types_bitmap)) && (key_types_bitmap == NULL || id_check_type(id, key_types_bitmap)) &&
/* We do not want to pre-add keys when we have filter on value types, /* We do not want to pre-add keys when we have filter on value types,
* but not on key types. */ * but not on key types. */
(val_types_bitmap == NULL || key_types_bitmap != NULL)) { (val_types_bitmap == NULL || key_types_bitmap != NULL)) {
PyObject *key = data_cb.py_id_key_lookup_only; PyObject *key = pyrna_id_CreatePyObject(id);
PyObject *set; PyObject *set;
RNA_id_pointer_create(id, &((BPy_StructRNA *)key)->ptr);
/* We have to insert the key now, /* We have to insert the key now,
* otherwise ID unused would be missing from final dict... */ * otherwise ID unused would be missing from final dict... */
if ((set = PyDict_GetItem(data_cb.user_map, key)) == NULL) { if ((set = PyDict_GetItem(data_cb.user_map, key)) == NULL) {
/* Cannot use our placeholder key here! */
key = pyrna_id_CreatePyObject(id);
set = PySet_New(NULL); set = PySet_New(NULL);
PyDict_SetItem(data_cb.user_map, key, set); PyDict_SetItem(data_cb.user_map, key, set);
Py_DECREF(set); Py_DECREF(set);
Py_DECREF(key);
} }
Py_DECREF(key);
} }
if (val_types_bitmap != NULL && !id_check_type(id, val_types_bitmap)) { if (val_types_bitmap != NULL && !id_check_type(id, val_types_bitmap)) {
@@ -282,10 +259,6 @@ static PyObject *bpy_user_map(PyObject *UNUSED(self), PyObject *args, PyObject *
ret = data_cb.user_map; ret = data_cb.user_map;
error: error:
if (data_cb.py_id_key_lookup_only != NULL) {
Py_XDECREF(data_cb.py_id_key_lookup_only);
}
if (key_types_bitmap != NULL) { if (key_types_bitmap != NULL) {
MEM_freeN(key_types_bitmap); MEM_freeN(key_types_bitmap);
} }