renderer: unqueue deleted node inputs
Fixes segfault when renderer tries to update from a since deleted node input.
This commit is contained in:
@@ -549,68 +549,6 @@ void TrackOutput::BlockConnected(NodeEdgePtr edge)
|
||||
UpdateInOutFrom(new_index);
|
||||
|
||||
InputConnectionChanged(edge);
|
||||
|
||||
/*
|
||||
// Determine what node was just connected
|
||||
Node* connected_node = edge->output()->parentNode();
|
||||
|
||||
// If this node is a block, we can do something with it
|
||||
if (connected_node->IsBlock()) {
|
||||
Block* connected_block = static_cast<Block*>(connected_node);
|
||||
|
||||
// See where this input falls in our internal "block cache"
|
||||
Block* next = nullptr;
|
||||
for (int i=block_input_->IndexOfSubParameter(edge->input())+1; i<block_input_->GetSize(); i++) {
|
||||
Node* that_node = block_input_->At(i)->get_connected_node();
|
||||
|
||||
// If we find a block, this is the block that will follow the one just connected
|
||||
if (that_node && that_node->IsBlock()) {
|
||||
next = static_cast<Block*>(that_node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int real_block_index;
|
||||
|
||||
// Either insert or append depending on if we found a "next" block
|
||||
if (next) {
|
||||
// Insert block before this next block
|
||||
real_block_index = block_cache_.indexOf(next);
|
||||
block_cache_.insert(real_block_index, connected_block);
|
||||
|
||||
// Update values with next
|
||||
next->set_previous(connected_block);
|
||||
connected_block->set_next(next);
|
||||
} else {
|
||||
// No "next", this block must come at the end
|
||||
real_block_index = block_cache_.size();
|
||||
block_cache_.append(connected_block);
|
||||
|
||||
// Update next value
|
||||
connected_block->set_next(nullptr);
|
||||
}
|
||||
|
||||
// For all blocks after the block we inserted (including it), update the "previous" and "next"
|
||||
// fields as well as the in/out values
|
||||
if (real_block_index == 0) {
|
||||
connected_block->set_previous(nullptr);
|
||||
} else {
|
||||
Block* prev = block_cache_.at(real_block_index - 1);
|
||||
|
||||
connected_block->set_previous(prev);
|
||||
prev->set_next(connected_block);
|
||||
}
|
||||
|
||||
UpdateInOutFrom(real_block_index);
|
||||
|
||||
// Make connections to this block
|
||||
connect(connected_block, &Block::LengthChanged, this, &TrackOutput::BlockLengthChanged);
|
||||
|
||||
emit BlockAdded(connected_block);
|
||||
}
|
||||
|
||||
InputConnectionChanged(edge);
|
||||
*/
|
||||
}
|
||||
|
||||
void TrackOutput::BlockDisconnected(NodeEdgePtr edge)
|
||||
@@ -647,36 +585,6 @@ void TrackOutput::BlockDisconnected(NodeEdgePtr edge)
|
||||
emit BlockRemoved(b);
|
||||
}
|
||||
|
||||
/*
|
||||
// See what kind of node was just connected
|
||||
Node* connected_node = edge->output()->parentNode();
|
||||
|
||||
// If this was a block, we would have put it in our block cache in BlockConnected()
|
||||
int index_of_block = block_cache_.indexOf(static_cast<Block*>(connected_node));
|
||||
if (index_of_block > -1) {
|
||||
Block* connected_block = static_cast<Block*>(connected_node);
|
||||
|
||||
// Determine what index this block was in our cache and remove it
|
||||
block_cache_.removeAt(index_of_block);
|
||||
|
||||
// If there were blocks following this one, update their ins/outs
|
||||
UpdateInOutFrom(index_of_block);
|
||||
|
||||
// Join the previous and next blocks together
|
||||
if (connected_block->previous()) {
|
||||
connected_block->previous()->set_next(connected_block->next());
|
||||
}
|
||||
|
||||
if (connected_block->next()) {
|
||||
connected_block->next()->set_previous(connected_block->previous());
|
||||
}
|
||||
|
||||
disconnect(connected_block, &Block::LengthChanged, this, &TrackOutput::BlockLengthChanged);
|
||||
|
||||
emit BlockRemoved(connected_block);
|
||||
}
|
||||
*/
|
||||
|
||||
InputConnectionChanged(edge);
|
||||
}
|
||||
|
||||
|
||||
@@ -324,10 +324,13 @@ void RenderBackend::NodeGraphChanged(NodeInput *source)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this dependency graph is already queued
|
||||
if (source->parentNode()->OutputsTo(queued_input, true, true)) {
|
||||
// In which case, no further copy is necessary
|
||||
return;
|
||||
// Check if this input supersedes an already queued input
|
||||
if ((source->IsArray() && static_cast<NodeInputArray*>(source)->sub_params().contains(queued_input))
|
||||
|| queued_input->parentNode()->OutputsTo(source, true, true)) {
|
||||
// In which case, we don't need to queue it and can queue our own
|
||||
graph_update_queue_.removeAt(i);
|
||||
disconnect(queued_input, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
|
||||
i--;
|
||||
}
|
||||
|
||||
// Check if the source is a member of this array, in which case it'll be copied eventually anyway
|
||||
@@ -336,16 +339,15 @@ void RenderBackend::NodeGraphChanged(NodeInput *source)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this input supersedes an already queued input
|
||||
if (queued_input->parentNode()->OutputsTo(source, true, true)
|
||||
|| (source->IsArray() && static_cast<NodeInputArray*>(source)->sub_params().contains(queued_input))) {
|
||||
// In which case, we don't need to queue it and can queue our own
|
||||
graph_update_queue_.removeAt(i);
|
||||
i--;
|
||||
// Check if this dependency graph is already queued
|
||||
if (source->parentNode()->OutputsTo(queued_input, true, true)) {
|
||||
// In which case, no further copy is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
graph_update_queue_.append(source);
|
||||
connect(source, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
|
||||
}
|
||||
|
||||
void RenderBackend::Close()
|
||||
@@ -668,6 +670,13 @@ void RenderBackend::AutoCacheVideoDownloaded()
|
||||
delete watcher;
|
||||
}
|
||||
|
||||
void RenderBackend::QueuedInputRemoved()
|
||||
{
|
||||
NodeInput* i = static_cast<NodeInput*>(sender());
|
||||
disconnect(i, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
|
||||
graph_update_queue_.removeOne(i);
|
||||
}
|
||||
|
||||
//#define PRINT_UPDATE_QUEUE_INFO
|
||||
void RenderBackend::ProcessUpdateQueue()
|
||||
{
|
||||
@@ -681,6 +690,8 @@ void RenderBackend::ProcessUpdateQueue()
|
||||
#ifdef PRINT_UPDATE_QUEUE_INFO
|
||||
qDebug() << " " << i->parentNode()->id() << i->id();
|
||||
#endif
|
||||
disconnect(i, &NodeInput::destroyed, this, &RenderBackend::QueuedInputRemoved);
|
||||
|
||||
CopyNodeInputValue(i);
|
||||
}
|
||||
|
||||
|
||||
@@ -246,6 +246,8 @@ private slots:
|
||||
|
||||
void AutoCacheVideoDownloaded();
|
||||
|
||||
void QueuedInputRemoved();
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
Reference in New Issue
Block a user