载入中...
搜索中...
未找到
EditingGraph.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <utility>
5
6namespace eve::editing {
7namespace {} // namespace
8
10 if (node.id.empty() || node.type.empty() || nodes_.contains(node.id))
11 return eve::editing::failed<void>(Status::Conflict, RuleId("editing.graph.invalid-node"),
12 "Graph node id/type is missing or the id already exists");
13 for (GraphPinRecord& pin : node.pins) {
14 if (pin.id.empty())
15 return eve::editing::failed<void>(Status::Rejected, RuleId("editing.graph.invalid-pin"),
16 "Graph pin id is required");
17 pin.node = node.id;
18 if (findPin(pin.id))
19 return eve::editing::failed<void>(Status::Conflict, RuleId("editing.graph.duplicate-pin"),
20 "Graph pin id already exists");
21 }
22 nodes_.emplace(node.id, std::move(node));
23 ++revision_;
24 return eve::editing::applied<void>();
25}
26
28 if (!nodes_.contains(node))
29 return eve::editing::failed<void>(Status::NotFound, RuleId("editing.graph.node-not-found"),
30 "Graph node does not exist");
31 std::vector<GraphPinId> pins;
32 for (const GraphPinRecord& pin : nodes_.at(node).pins) pins.push_back(pin.id);
33 std::erase_if(edges_, [&](const auto& edge) {
34 return std::find(pins.begin(), pins.end(), edge.second.from) != pins.end() ||
35 std::find(pins.begin(), pins.end(), edge.second.to) != pins.end();
36 });
37 nodes_.erase(node);
38 ++revision_;
39 return eve::editing::applied<void>();
40}
41
43 if (!decision.allowed) {
44 auto diagnostics = decision.diagnostics;
45 if (diagnostics.empty())
47 RuleId("editing.graph.connection-rejected"),
48 DiagnosticSeverity::Error, "Connection was rejected"));
49 return Result<void>::failure(eve::Status(Status::Rejected, std::move(diagnostics)));
50 }
51 if (edge.id.empty() || edges_.contains(edge.id) || !findPin(edge.from) || !findPin(edge.to))
52 return eve::editing::failed<void>(Status::Rejected, RuleId("editing.graph.invalid-edge"),
53 "Graph edge id/pins are invalid or duplicated");
54 edges_.emplace(edge.id, std::move(edge));
55 ++revision_;
56 return eve::editing::applied<void>();
57}
58
60 if (!edges_.erase(edge))
61 return eve::editing::failed<void>(Status::NotFound, RuleId("editing.graph.edge-not-found"),
62 "Graph edge does not exist");
63 ++revision_;
64 return eve::editing::applied<void>();
65}
66
68 auto found = nodes_.find(node);
69 if (found == nodes_.end())
70 return eve::editing::failed<void>(Status::NotFound, RuleId("editing.graph.node-not-found"),
71 "Graph node does not exist");
72 if (properties.type() != Value::Type::Object)
73 return eve::editing::failed<void>(Status::Rejected, RuleId("editing.graph.invalid-properties"),
74 "Graph node properties must be an object");
75 found->second.properties = std::move(properties);
76 ++revision_;
77 return eve::editing::applied<void>();
78}
79
81 if (parameters.type() != Value::Type::Object)
82 return eve::editing::failed<void>(Status::Rejected, RuleId("editing.graph.invalid-parameters"),
83 "Graph parameters must be an object");
84 if (!parameters.isWithinLimits(4, 4096, 256 * 1024))
85 return eve::editing::failed<void>(Status::Rejected, RuleId("editing.graph.parameters-too-large"),
86 "Graph parameters exceed editing document limits");
87 parameters_ = std::move(parameters);
88 ++revision_;
89 return eve::editing::applied<void>();
90}
91
92GraphDocumentData GraphDocument::snapshot(std::string domain) const {
93 GraphDocumentData result;
94 result.domain = std::move(domain);
95 result.revision = revision_;
96 result.parameters = parameters_;
97 for (const auto& [id, node] : nodes_) {
98 (void)id;
99 result.nodes.push_back(node);
100 }
101 for (const auto& [id, edge] : edges_) {
102 (void)id;
103 result.edges.push_back(edge);
104 }
105 return result;
106}
107
109 for (const auto& [id, node] : nodes_) {
110 (void)id;
111 auto found = std::find_if(node.pins.begin(), node.pins.end(),
112 [&](const GraphPinRecord& candidate) { return candidate.id == pin; });
113 if (found != node.pins.end()) return &*found;
114 }
115 return nullptr;
116}
117
118} // namespace eve::editing
std::map< std::string, PropertyRule > properties
const RoadNode * node
const RoadEdge * edge
bool found
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Structured status and zero or more diagnostics for an operation.
Definition Status.h:68
UUID-backed identifier adapter for legacy textual boundaries.
Definition Identity.h:314
Result< void > connect(GraphEdgeRecord edge, const GraphConnectionDecision &decision)
Connect.
Result< void > setNodeProperties(const GraphNodeId &node, Value properties)
Sets the node properties.
const GraphPinRecord * findPin(const GraphPinId &pin) const
Finds pin.
Result< void > setParameters(Value parameters)
Sets the parameters.
Result< void > disconnect(const StableId &edge)
Disconnect.
GraphDocumentData snapshot(std::string domain) const
Snapshot.
Result< void > deleteNode(const GraphNodeId &node)
Deletes node.
Result< void > createNode(GraphNodeRecord node)
Creates node.
Deterministic owning value tree shared by authoring hosts.
bool isWithinLimits(size_t maxDepth, size_t maxElements, size_t maxStringBytes) const
Validate nesting, element count and approximate string byte limits.
Type type() const
Return the active value type.
StrongId< RuleIdTag > RuleId
Definition EditingIds.h:60
Diagnostic ruleDiagnostic(eve::DiagnosticCode code, RuleId rule, DiagnosticSeverity severity, std::string message)
Build a common diagnostic carrying an open editing rule identity.
Result of domain-specific connection validation.
std::vector< Diagnostic > diagnostics
Immutable graph document value sent to a domain compiler.
std::vector< GraphNodeRecord > nodes
std::vector< GraphEdgeRecord > edges
Directed connection between an output and input pin.
Generic graph node independent of its domain.
Stable typed pin owned by a graph node.