don't copy items when splitting or duplicating blocks

This commit is contained in:
itsmattkc
2021-03-01 13:27:13 +11:00
parent 605a593f90
commit a57bf35e93
6 changed files with 88 additions and 80 deletions
+68 -3
View File
@@ -1105,6 +1105,71 @@ void Node::CopyDependencyGraph(const QVector<Node *> &src, const QVector<Node *>
}
}
Node *Node::CopyNodeAndDependencyGraphMinusItemsInternal(QMap<const Node*, Node*>& created, const Node *node, MultiUndoCommand *command)
{
// Make a new node of the same type
Node* copy = node->copy();
// Add to map
created.insert(node, copy);
// Copy values to the clone
CopyInputs(node, copy, false);
// Add it to the same graph
command->add_child(new NodeAddCommand(node->parent(), copy));
// Go through input connections and copy if non-item and connect if item
for (auto it=node->input_connections_.cbegin(); it!=node->input_connections_.cend(); it++) {
NodeInput input = it->first;
NodeOutput output = it->second;
Node* connected = output.node();
Node* connected_copy;
if (dynamic_cast<Item*>(connected)) {
// This is an item and we avoid copying those and just connect to them directly
connected_copy = connected;
} else {
// Non-item, we want to clone this too
connected_copy = created.value(connected, nullptr);
if (!connected_copy) {
connected_copy = CopyNodeAndDependencyGraphMinusItemsInternal(created, connected, command);
}
}
command->add_child(new NodeEdgeAddCommand(NodeOutput(connected_copy, output.output()),
NodeInput(copy, input.input(), input.element())));
}
return copy;
}
Node *Node::CopyNodeAndDependencyGraphMinusItems(const Node *node, MultiUndoCommand *command)
{
QMap<const Node*, Node*> created;
return CopyNodeAndDependencyGraphMinusItemsInternal(created, node, command);
}
Node *Node::CopyNodeInGraph(const Node *node, MultiUndoCommand *command)
{
Node* copy;
if (Config::Current()[QStringLiteral("SplitClipsCopyNodes")].toBool()) {
copy = Node::CopyNodeAndDependencyGraphMinusItems(node, command);
} else {
copy = node->copy();
command->add_child(new NodeAddCommand(static_cast<NodeGraph*>(node->parent()),
copy));
command->add_child(new NodeCopyInputsCommand(node, copy, true));
}
return copy;
}
void Node::SendInvalidateCache(const TimeRange &range, qint64 job_time)
{
for (const OutputConnection& conn : output_connections_) {
@@ -1376,7 +1441,7 @@ void Node::Hash(const QString &output, QCryptographicHash &hash, const rational&
}
}
void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
void Node::CopyInputs(const Node *source, Node *destination, bool include_connections)
{
Q_ASSERT(source->id() == destination->id());
@@ -1388,7 +1453,7 @@ void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
destination->SetLabel(source->GetLabel());
}
void Node::CopyInput(Node *src, Node *dst, const QString &input, bool include_connections, bool traverse_arrays)
void Node::CopyInput(const Node *src, Node *dst, const QString &input, bool include_connections, bool traverse_arrays)
{
Q_ASSERT(src->id() == dst->id());
@@ -1419,7 +1484,7 @@ void Node::CopyInput(Node *src, Node *dst, const QString &input, bool include_co
}
}
void Node::CopyValuesOfElement(Node *src, Node *dst, const QString &input, int src_element, int dst_element)
void Node::CopyValuesOfElement(const Node *src, Node *dst, const QString &input, int src_element, int dst_element)
{
if (dst_element >= dst->GetInternalInputArraySize(input)) {
qDebug() << "Ignored destination element that was out of array bounds";
+10 -4
View File
@@ -640,12 +640,12 @@ public:
*
* Nodes must be of the same types (i.e. have the same ID)
*/
static void CopyInputs(Node* source, Node* destination, bool include_connections = true);
static void CopyInputs(const Node *source, Node* destination, bool include_connections = true);
static void CopyInput(Node* src, Node* dst, const QString& input, bool include_connections, bool traverse_arrays);
static void CopyInput(const Node *src, Node* dst, const QString& input, bool include_connections, bool traverse_arrays);
static void CopyValuesOfElement(Node* src, Node* dst, const QString& input, int src_element, int dst_element);
static void CopyValuesOfElement(Node* src, Node* dst, const QString& input, int element)
static void CopyValuesOfElement(const Node* src, Node* dst, const QString& input, int src_element, int dst_element);
static void CopyValuesOfElement(const Node* src, Node* dst, const QString& input, int element)
{
return CopyValuesOfElement(src, dst, input, element, element);
}
@@ -656,6 +656,10 @@ public:
static QVector<Node*> CopyDependencyGraph(const QVector<Node*>& nodes, MultiUndoCommand *command);
static void CopyDependencyGraph(const QVector<Node*>& src, const QVector<Node*>& dst, MultiUndoCommand *command);
static Node* CopyNodeAndDependencyGraphMinusItems(const Node* node, MultiUndoCommand* command);
static Node* CopyNodeInGraph(const Node* node, MultiUndoCommand* command);
/**
* @brief Return whether this Node can be deleted or not
*/
@@ -1048,6 +1052,8 @@ private:
void ArrayResizeInternal(const QString& id, int size);
static Node *CopyNodeAndDependencyGraphMinusItemsInternal(QMap<const Node*, Node*>& created, const Node *node, MultiUndoCommand *command);
/**
* @brief Immediates aren't deleted, so the actual array size may be larger than ArraySize()
*/
+1 -1
View File
@@ -112,7 +112,7 @@ Project *NodeAddCommand::GetRelevantProject() const
return dynamic_cast<Project*>(graph_);
}
NodeCopyInputsCommand::NodeCopyInputsCommand(Node *src, Node *dest, bool include_connections) :
NodeCopyInputsCommand::NodeCopyInputsCommand(const Node *src, Node *dest, bool include_connections) :
src_(src),
dest_(dest),
include_connections_(include_connections)
+2 -2
View File
@@ -203,7 +203,7 @@ private:
class NodeCopyInputsCommand : public UndoCommand {
public:
NodeCopyInputsCommand(Node* src,
NodeCopyInputsCommand(const Node* src,
Node* dest,
bool include_connections);
@@ -214,7 +214,7 @@ public:
virtual Project* GetRelevantProject() const override {return nullptr;}
private:
Node* src_;
const Node* src_;
Node* dest_;
+6 -52
View File
@@ -488,6 +488,7 @@ class BlockSplitCommand : public UndoCommand {
public:
BlockSplitCommand(Block* block, rational point) :
block_(block),
new_block_(nullptr),
point_(point),
reconnect_tree_command_(nullptr)
{
@@ -508,7 +509,7 @@ public:
*/
Block* new_block()
{
return static_cast<Block*>(added_nodes_.first());
return new_block_;
}
virtual void redo() override
@@ -517,47 +518,9 @@ public:
Q_ASSERT(point_ > block_->in() && point_ < block_->out());
// Determine if we're copying the dependencies as part of this command
bool copy_dependencies_too = Config::Current()[QStringLiteral("SplitClipsCopyNodes")].toBool();
// Copy nodes if we haven't already done it
if (added_nodes_.isEmpty()) {
if (copy_dependencies_too) {
src_nodes_.append(block_);
src_nodes_.append(block_->GetDependencies());
added_nodes_.resize(src_nodes_.size());
for (int i=0; i<added_nodes_.size(); i++) {
// Copy dependency
Node* copy = src_nodes_[i]->copy();
// Copy inputs
Node::CopyInputs(src_nodes_[i], copy, false);
// Keep in array
added_nodes_[i] = copy;
}
} else {
// Just copy the block itself
added_nodes_.append(block_->copy());
}
}
// Add all new nodes to the graph
foreach (Node* n, added_nodes_) {
n->setParent(block_->parent());
}
if (!reconnect_tree_command_) {
if (copy_dependencies_too) {
// Create equivalent connections among our copied dependency tree
reconnect_tree_command_ = new MultiUndoCommand();
Node::CopyDependencyGraph(src_nodes_, added_nodes_, static_cast<MultiUndoCommand*>(reconnect_tree_command_));
} else {
reconnect_tree_command_ = new NodeCopyInputsCommand(block_, new_block(), true);
}
reconnect_tree_command_ = new MultiUndoCommand();
new_block_ = static_cast<Block*>(Node::CopyNodeInGraph(block_, reconnect_tree_command_));
}
reconnect_tree_command_->redo();
@@ -612,29 +575,20 @@ public:
// If we ran a reconnect command, disconnect now
reconnect_tree_command_->undo();
foreach (Node* n, added_nodes_) {
// Remove nodes
n->setParent(&memory_manager_);
}
track->EndOperation();
}
private:
Block* block_;
Block* new_block_;
rational old_length_;
rational point_;
QObject memory_manager_;
UndoCommand* reconnect_tree_command_;
MultiUndoCommand* reconnect_tree_command_;
NodeInput moved_transition_;
QVector<Node*> src_nodes_;
QVector<Node*> added_nodes_;
};
class BlockSplitPreservingLinksCommand : public UndoCommand {
+1 -18
View File
@@ -622,25 +622,8 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
if (duplicate_clips) {
// Duplicate rather than move
Node* copy;
if (Config::Current()[QStringLiteral("SplitClipsCopyNodes")].toBool()) {
QVector<Node*> nodes_to_clone;
nodes_to_clone.append(block);
nodes_to_clone.append(block->GetDependencies());
QVector<Node*> duplicated = Node::CopyDependencyGraph(nodes_to_clone, command);
copy = duplicated.first();
} else {
copy = block->copy();
command->add_child(new NodeAddCommand(static_cast<NodeGraph*>(block->parent()),
copy));
command->add_child(new NodeCopyInputsCommand(block, copy, true));
}
// Place the copy instead of the original block
block = static_cast<Block*>(copy);
block = static_cast<Block*>(Node::CopyNodeInGraph(block, command));
}
const Track::Reference& track_ref = p.ghost->GetAdjustedTrack();