Skip to content

Commit a4787cd

Browse files
committed
Added checking to see if nodes can connect in a graph.
1 parent cc5eeb5 commit a4787cd

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

include/flow/core/Graph.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ class Graph
145145
*/
146146
void Clear() noexcept { _connections.Clear(), _nodes.clear(); }
147147

148+
/**
149+
* @brief Check if the nodes can be connected
150+
*/
151+
bool CanConnectNode(const UUID& start, const IndexableName& start_key, const UUID& end,
152+
const IndexableName& end_key);
153+
148154
/**
149155
* @brief Connects 2 nodes by their IDs and Port keys.
150156
*

src/Graph.cpp

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,19 +200,57 @@ std::vector<SharedNode> Graph::GetOrphanNodes() const
200200
return orphans;
201201
}
202202

203+
bool Graph::CanConnectNode(const UUID& start, const IndexableName& start_key, const UUID& end,
204+
const IndexableName& end_key)
205+
{
206+
// Check if both nodes exist
207+
auto start_node = GetNode(start);
208+
auto end_node = GetNode(end);
209+
if (!(start_node && end_node)) return false;
210+
211+
// Check if the start node has the specified output port
212+
const auto start_port = start_node->GetOutputPort(start_key);
213+
if (!start_port) return false;
214+
215+
// Check if the end node has the specified input port
216+
const auto end_port = end_node->GetInputPort(end_key);
217+
if (!end_port) return false;
218+
219+
// Check if the end port is already connected
220+
if (end_port->IsConnected())
221+
{
222+
// Check if it's already connected to the same start port
223+
auto conns = _connections.FindConnections(start, start_key);
224+
auto found_conn = std::find_if(conns.begin(), conns.end(), [&](const auto& conn) {
225+
return conn->EndNodeID() == end && conn->EndPortKey() == end_key;
226+
});
227+
228+
// If already connected to the same ports, consider it as "can connect" (no-op)
229+
return found_conn != conns.end();
230+
}
231+
232+
return true;
233+
}
234+
203235
SharedConnection Graph::ConnectNodes(const UUID& start_id, const IndexableName& start_port_key, const UUID& end_id,
204236
const IndexableName& end_port_key)
205237
{
238+
// First check if the nodes can be connected
239+
if (!CanConnectNode(start_id, start_port_key, end_id, end_port_key))
240+
{
241+
return nullptr;
242+
}
243+
244+
// Get nodes again (we know they exist from CanConnectNode)
206245
auto in_node = GetNode(start_id);
207246
auto out_node = GetNode(end_id);
208247

209-
if (!(in_node && out_node)) return nullptr;
210-
211248
const auto start_port = in_node->GetOutputPort(start_port_key);
212249
const auto end_port = out_node->GetInputPort(end_port_key);
213250

214-
start_port->Connect();
215-
if (!end_port->Connect())
251+
// If end port is already connected, it means it's connected to the same start port
252+
// (verified by CanConnectNode), so return the existing connection
253+
if (end_port->IsConnected())
216254
{
217255
auto conns = _connections.FindConnections(start_id, start_port_key);
218256
auto found_conn = std::find_if(conns.begin(), conns.end(), [&](const auto& conn) {
@@ -223,11 +261,16 @@ SharedConnection Graph::ConnectNodes(const UUID& start_id, const IndexableName&
223261
{
224262
return *found_conn;
225263
}
226-
227-
return nullptr;
228264
}
229265

266+
// Mark ports as connected
267+
start_port->Connect();
268+
end_port->Connect();
269+
270+
// Create the connection
230271
auto&& conn = _connections.Add(start_id, start_port->GetVarName(), end_id, end_port->GetVarName());
272+
273+
// Propagate existing data if any
231274
if (auto data = in_node->GetOutputData(start_port_key))
232275
{
233276
PropagateConnectionsData(start_id, start_port_key, std::move(data));

0 commit comments

Comments
 (0)