NodeState 是 QtNodes 框架中负责管理节点连接状态和交互状态的核心类,它跟踪记录节点所有输入/输出连接以及当前的交互状态。
核心职责
-
连接管理:维护节点所有输入和输出连接的完整记录
-
交互状态跟踪:管理节点对连接操作的响应状态
-
数据类型匹配:在连接操作中跟踪涉及的数据类型
-
尺寸调整状态:跟踪节点是否正在被调整大小
#pragma once
#include "Export.hpp"
#include "NodeData.hpp"
#include "PortType.hpp"
#include "memory.hpp"
#include <QtCore/QUuid>
#include <unordered_map>
#include <vector>
namespace QtNodes
{
class Connection;
class NodeDataModel;
/// Contains vectors of connected input and output connections.
/// Stores bool for reacting on hovering connections
class NODE_EDITOR_PUBLIC NodeState
{
public:
enum ReactToConnectionState
{
REACTING,
NOT_REACTING
};
public:
NodeState(std::unique_ptr<NodeDataModel> const &model);
public:
using ConnectionPtrSet = std::unordered_map<QUuid, Connection *>;
/// Returns vector of connections ID.
/// Some of them can be empty (null)
std::vector<ConnectionPtrSet> const &getEntries(PortType) const;
std::vector<ConnectionPtrSet> &getEntries(PortType);
ConnectionPtrSet connections(PortType portType, PortIndex portIndex) const;
void setConnection(PortType portType, PortIndex portIndex, Connection &connection);
void eraseConnection(PortType portType, PortIndex portIndex, QUuid id);
ReactToConnectionState reaction() const;
PortType reactingPortType() const;
std::shared_ptr<NodeDataType> reactingDataType() const;
void setReaction(ReactToConnectionState reaction, PortType reactingPortType = PortType::None,
std::shared_ptr<NodeDataType> reactingDataType = std::make_shared<NodeDataType>());
bool isReacting() const;
void setResizing(bool resizing);
bool resizing() const;
private:
std::vector<ConnectionPtrSet> _inConnections;
std::vector<ConnectionPtrSet> _outConnections;
ReactToConnectionState _reaction;
PortType _reactingPortType;
std::shared_ptr<NodeDataType> _reactingDataType;
bool _resizing;
};
} // namespace QtNodes
#include "NodeState.hpp"
#include "Connection.hpp"
#include "NodeDataModel.hpp"
using QtNodes::Connection;
using QtNodes::NodeDataModel;
using QtNodes::NodeDataType;
using QtNodes::NodeState;
using QtNodes::PortIndex;
using QtNodes::PortType;
NodeState::NodeState(std::unique_ptr<NodeDataModel> const &model)
: _inConnections(model->nPorts(PortType::In)), _outConnections(model->nPorts(PortType::Out)), _reaction(NOT_REACTING),
_reactingPortType(PortType::None), _resizing(false)
{
}
std::vector<NodeState::ConnectionPtrSet> const &NodeState::getEntries(PortType portType) const
{
if (portType == PortType::In)
return _inConnections;
else
return _outConnections;
}
std::vector<NodeState::ConnectionPtrSet> &NodeState::getEntries(PortType portType)
{
if (portType == PortType::In)
return _inConnections;
else
return _outConnections;
}
NodeState::ConnectionPtrSet NodeState::connections(PortType portType, PortIndex portIndex) const
{
auto const &connections = getEntries(portType);
return connections[portIndex];
}
void NodeState::setConnection(PortType portType, PortIndex portIndex, Connection &connection)
{
auto &connections = getEntries(portType);
connections.at(portIndex).insert(std::make_pair(connection.id(), &connection));
}
void NodeState::eraseConnection(PortType portType, PortIndex portIndex, QUuid id)
{
getEntries(portType)[portIndex].erase(id);
}
NodeState::ReactToConnectionState NodeState::reaction() const
{
return _reaction;
}
PortType NodeState::reactingPortType() const
{
return _reactingPortType;
}
std::shared_ptr<QtNodes::NodeDataType> NodeState::reactingDataType() const
{
return _reactingDataType;
}
void NodeState::setReaction(ReactToConnectionState reaction, PortType reactingPortType, std::shared_ptr<NodeDataType> reactingDataType)
{
_reaction = reaction;
_reactingPortType = reactingPortType;
_reactingDataType = std::move(reactingDataType);
}
bool NodeState::isReacting() const
{
return _reaction == REACTING;
}
bool NodeState::resizing() const
{
return _resizing;
}
void NodeState::setResizing(bool resizing)
{
_resizing = resizing;
}
主要数据结构
std::vector<ConnectionPtrSet> _inConnections; // 输入连接集合 std::vector<ConnectionPtrSet> _outConnections; // 输出连接集合 ReactToConnectionState _reaction; // 响应状态 PortType _reactingPortType; // 正在交互的端口类型 std::shared_ptr<NodeDataType> _reactingDataType; // 正在交互的数据类型 bool _resizing; // 是否正在调整大小
其中 ConnectionPtrSet 定义为:
std::unordered_map<QUuid, Connection*> // 连接ID到连接对象的映射
关键方法分析
1. 连接管理方法
// 获取指定端口类型的所有连接
std::vector<ConnectionPtrSet> const& getEntries(PortType) const;
std::vector<ConnectionPtrSet>& getEntries(PortType);
// 获取特定端口的连接集合
ConnectionPtrSet connections(PortType portType, PortIndex portIndex) const;
// 添加连接
void setConnection(PortType portType, PortIndex portIndex, Connection &connection);
// 删除连接
void eraseConnection(PortType portType, PortIndex portIndex, QUuid id);
2. 交互状态管理方法
// 设置/获取响应状态
void setReaction(ReactToConnectionState reaction,
PortType reactingPortType = PortType::None,
std::shared_ptr<NodeDataType> reactingDataType = ...);
ReactToConnectionState reaction() const;
// 检查是否正在响应连接操作
bool isReacting() const;
// 获取正在交互的端口类型
PortType reactingPortType() const;
// 获取正在交互的数据类型
std::shared_ptr<NodeDataType> reactingDataType() const;
3. 尺寸调整状态
// 设置/获取调整大小状态 void setResizing(bool resizing); bool resizing() const;
设计特点
-
双向连接管理:独立维护输入和输出连接集合
-
多连接支持:每个端口可以支持多个连接(通过unordered_map实现)
-
精确状态跟踪:详细记录交互过程中的端口类型和数据类型
-
线程安全考虑:使用智能指针管理数据类型
-
高效查找:使用QUuid作为键值实现快速连接查找
与其他类的协作关系
-
NodeDataModel:
-
初始化时获取端口数量
-
交互时参考端口连接策略
-
-
Connection:
-
存储和管理连接对象
-
通过QUuid唯一标识连接
-
-
Node:
-
作为节点状态的核心管理者
-
协调状态变化与几何更新
-
-
NodeGraphicsObject:
-
响应交互操作时更新状态
-
调整大小时设置状态标志
-
状态转换示例
-
连接创建过程:
-
用户开始拖拽连接:
setReaction(REACTING, PortType::Out, dataType) -
用户悬停在目标端口:检查
reactingDataType()是否匹配 -
连接建立:
setConnection()添加新连接 -
完成:
setReaction(NOT_REACTING)
-
-
连接删除过程:
-
用户删除连接:
eraseConnection()移除指定连接
-
-
调整大小过程:
-
开始调整:
setResizing(true) -
调整结束:
setResizing(false)
-
使用场景
-
绘制节点时:
-
查询连接状态决定如何绘制端口
-
检查响应状态显示交互反馈
-
-
处理连接操作时:
-
验证连接是否允许
-
管理连接集合
-
-
执行数据流时:
-
遍历输入连接获取数据
-
通过输出连接传播数据
-
-
序列化/反序列化时:
-
保存/恢复连接状态
-
这个类的设计使得节点能够高效地管理复杂的连接关系,并在交互过程中保持精确的状态跟踪,为可视化编程提供了坚实的基础。
583

被折叠的 条评论
为什么被折叠?



