Depsgraph: Fix filtering-related crashes
* Simplified operation-relation deletion. Now we collect the relations to delete into a vector, then iterate through that, thus solving issues with iterator invalidation (+ aborts arising from that) * DEG_foreach_ancestor_ID() was assuming that all dependencies were OperationDepsNodes, when in fact, some could be TimeSource nodes
This commit is contained in:
parent
9a0ef0933d
commit
6ec933886c
|
@ -93,22 +93,19 @@ void deg_add_retained_id_cb(ID *id, void *user_data)
|
|||
/* TODO: Make this part of OperationDepsNode? */
|
||||
void deg_unlink_opnode(OperationDepsNode *op_node)
|
||||
{
|
||||
/* Delete inlinks to this operation */
|
||||
for (DepsNode::Relations::const_iterator it_rel = op_node->inlinks.begin();
|
||||
it_rel != op_node->inlinks.end();
|
||||
)
|
||||
{
|
||||
DepsRelation *rel = *it_rel;
|
||||
rel->unlink();
|
||||
OBJECT_GUARDED_DELETE(rel, DepsRelation);
|
||||
std::vector<DepsRelation *> all_links;
|
||||
|
||||
/* Collect all inlinks to this operation */
|
||||
foreach (DepsRelation *rel, op_node->inlinks) {
|
||||
all_links.push_back(rel);
|
||||
}
|
||||
/* Collect all outlinks from this operation */
|
||||
foreach (DepsRelation *rel, op_node->outlinks) {
|
||||
all_links.push_back(rel);
|
||||
}
|
||||
|
||||
/* Delete outlinks from this operation */
|
||||
for (DepsNode::Relations::const_iterator it_rel = op_node->outlinks.begin();
|
||||
it_rel != op_node->outlinks.end();
|
||||
)
|
||||
{
|
||||
DepsRelation *rel = *it_rel;
|
||||
/* Delete all collected entries */
|
||||
foreach (DepsRelation *rel, all_links) {
|
||||
rel->unlink();
|
||||
OBJECT_GUARDED_DELETE(rel, DepsRelation);
|
||||
}
|
||||
|
|
|
@ -178,21 +178,27 @@ static void deg_foreach_ancestor_ID(const Depsgraph *graph,
|
|||
}
|
||||
/* Schedule incoming operation nodes. */
|
||||
if (op_node->inlinks.size() == 1) {
|
||||
OperationDepsNode *from_node = (OperationDepsNode *)op_node->inlinks[0]->from;
|
||||
if (from_node->scheduled == false) {
|
||||
from_node->scheduled = true;
|
||||
op_node = from_node;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
DepsNode *from = op_node->inlinks[0]->from;
|
||||
if (from->get_class() == DEG_NODE_CLASS_OPERATION) {
|
||||
OperationDepsNode *from_node = (OperationDepsNode *)from;
|
||||
if (from_node->scheduled == false) {
|
||||
from_node->scheduled = true;
|
||||
op_node = from_node;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach (DepsRelation *rel, op_node->inlinks) {
|
||||
OperationDepsNode *from_node = (OperationDepsNode *)rel->from;
|
||||
if (from_node->scheduled == false) {
|
||||
queue.push_front(from_node);
|
||||
from_node->scheduled = true;
|
||||
DepsNode *from = rel->from;
|
||||
if (from->get_class() == DEG_NODE_CLASS_OPERATION) {
|
||||
OperationDepsNode *from_node = (OperationDepsNode *)from;
|
||||
if (from_node->scheduled == false) {
|
||||
queue.push_front(from_node);
|
||||
from_node->scheduled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue