载入中...
搜索中...
未找到
ActionVfxBlock.cpp
浏览该文件的文档.
2
3#include <cmath>
4#include <string_view>
5#include <utility>
6
7namespace eve::action {
8namespace {
9
10Result<double> numeric(const Value::Object& payload, std::string_view key, double fallback) {
11 const auto found = payload.find(std::string(key));
12 if (found == payload.end()) return Result<double>::success(fallback);
13 double value = 0.0;
14 if (const auto* integer = found->second.getIf<std::int64_t>())
15 value = static_cast<double>(*integer);
16 else if (const auto* decimal = found->second.getIf<double>())
17 value = *decimal;
18 else
20 Diagnostic::error(DiagnosticCode::InvalidArgument, "VFX field must be numeric", std::string(key)));
21 if (!std::isfinite(value))
23 Diagnostic::error(DiagnosticCode::InvalidArgument, "VFX field must be finite", std::string(key)));
25}
26
27} // namespace
28
30 ActionVfxBinding candidate;
31 const auto uri = payload.find("uri");
32 if (uri == payload.end() || !uri->second.getIf<std::string>() || uri->second.getIf<std::string>()->empty())
34 Diagnostic::error(DiagnosticCode::InvalidArgument, "VFX URI must be non-empty text", "uri"));
35 candidate.uri = *uri->second.getIf<std::string>();
36
39 candidate.spatial = std::move(spatial).takeValue();
40
41 if (const auto stop = payload.find("stopBehavior"); stop != payload.end()) {
42 const auto* value = stop->second.getIf<std::string>();
43 if (!value)
45 Diagnostic::error(DiagnosticCode::InvalidArgument, "VFX stopBehavior must be text", "stopBehavior"));
46 if (*value == "stop_emitting")
48 else if (*value == "clear_immediately")
50 else
53 "VFX stopBehavior must be stop_emitting or clear_immediately", "stopBehavior"));
54 }
55 if (const auto synced = payload.find("playbackRateSynced"); synced != payload.end()) {
56 const auto* value = synced->second.getIf<bool>();
57 if (!value)
59 DiagnosticCode::InvalidArgument, "VFX playbackRateSynced must be boolean", "playbackRateSynced"));
60 candidate.playbackRateSynced = *value;
61 }
62
63 auto clipStart = numeric(payload, "clipStartTime", 0.0);
64 if (!clipStart) return Result<ActionVfxBinding>::failure(clipStart.status());
65 auto clipEnd = numeric(payload, "clipEndTime", 0.5);
66 if (!clipEnd) return Result<ActionVfxBinding>::failure(clipEnd.status());
67 if (clipStart.value() < 0.0)
69 DiagnosticCode::InvalidArgument, "VFX clipStartTime must be non-negative", "clipStartTime"));
70 if (clipEnd.value() <= clipStart.value())
72 DiagnosticCode::InvalidArgument, "VFX clipEndTime must be greater than clipStartTime", "clipEndTime"));
73 candidate.clipStartTime = clipStart.value();
74 candidate.clipEndTime = clipEnd.value();
75
76 auto lifetime = numeric(payload, "lifetimeSeconds", 0.0);
78 if (shape == ActionVfxShape::Instant && lifetime.value() <= 0.0)
80 DiagnosticCode::InvalidArgument, "instant VFX lifetimeSeconds must be positive", "lifetimeSeconds"));
81 if (shape == ActionVfxShape::State && lifetime.value() < 0.0)
83 DiagnosticCode::InvalidArgument, "VFX lifetimeSeconds must be non-negative", "lifetimeSeconds"));
84 candidate.lifetimeSeconds = lifetime.value();
85 return Result<ActionVfxBinding>::success(std::move(candidate));
86}
87
88} // namespace eve::action
double value
Value::Object payload
Typed VFX action-block payload contract.
std::uint32_t key
ShaderImageInput shape
std::weak_ptr< const void > lifetime
bool found
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
std::map< std::string, Value > Object
Definition Value.h:34
ActionVfxShape
Authored VFX block shape used to select lifetime validation.
static Result< ActionSpatialBinding > fromPayload(const Value::Object &payload)
Decode and validate the common spatial fields in an owning payload.
Owning validated VFX settings shared by runtime and editor preview.
ActionSpatialBinding spatial
ActionVfxStopBehavior stopBehavior
static Result< ActionVfxBinding > fromPayload(const Value::Object &payload, ActionVfxShape shape)
Decode one dynamic VFX payload transactionally.