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:
authorBastien Montagne <montagne29@wanadoo.fr>2018-11-14 19:04:10 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-11-14 19:07:02 +0300
commitb44e6f2b3d32e604c3030eaf61b15e0e2a20d520 (patch)
tree808c31a00f1771e700435d8201fd1159489494b5 /source/blender/makesrna/intern/rna_depsgraph.c
parentd2dd278c5e2f4d41bc94df7fca959cca6d2526d0 (diff)
Fix T57760: Depsgraph 'object_instances' showing incorrect list of objects.
It appears that Python gets next item before using current one, which would break our Depsgraph instance iterator (since only current item is valid there, we use the same memory at each iteration). Working around that with an ugly ping-pong game between two sets of iterator data, so that previous one (C RNA-iterator-wise) remains valid memory for Python to access to.
Diffstat (limited to 'source/blender/makesrna/intern/rna_depsgraph.c')
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index 7bfd3f679d8..4c455915361 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -280,38 +280,59 @@ static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter)
* Contains extra information about duplicator and persistent ID.
*/
+/* XXX Ugly python seems to query next item of an iterator before using current one (see T57558).
+ * This forces us to use that nasty ping-pong game between two sets of iterator data, so that previous one remains
+ * valid memory for python to access to. Yuck.
+ */
+typedef struct RNA_Depsgraph_Instances_Iterator
+{
+ BLI_Iterator iterators[2];
+ DEGObjectIterData deg_data[2];
+ int counter;
+} RNA_Depsgraph_Instances_Iterator;
+
static void rna_Depsgraph_object_instances_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
- DEGObjectIterData *data = MEM_callocN(sizeof(DEGObjectIterData), __func__);
+ RNA_Depsgraph_Instances_Iterator *di_it = iter->internal.custom = MEM_callocN(sizeof(*di_it), __func__);
+ DEGObjectIterData *data = &di_it->deg_data[0];
data->graph = (Depsgraph *)ptr->data;
data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_DUPLI;
- ((BLI_Iterator *)iter->internal.custom)->valid = true;
- DEG_iterator_objects_begin(iter->internal.custom, data);
- iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
+ di_it->iterators[0].valid = true;
+ DEG_iterator_objects_begin(&di_it->iterators[0], data);
+ iter->valid = di_it->iterators[0].valid;
}
static void rna_Depsgraph_object_instances_next(CollectionPropertyIterator *iter)
{
- DEG_iterator_objects_next(iter->internal.custom);
- iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
+ RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *)iter->internal.custom;
+
+ /* We need to copy current iterator status to next one beeing worked on. */
+ di_it->iterators[(di_it->counter + 1) % 2] = di_it->iterators[di_it->counter % 2];
+ di_it->deg_data[(di_it->counter + 1) % 2] = di_it->deg_data[di_it->counter % 2];
+ di_it->counter++;
+
+ di_it->iterators[di_it->counter % 2].data = &di_it->deg_data[di_it->counter % 2];
+ DEG_iterator_objects_next(&di_it->iterators[di_it->counter % 2]);
+ iter->valid = di_it->iterators[di_it->counter % 2].valid;
}
static void rna_Depsgraph_object_instances_end(CollectionPropertyIterator *iter)
{
- DEG_iterator_objects_end(iter->internal.custom);
- MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
- MEM_freeN(iter->internal.custom);
+ RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *)iter->internal.custom;
+ DEG_iterator_objects_end(&di_it->iterators[0]);
+ DEG_iterator_objects_end(&di_it->iterators[1]);
+ MEM_freeN(di_it);
}
static PointerRNA rna_Depsgraph_object_instances_get(CollectionPropertyIterator *iter)
{
- BLI_Iterator *iterator = (BLI_Iterator *)iter->internal.custom;
+ RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *)iter->internal.custom;
+ BLI_Iterator *iterator = &di_it->iterators[di_it->counter % 2];
return rna_pointer_inherit_refine(&iter->parent, &RNA_DepsgraphObjectInstance, iterator);
}