use strings to connect nodes

This makes the node system somewhat more high-level with the intent of making
working with them far more flexible and stable. By making the architecture more
abstracted, it becomes far less rigid which should allow us to do even more
with it and make it much less crash prone.
This commit is contained in:
itsmattkc
2021-02-09 15:48:37 +11:00
parent d1a3e22eaa
commit 81c1922911
138 changed files with 4487 additions and 3913 deletions
+24 -25
View File
@@ -40,7 +40,6 @@ NodeView::NodeView(QWidget *parent) :
drop_edge_(nullptr),
create_edge_(nullptr),
create_edge_dst_(nullptr),
create_edge_dst_input_(nullptr),
create_edge_dst_temp_expanded_(false),
filter_mode_(kFilterShowSelectedBlocks),
scale_(1.0)
@@ -103,10 +102,8 @@ void NodeView::SetGraph(NodeGraph *graph)
}
foreach (Node* n, graph_->nodes()) {
foreach (NodeInput* input, n->parameters()) {
for (auto it=input->edges().cbegin(); it!=input->edges().cend(); it++) {
scene_.AddEdge(it->second, input, it->first);
}
for (auto it=n->input_connections().cbegin(); it!=n->input_connections().cend(); it++) {
scene_.AddEdge(it->second, it->first);
}
}
}
@@ -124,7 +121,7 @@ void NodeView::DeleteSelected()
QVector<NodeViewEdge *> selected_edges = scene_.GetSelectedEdges();
foreach (NodeViewEdge* edge, selected_edges) {
command->add_child(new NodeEdgeRemoveCommand(edge->output(), edge->input(), edge->element()));
command->add_child(new NodeEdgeRemoveCommand(edge->output(), edge->input()));
}
}
@@ -426,18 +423,18 @@ void NodeView::mouseMoveEvent(QMouseEvent *event)
if (highlight_index >= 0) {
create_edge_dst_input_ = create_edge_dst_->GetInputAtIndex(highlight_index);
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
create_edge_dst_->GetInputPoint(highlight_index, create_edge_src_->pos()),
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(Node::kDefaultOutput),
create_edge_dst_->GetInputPoint(create_edge_dst_input_.input(), create_edge_dst_input_.element(), create_edge_src_->pos()),
true);
} else {
create_edge_dst_input_ = nullptr;
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
create_edge_dst_input_.Reset();
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(Node::kDefaultOutput),
scene_pt,
false);
}
// Set connected to whether we have a valid input destination
create_edge_->SetConnected(create_edge_dst_input_);
create_edge_->SetConnected(create_edge_dst_input_.IsValid());
return;
}
@@ -466,20 +463,22 @@ void NodeView::mouseMoveEvent(QMouseEvent *event)
new_drop_edge = dynamic_cast<NodeViewEdge*>(item);
if (new_drop_edge) {
drop_input_ = nullptr;
drop_input_.Reset();
foreach (NodeInput* input, attached_node->parameters()) {
if (input->IsConnectable()) {
if (input->GetDataType() == new_drop_edge->input()->GetDataType()) {
drop_input_ = input;
foreach (const QString& input, attached_node->inputs()) {
NodeInput i(attached_node, input);
if (attached_node->IsInputConnectable(input)) {
if (attached_node->GetInputDataType(input) == new_drop_edge->input().GetDataType()) {
drop_input_ = i;
break;
} else if (!drop_input_) {
drop_input_ = input;
} else if (!drop_input_.IsValid()) {
drop_input_ = i;
}
}
}
if (drop_input_) {
if (drop_input_.IsValid()) {
break;
} else {
new_drop_edge = nullptr;
@@ -519,10 +518,10 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
create_edge_dst_->SetExpanded(false);
}
if (create_edge_dst_input_) {
if (create_edge_dst_input_.IsValid()) {
// Make connection
Core::instance()->undo_stack()->push(new NodeEdgeAddCommand(create_edge_src_->GetNode(), create_edge_dst_input_, -1));
create_edge_dst_input_ = nullptr;
Core::instance()->undo_stack()->push(new NodeEdgeAddCommand(create_edge_src_->GetNode(), create_edge_dst_input_));
create_edge_dst_input_.Reset();
}
create_edge_dst_ = nullptr;
@@ -539,11 +538,11 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
MultiUndoCommand* command = new MultiUndoCommand();
// Remove old edge
command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input(), drop_edge_->element()));
command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input()));
// Place new edges
command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_, -1));
command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input(), drop_edge_->element()));
command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_));
command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input()));
Core::instance()->undo_stack()->push(command);
}
+2 -2
View File
@@ -107,12 +107,12 @@ private:
QList<AttachedItem> attached_items_;
NodeViewEdge* drop_edge_;
NodeInput* drop_input_;
NodeInput drop_input_;
NodeViewEdge* create_edge_;
NodeViewItem* create_edge_src_;
NodeViewItem* create_edge_dst_;
NodeInput* create_edge_dst_input_;
NodeInput create_edge_dst_input_;
bool create_edge_dst_temp_expanded_;
NodeViewScene scene_;
+3 -4
View File
@@ -33,13 +33,12 @@
namespace olive {
NodeViewEdge::NodeViewEdge(Node* output, NodeInput *input, int element,
NodeViewEdge::NodeViewEdge(const NodeOutput &output, const NodeInput &input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent) :
QGraphicsPathItem(parent),
output_(output),
input_(input),
element_(element),
from_item_(from_item),
to_item_(to_item)
{
@@ -56,8 +55,8 @@ NodeViewEdge::NodeViewEdge(QGraphicsItem *parent) :
void NodeViewEdge::Adjust()
{
// Draw a line between the two
SetPoints(from_item()->GetOutputPoint(),
to_item()->GetInputPoint(input_, from_item()->pos()),
SetPoints(from_item()->GetOutputPoint(output_.output()),
to_item()->GetInputPoint(input_.input(), input_.element(), from_item()->pos()),
to_item()->IsExpanded());
}
+5 -5
View File
@@ -39,18 +39,18 @@ class NodeViewItem;
class NodeViewEdge : public QGraphicsPathItem
{
public:
NodeViewEdge(Node* output, NodeInput *input, int element,
NodeViewEdge(const NodeOutput& output, const NodeInput& input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent = nullptr);
NodeViewEdge(QGraphicsItem* parent = nullptr);
Node* output() const
const NodeOutput& output() const
{
return output_;
}
NodeInput* input() const
const NodeInput& input() const
{
return input_;
}
@@ -112,9 +112,9 @@ protected:
private:
void Init();
Node* output_;
NodeOutput output_;
NodeInput* input_;
NodeInput input_;
int element_;
+6 -11
View File
@@ -187,8 +187,8 @@ void NodeViewItem::SetNode(Node *n)
if (node_) {
node_->Retranslate();
foreach (NodeInput* input, node_->parameters()) {
if (input->IsConnectable()) {
foreach (const QString& input, node_->inputs()) {
if (node_->IsInputConnectable(input)) {
node_inputs_.append(input);
}
}
@@ -258,7 +258,7 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
painter->fillRect(input_rect, highlight_col);
}
painter->drawText(input_rect, Qt::AlignCenter, node_inputs_.at(i)->name());
painter->drawText(input_rect, Qt::AlignCenter, node_->GetInputName(node_inputs_.at(i)));
}
}
@@ -430,17 +430,12 @@ QRectF NodeViewItem::GetInputRect(int index) const
return r;
}
QPointF NodeViewItem::GetInputPoint(NodeInput *input, const QPointF& source_pos) const
QPointF NodeViewItem::GetInputPoint(const QString &input, int element, const QPointF& source_pos) const
{
return GetInputPoint(node_inputs_.indexOf(input), source_pos);
return pos() + GetInputPointInternal(node_inputs_.indexOf(input), source_pos);
}
QPointF NodeViewItem::GetInputPoint(int input, const QPointF &source_pos) const
{
return pos() + GetInputPointInternal(input, source_pos);
}
QPointF NodeViewItem::GetOutputPoint() const
QPointF NodeViewItem::GetOutputPoint(const QString& output) const
{
switch (flow_dir_) {
case NodeViewCommon::kLeftToRight:
+5 -6
View File
@@ -78,10 +78,9 @@ public:
/**
* @brief Returns GLOBAL point that edges should connect to for any NodeParam member of this object
*/
QPointF GetInputPoint(NodeInput* input, const QPointF &source_pos) const;
QPointF GetInputPoint(int input, const QPointF &source_pos) const;
QPointF GetInputPoint(const QString& input, int element, const QPointF &source_pos) const;
QPointF GetOutputPoint() const;
QPointF GetOutputPoint(const QString &output) const;
/**
* @brief Sets the direction nodes are flowing
@@ -105,9 +104,9 @@ public:
int GetIndexAt(QPointF pt) const;
NodeInput* GetInputAtIndex(int index) const
NodeInput GetInputAtIndex(int index) const
{
return node_inputs_.at(index);
return NodeInput(node_, node_inputs_.at(index));
}
void SetHighlightedIndex(int index);
@@ -143,7 +142,7 @@ private:
/**
* @brief Cached list of node inputs
*/
QList<NodeInput*> node_inputs_;
QVector<QString> node_inputs_;
/**
* @brief Rectangle of the Node's title bar (equal to rect() when collapsed)
+8 -8
View File
@@ -98,10 +98,10 @@ NodeViewItem *NodeViewScene::NodeToUIObject(Node *n)
return item_map_.value(n);
}
NodeViewEdge *NodeViewScene::EdgeToUIObject(Node* output, NodeInput* input, int element)
NodeViewEdge *NodeViewScene::EdgeToUIObject(const NodeOutput& output, const NodeInput& input)
{
foreach (NodeViewEdge* edge, edges_) {
if (edge->output() == output && edge->input() == input && edge->element() == element) {
if (edge->output() == output && edge->input() == input) {
return edge;
}
}
@@ -174,14 +174,14 @@ void NodeViewScene::RemoveNode(Node *node)
delete item_map_.take(node);
}
void NodeViewScene::AddEdge(Node* output, NodeInput* input, int element)
void NodeViewScene::AddEdge(const NodeOutput &output, const NodeInput &input)
{
AddEdgeInternal(output, input, element, NodeToUIObject(output), NodeToUIObject(input->parent()));
AddEdgeInternal(output, input, NodeToUIObject(output.node()), NodeToUIObject(input.node()));
}
void NodeViewScene::RemoveEdge(Node* output, NodeInput* input, int element)
void NodeViewScene::RemoveEdge(const NodeOutput &output, const NodeInput &input)
{
NodeViewEdge* edge = EdgeToUIObject(output, input, element);
NodeViewEdge* edge = EdgeToUIObject(output, input);
edge->from_item()->RemoveEdge(edge);
edge->to_item()->RemoveEdge(edge);
edges_.removeOne(edge);
@@ -203,9 +203,9 @@ int NodeViewScene::DetermineWeight(Node *n)
return qMax(1, weight);
}
void NodeViewScene::AddEdgeInternal(Node *output, NodeInput *input, int element, NodeViewItem *from, NodeViewItem *to)
void NodeViewScene::AddEdgeInternal(const NodeOutput& output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to)
{
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, element, from, to);
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, from, to);
edge_ui->SetFlowDirection(direction_);
edge_ui->SetCurved(curved_edges_);
+4 -4
View File
@@ -53,7 +53,7 @@ public:
* in this view/scene), this function returns nullptr.
*/
NodeViewItem* NodeToUIObject(Node* n);
NodeViewEdge *EdgeToUIObject(Node* output, NodeInput *input, int element);
NodeViewEdge *EdgeToUIObject(const NodeOutput &output, const NodeInput &input);
QVector<Node *> GetSelectedNodes() const;
QVector<NodeViewItem*> GetSelectedItems() const;
@@ -98,8 +98,8 @@ public slots:
*/
void RemoveNode(Node* node);
void AddEdge(Node* output, NodeInput* input, int element);
void RemoveEdge(Node* output, NodeInput* input, int element);
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
/**
* @brief Set whether edges in this scene should be curved or not
@@ -109,7 +109,7 @@ public slots:
private:
static int DetermineWeight(Node* n);
void AddEdgeInternal(Node* output, NodeInput* input, int element, NodeViewItem* from, NodeViewItem* to);
void AddEdgeInternal(const NodeOutput &output, const NodeInput &input, NodeViewItem* from, NodeViewItem* to);
QHash<Node*, NodeViewItem*> item_map_;
+15 -21
View File
@@ -25,10 +25,9 @@
namespace olive {
NodeEdgeAddCommand::NodeEdgeAddCommand(Node *output, NodeInput *input, int element) :
NodeEdgeAddCommand::NodeEdgeAddCommand(const NodeOutput &output, const NodeInput &input) :
output_(output),
input_(input),
element_(element),
remove_command_(nullptr)
{
}
@@ -40,22 +39,20 @@ NodeEdgeAddCommand::~NodeEdgeAddCommand()
void NodeEdgeAddCommand::redo()
{
if (input_->IsConnected(element_)) {
if (input_.IsConnected()) {
if (!remove_command_) {
remove_command_ = new NodeEdgeRemoveCommand(input_->GetConnectedNode(element_),
input_,
element_);
remove_command_ = new NodeEdgeRemoveCommand(input_.GetConnectedOutput(), input_);
}
remove_command_->redo();
}
Node::ConnectEdge(output_, input_, element_);
Node::ConnectEdge(output_, input_);
}
void NodeEdgeAddCommand::undo()
{
Node::DisconnectEdge(output_, input_, element_);
Node::DisconnectEdge(output_, input_);
if (remove_command_) {
remove_command_->undo();
@@ -64,29 +61,28 @@ void NodeEdgeAddCommand::undo()
Project *NodeEdgeAddCommand::GetRelevantProject() const
{
return output_->parent()->project();
return output_.node()->parent()->project();
}
NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(Node *output, NodeInput *input, int element) :
NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(const NodeOutput &output, const NodeInput &input) :
output_(output),
input_(input),
element_(element)
input_(input)
{
}
void NodeEdgeRemoveCommand::redo()
{
Node::DisconnectEdge(output_, input_, element_);
Node::DisconnectEdge(output_, input_);
}
void NodeEdgeRemoveCommand::undo()
{
Node::ConnectEdge(output_, input_, element_);
Node::ConnectEdge(output_, input_);
}
Project *NodeEdgeRemoveCommand::GetRelevantProject() const
{
return output_->parent()->project();
return output_.node()->parent()->project();
}
NodeAddCommand::NodeAddCommand(NodeGraph *graph, Node *node) :
@@ -134,14 +130,12 @@ void NodeRemoveAndDisconnectCommand::prep()
}
// Disconnect everything
foreach (const Node::InputConnection& conn, node_->edges()) {
command_->add_child(new NodeEdgeRemoveCommand(node_, conn.input, conn.element));
for (auto it=node_->input_connections().cbegin(); it!=node_->input_connections().cend(); it++) {
command_->add_child(new NodeEdgeRemoveCommand(it->second, it->first));
}
foreach (NodeInput* input, node_->inputs()) {
for (auto it=input->edges().cbegin(); it!=input->edges().cend(); it++) {
command_->add_child(new NodeEdgeRemoveCommand(it->second, input, it->first));
}
for (const Node::OutputConnection& conn : node_->output_connections()) {
command_->add_child(new NodeEdgeRemoveCommand(conn.first, conn.second));
}
}
+6 -8
View File
@@ -34,7 +34,7 @@ namespace olive {
*/
class NodeEdgeRemoveCommand : public UndoCommand {
public:
NodeEdgeRemoveCommand(Node* output, NodeInput* input, int element);
NodeEdgeRemoveCommand(const NodeOutput& output, const NodeInput& input);
virtual Project* GetRelevantProject() const override;
@@ -42,9 +42,8 @@ public:
virtual void undo() override;
private:
Node* output_;
NodeInput* input_;
int element_;
NodeOutput output_;
NodeInput input_;
};
@@ -55,7 +54,7 @@ private:
*/
class NodeEdgeAddCommand : public UndoCommand {
public:
NodeEdgeAddCommand(Node* output, NodeInput* input, int element);
NodeEdgeAddCommand(const NodeOutput& output, const NodeInput& input);
virtual ~NodeEdgeAddCommand() override;
@@ -65,9 +64,8 @@ public:
virtual void undo() override;
private:
Node* output_;
NodeInput* input_;
int element_;
NodeOutput output_;
NodeInput input_;
NodeEdgeRemoveCommand* remove_command_;