diff --git a/app/node/connectable.h b/app/node/connectable.h index 6d496a4be..cada64d43 100644 --- a/app/node/connectable.h +++ b/app/node/connectable.h @@ -62,15 +62,6 @@ public: int element; }; -signals: - void OutputConnected(NodeInput* destination, int element); - - void OutputDisconnected(NodeInput* destination, int element); - - void InputConnected(Node* source, int element); - - void InputDisconnected(Node* source, int element); - protected: const std::vector& output_connections() const { diff --git a/app/node/graph.cpp b/app/node/graph.cpp index 865c0663e..9036a2d70 100644 --- a/app/node/graph.cpp +++ b/app/node/graph.cpp @@ -28,10 +28,9 @@ NodeGraph::NodeGraph() void NodeGraph::Clear() { - foreach (Node* node, node_children_) { - delete node; + while (!node_children_.isEmpty()) { + delete node_children_.first(); } - node_children_.clear(); } void NodeGraph::childEvent(QChildEvent *event) @@ -45,12 +44,10 @@ void NodeGraph::childEvent(QChildEvent *event) node_children_.append(node); - // Connect to each input - foreach (NodeInput* input, node->parameters()) { - connect(input, &NodeInput::InputConnected, this, &NodeGraph::SignalInputConnected); - connect(input, &NodeInput::InputDisconnected, this, &NodeGraph::SignalInputDisconnected); - connect(input, &NodeInput::ValueChanged, this, &NodeGraph::SignalValueChanged); - } + // Connect signals + connect(node, &Node::InputConnected, this, &NodeGraph::InputConnected); + connect(node, &Node::InputDisconnected, this, &NodeGraph::InputDisconnected); + connect(node, &Node::ValueChanged, this, &NodeGraph::ValueChanged); emit NodeAdded(node); @@ -58,12 +55,10 @@ void NodeGraph::childEvent(QChildEvent *event) node_children_.removeOne(node); - // Disconnect from inputs - foreach (NodeInput* input, node->parameters()) { - disconnect(input, &NodeInput::InputConnected, this, &NodeGraph::SignalInputConnected); - disconnect(input, &NodeInput::InputDisconnected, this, &NodeGraph::SignalInputDisconnected); - disconnect(input, &NodeInput::ValueChanged, this, &NodeGraph::SignalValueChanged); - } + // Disconnect signals + disconnect(node, &Node::InputConnected, this, &NodeGraph::InputConnected); + disconnect(node, &Node::InputDisconnected, this, &NodeGraph::InputDisconnected); + disconnect(node, &Node::ValueChanged, this, &NodeGraph::ValueChanged); emit NodeRemoved(node); @@ -71,21 +66,4 @@ void NodeGraph::childEvent(QChildEvent *event) } } -void NodeGraph::SignalInputConnected(Node *output, int element) -{ - emit InputConnected(output, static_cast(sender()), element); -} - -void NodeGraph::SignalInputDisconnected(Node *output, int element) -{ - emit InputDisconnected(output, static_cast(sender()), element); -} - -void NodeGraph::SignalValueChanged(const TimeRange &range, int element) -{ - Q_UNUSED(range) - - emit ValueChanged(static_cast(sender()), element); -} - } diff --git a/app/node/graph.h b/app/node/graph.h index 0119cb073..c52eecdfa 100644 --- a/app/node/graph.h +++ b/app/node/graph.h @@ -77,13 +77,6 @@ protected: private: QVector node_children_; -private slots: - void SignalInputConnected(Node* output, int element); - - void SignalInputDisconnected(Node* output, int element); - - void SignalValueChanged(const TimeRange& range, int element); - }; } diff --git a/app/node/input.cpp b/app/node/input.cpp index d3db26080..b29a1065e 100644 --- a/app/node/input.cpp +++ b/app/node/input.cpp @@ -669,6 +669,7 @@ void NodeInput::CopyValuesOfElement(NodeInput *src, NodeInput *dst, int element) dst->SetSplitStandardValue(src->GetSplitStandardValue(element), element); // Copy keyframes + dst->GetImmediate(element)->delete_all_keyframes(); foreach (const NodeKeyframeTrack& track, src->GetImmediate(element)->keyframe_tracks()) { foreach (NodeKeyframe* key, track) { key->copy(dst); diff --git a/app/node/input.h b/app/node/input.h index 89ffe8c98..73f8e9a17 100644 --- a/app/node/input.h +++ b/app/node/input.h @@ -355,6 +355,10 @@ signals: void DataTypeChanged(NodeValue::Type type); + void InputConnected(Node* source, int element); + + void InputDisconnected(Node* source, int element); + protected: virtual bool event(QEvent* e) override; diff --git a/app/node/inputimmediate.cpp b/app/node/inputimmediate.cpp index c48e271f2..ee96c52be 100644 --- a/app/node/inputimmediate.cpp +++ b/app/node/inputimmediate.cpp @@ -240,4 +240,13 @@ void NodeInputImmediate::remove_keyframe(NodeKeyframe *key) keyframe_tracks_[key->track()].removeOne(key); } +void NodeInputImmediate::delete_all_keyframes() +{ + for (NodeKeyframeTrack& track : keyframe_tracks_) { + while (!track.isEmpty()) { + delete track.first(); + } + } +} + } diff --git a/app/node/inputimmediate.h b/app/node/inputimmediate.h index d9678e149..4650b9ee6 100644 --- a/app/node/inputimmediate.h +++ b/app/node/inputimmediate.h @@ -42,6 +42,8 @@ public: void remove_keyframe(NodeKeyframe* key); + void delete_all_keyframes(); + /** * @brief Get non-keyframed value split into components (the way it's stored) */ diff --git a/app/node/keyframe.cpp b/app/node/keyframe.cpp index 7eb7931c3..6703d4af0 100644 --- a/app/node/keyframe.cpp +++ b/app/node/keyframe.cpp @@ -38,6 +38,11 @@ NodeKeyframe::NodeKeyframe(const rational &time, const QVariant &value, const No setParent(parent); } +NodeKeyframe::~NodeKeyframe() +{ + setParent(nullptr); +} + NodeKeyframe *NodeKeyframe::copy(QObject* parent) const { NodeKeyframe* copy = new NodeKeyframe(time_, value_, type_, track_, element_, parent); diff --git a/app/node/keyframe.h b/app/node/keyframe.h index aa19c38d9..c99e8d522 100644 --- a/app/node/keyframe.h +++ b/app/node/keyframe.h @@ -63,6 +63,8 @@ public: */ NodeKeyframe(const rational& time, const QVariant& value, const Type& type, const int& track, int element, QObject* parent = nullptr); + virtual ~NodeKeyframe() override; + NodeKeyframe* copy(QObject* parent = nullptr) const; NodeInput* parent() const; diff --git a/app/node/node.cpp b/app/node/node.cpp index f712efe71..33c45de84 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -36,6 +36,8 @@ namespace olive { +#define super NodeConnectable + Node::Node() : can_be_deleted_(true), override_color_(-1) @@ -45,6 +47,8 @@ Node::Node() : Node::~Node() { DisconnectAll(); + + setParent(nullptr); } NodeGraph *Node::parent() const @@ -319,6 +323,11 @@ void Node::SendInvalidateCache(const TimeRange &range) } } +void Node::InvalidateAll(NodeInput* input, int element) +{ + InvalidateCache(TimeRange(RATIONAL_MIN, RATIONAL_MAX), {input, element}); +} + void Node::IgnoreInvalidationsFrom(NodeInput *input) { ignore_connections_.append(input); @@ -498,17 +507,30 @@ void Node::HashInputElement(QCryptographicHash &hash, NodeInput *input, int elem } } -void Node::InputConnectionChanged(Node *source, int element) +void Node::ParameterConnected(Node *source, int element) { - Q_UNUSED(source) - NodeInput* input = static_cast(sender()); + emit InputConnected(source, input, element); + if (ignore_connections_.contains(input)) { return; } - InvalidateCache(TimeRange(RATIONAL_MIN, RATIONAL_MAX), {input, element}); + InvalidateAll(input, element); +} + +void Node::ParameterDisconnected(Node *source, int element) +{ + NodeInput* input = static_cast(sender()); + + emit InputDisconnected(source, input, element); + + if (ignore_connections_.contains(input)) { + return; + } + + InvalidateAll(input, element); } QVector Node::GetDependencies() const @@ -764,10 +786,12 @@ void Node::SetPosition(const QPointF &pos) emit PositionChanged(position_); } -void Node::InputChanged(const TimeRange& range, int element) +void Node::ParameterValueChanged(const TimeRange& range, int element) { NodeInput* input = static_cast(sender()); + emit ValueChanged(input, element); + if (ignore_connections_.contains(input)) { return; } @@ -807,6 +831,8 @@ void Node::DrawAndExpandGizmoHandles(QPainter *p, int handle_radius, QRectF *rec void Node::childEvent(QChildEvent *event) { + super::childEvent(event); + NodeInput* input = dynamic_cast(event->child()); if (input) { @@ -817,17 +843,13 @@ void Node::childEvent(QChildEvent *event) // Keep main output as the last parameter, assume if there are no parameters that this is the output parameter inputs_.append(input); - connect(input, &NodeInput::InputConnected, this, &Node::InputConnected); - connect(input, &NodeInput::InputDisconnected, this, &Node::InputDisconnected); - connect(input, &NodeInput::ValueChanged, this, &Node::InputChanged); - connect(input, &NodeInput::InputConnected, this, &Node::InputConnectionChanged); - connect(input, &NodeInput::InputDisconnected, this, &Node::InputConnectionChanged); + connect(input, &NodeInput::ValueChanged, this, &Node::ParameterValueChanged); + connect(input, &NodeInput::InputConnected, this, &Node::ParameterConnected); + connect(input, &NodeInput::InputDisconnected, this, &Node::ParameterDisconnected); } else if (event->type() == QEvent::ChildRemoved) { - disconnect(input, &NodeInput::InputConnected, this, &Node::InputConnected); - disconnect(input, &NodeInput::InputDisconnected, this, &Node::InputDisconnected); - disconnect(input, &NodeInput::ValueChanged, this, &Node::InputChanged); - disconnect(input, &NodeInput::InputConnected, this, &Node::InputConnectionChanged); - disconnect(input, &NodeInput::InputDisconnected, this, &Node::InputConnectionChanged); + disconnect(input, &NodeInput::ValueChanged, this, &Node::ParameterValueChanged); + disconnect(input, &NodeInput::InputConnected, this, &Node::ParameterConnected); + disconnect(input, &NodeInput::InputDisconnected, this, &Node::ParameterDisconnected); inputs_.removeOne(input); } diff --git a/app/node/node.h b/app/node/node.h index 53cf9ef94..792b34313 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -427,6 +427,8 @@ public: return output_connections(); } + void InvalidateAll(NodeInput *input, int element); + protected: void SendInvalidateCache(const TimeRange &range); @@ -478,10 +480,15 @@ signals: void ColorChanged(); -public slots: - void InputChanged(const olive::TimeRange &range, int element); + void ValueChanged(NodeInput* input, int element); - void InputConnectionChanged(Node* source, int element); + void InputConnected(Node* output, NodeInput* input, int element); + + void InputDisconnected(Node* output, NodeInput* input, int element); + + void OutputConnected(NodeInput* destination, int element); + + void OutputDisconnected(NodeInput* destination, int element); private: template @@ -518,6 +525,13 @@ private: */ int override_color_; +private slots: + void ParameterValueChanged(const olive::TimeRange &range, int element); + + void ParameterConnected(Node* source, int element); + + void ParameterDisconnected(Node* source, int element); + }; template diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index ae0dfc7f9..c84c67dd7 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -515,7 +515,7 @@ void Track::BlockConnected(Node *node, int element) { if (element == -1) { // User has replaced the entire array, we will invalidate everything - InputConnectionChanged(node, element); + InvalidateAll(block_input_, element); return; } @@ -587,7 +587,7 @@ void Track::BlockDisconnected(Node* node, int element) { if (element == -1) { // User has replaced the entire array, we will invalidate everything - InputConnectionChanged(node, element); + InvalidateAll(block_input_, element); return; } diff --git a/app/node/output/track/tracklist.cpp b/app/node/output/track/tracklist.cpp index 33e651efa..48792fbf8 100644 --- a/app/node/output/track/tracklist.cpp +++ b/app/node/output/track/tracklist.cpp @@ -48,7 +48,7 @@ Track *TrackList::GetTrackAt(int index) const void TrackList::TrackConnected(Node *node, int element) { if (element == -1) { - parent()->InputConnectionChanged(node, element); + parent()->InvalidateAll(track_input_, element); return; } @@ -99,7 +99,7 @@ void TrackList::TrackDisconnected(Node *node, int element) { if (element == -1) { // User has replaced the entire array, we will invalidate everything - parent()->InputConnectionChanged(node, element); + parent()->InvalidateAll(track_input_, element); return; } diff --git a/app/project/item/item.cpp b/app/project/item/item.cpp index fdc6c667b..8d4b437ef 100644 --- a/app/project/item/item.cpp +++ b/app/project/item/item.cpp @@ -22,6 +22,8 @@ namespace olive { +#define super QObject + Item::Item() : item_parent_(nullptr), project_(nullptr) @@ -30,6 +32,7 @@ Item::Item() : Item::~Item() { + setParent(nullptr); } const QString &Item::name() const @@ -111,7 +114,7 @@ void Item::NameChangedEvent(const QString &) void Item::childEvent(QChildEvent *event) { - QObject::childEvent(event); + super::childEvent(event); Item* cast_test = dynamic_cast(event->child()); diff --git a/app/project/item/item.h b/app/project/item/item.h index 3547b0fb1..a410ff302 100644 --- a/app/project/item/item.h +++ b/app/project/item/item.h @@ -60,7 +60,7 @@ public: /** * @brief Required virtual Item destructor */ - virtual ~Item(); + virtual ~Item() override; virtual void Load(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled) = 0; diff --git a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp index 13e5203ef..32698c861 100644 --- a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp +++ b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp @@ -230,7 +230,7 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e) if (e) { // Enable keyframing - new NodeParamSetKeyframingCommand(input_, true, command); + new NodeParamSetKeyframingCommand(input_, element_, true, command); // Create one keyframe across all tracks here const QVector& key_vals = input_->GetSplitStandardValue(element_); @@ -267,7 +267,7 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e) } // Disable keyframing - new NodeParamSetKeyframingCommand(input_, false, command); + new NodeParamSetKeyframingCommand(input_, element_, false, command); } else { // Disable action has effectively been ignored