载入中...
搜索中...
未找到
DialogueGraphRuntime.cpp
浏览该文件的文档.
2
4
5#include <memory>
6#include <utility>
7
8namespace eve::dialogue_editing {
9namespace {
10
11const EditorValue* field(const EditorValue& value, const char* key) {
12 const auto* object = value.getIf<EditorValue::Object>();
13 if (!object) return nullptr;
14 const auto found = object->find(key);
15 return found == object->end() ? nullptr : &found->second;
16}
17
18} // namespace
19
21 const GraphDocumentData& graph) const {
23 const DialogueGraphCompileResult compiled = domain.compile(graph);
24 if (compiled.status != EditorStatus::Applied)
26 eve::Status(compiled.status, compiled.diagnostics));
27 const auto* id = field(compiled.definition, "id")->getIf<std::string>();
28 const auto* version = field(compiled.definition, "version")->getIf<int64_t>();
29 const auto* entry = field(compiled.definition, "entry")->getIf<std::string>();
30 const auto* parameters = field(compiled.definition, "parameters")->getIf<EditorValue::Array>();
31 const auto* nodes = field(compiled.definition, "nodes")->getIf<EditorValue::Array>();
32 auto document = std::make_unique<dialogue::ConversationDocument>(*id);
33 document->removeNode("end");
34 if (!document->setVersion(static_cast<int>(*version)))
35 return eve::editing::failed<dialogue::ConversationDocument*>(
36 EditorStatus::Failed, RuleId("editor.dialogue.version-rejected"), "Conversation version was rejected");
37 for (const EditorValue& parameter : *parameters)
38 document->addParameter(*parameter.getIf<std::string>());
39 for (const EditorValue& nodeValue : *nodes) {
40 const auto* nodeId = field(nodeValue, "id")->getIf<std::string>();
41 const auto* kind = field(nodeValue, "kind")->getIf<std::string>();
42 if (!document->addNode(*nodeId, *kind))
43 return eve::editing::failed<dialogue::ConversationDocument*>(EditorStatus::Failed,
44 RuleId("editor.dialogue.node-rejected"),
45 "Conversation node was rejected: " + *nodeId);
46 }
47 for (const EditorValue& nodeValue : *nodes) {
48 const auto* nodeId = field(nodeValue, "id")->getIf<std::string>();
49 const auto* kind = field(nodeValue, "kind")->getIf<std::string>();
50 const auto* properties = field(nodeValue, "properties")->getIf<EditorValue::Object>();
51 for (const auto& [key, value] : *properties) {
52 const auto* text = value.getIf<std::string>();
53 if (!text || !document->setField(*nodeId, key, *text))
54 return eve::editing::failed<dialogue::ConversationDocument*>(
55 EditorStatus::Failed, RuleId("editor.dialogue.field-rejected"),
56 "Conversation field was rejected: " + *nodeId + "." + key);
57 }
58 if (*kind != "branch" && *kind != "choice" && *kind != "end") {
59 const auto* next = field(nodeValue, "next")->getIf<std::string>();
60 if (!document->setField(*nodeId, "next", *next))
61 return eve::editing::failed<dialogue::ConversationDocument*>(EditorStatus::Failed,
62 RuleId("editor.dialogue.next-rejected"),
63 "Conversation next target was rejected");
64 }
65 const auto* routes = field(nodeValue, "routes")->getIf<EditorValue::Array>();
66 for (const EditorValue& route : *routes) {
67 const auto* label = field(route, "label")->getIf<std::string>();
68 const auto* target = field(route, "target")->getIf<std::string>();
69 if (!document->addRoute(*nodeId, *label, *target))
70 return eve::editing::failed<dialogue::ConversationDocument*>(
71 EditorStatus::Failed, RuleId("editor.dialogue.route-rejected"), "Conversation route was rejected");
72 }
73 }
74 if (!document->setEntry(*entry) || !document->validate()) {
75 std::vector<EditorDiagnostic> diagnostics;
76 diagnostics.push_back(eve::editing::ruleDiagnostic(
77 eve::DiagnosticCode::Failed, RuleId("editor.dialogue.runtime-validation"), DiagnosticSeverity::Error,
78 "Conversation runtime validation failed"));
79 for (int index = 0; index < document->getDiagnosticCount(); ++index)
80 diagnostics.push_back(eve::editing::ruleDiagnostic(
81 eve::DiagnosticCode::Failed, RuleId("editor.dialogue.runtime-diagnostic"),
82 document->getDiagnosticSeverity(index) == "error" ? DiagnosticSeverity::Error
83 : DiagnosticSeverity::Warning,
84 document->getDiagnosticMessage(index)));
86 eve::Status(EditorStatus::Failed, std::move(diagnostics)));
87 }
88 return eve::editing::applied<dialogue::ConversationDocument*>(document.release());
89}
90
91} // namespace eve::dialogue_editing
LogicalId target
double value
std::string label
std::string nodeId
std::uint32_t key
std::string text
TokenKind kind
std::map< std::string, PropertyRule > properties
std::vector< BvhNode > nodes
std::map< std::string, std::vector< std::string > > graph
Definition Package.cpp:59
bool found
uint32_t index
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
dialogue.conversation domain for line, choice, branch and action flow.
DialogueGraphCompileResult compile(const GraphDocumentData &graph) const
Validate and compile the graph into a deterministic value definition.
Result< dialogue::ConversationDocument * > build(const GraphDocumentData &graph) const
Build a validated ConversationDocument; caller owns the returned document.
Deterministic owning value tree shared by authoring hosts.
std::vector< Value > Array
std::map< std::string, Value > Object
const T * getIf() const
Return an immediately borrowed typed value.
Diagnostic ruleDiagnostic(eve::DiagnosticCode code, RuleId rule, DiagnosticSeverity severity, std::string message)
Build a common diagnostic carrying an open editing rule identity.
const EditorValue * field(const EditorValue &value, const char *name)
Validated, runtime-neutral conversation definition compiled from a graph.
std::vector< EditorDiagnostic > diagnostics
Immutable graph document value sent to a domain compiler.