载入中...
搜索中...
未找到
ActionCancelWindowState.cpp
浏览该文件的文档.
2
3#include "common/Capability.h"
4
5#include <algorithm>
6#include <sstream>
7#include <utility>
8
10namespace {
11
12std::vector<std::string> splitAllows(const std::string& resource) {
13 std::vector<std::string> allows;
14 std::stringstream stream(resource);
15 std::string item;
16 while (std::getline(stream, item, ';')) {
17 if (!item.empty()) allows.push_back(item);
18 }
19 std::sort(allows.begin(), allows.end());
20 allows.erase(std::unique(allows.begin(), allows.end()), allows.end());
21 return allows;
22}
23
24} // namespace
25
27
28ActionCancelWindowState::~ActionCancelWindowState() { cap::removeListener<IActionStateWindowSink>(this); }
29
31 for (std::size_t index = 0; index < cap::listenerCount<IActionStateWindowSink>(); ++index)
32 if (cap::listenerAt<IActionStateWindowSink>(index) == this) return true;
33 return false;
34}
35
37 const bool current = enabled();
38 if (value && !current)
39 cap::addListener<IActionStateWindowSink>(this);
40 else if (!value && current)
41 cap::removeListener<IActionStateWindowSink>(this);
42}
43
47
49 const ActionTimelineEvent& event,
51 if (!supports(binding.kind))
53 Diagnostic::error(DiagnosticCode::Unsupported, "input adapter does not own this window kind", "kind"));
54 if (!resolver_)
56 Diagnostic::error(DiagnosticCode::NotFound, "cancel subject resolver is unavailable", "resolver"));
57 auto allows = splitAllows(binding.resource);
58 if (allows.empty())
60 Diagnostic::error(DiagnosticCode::InvalidArgument, "cancel allow-list is empty", "allows"));
61 std::optional<ecs::EntityHandle> handle;
62 if (binding.targetIndex) {
63 if (*binding.targetIndex >= context.targets.size())
65 Diagnostic::error(DiagnosticCode::NotFound, "cancel target index is unavailable", "targetIndex"));
66 handle = context.targets[*binding.targetIndex];
67 } else {
68 handle = context.source;
69 }
70 if (!handle)
72 Diagnostic::error(DiagnosticCode::NotFound, "cancel window has no source or target", "subject"));
73 auto subject = resolver_(*handle);
74 if (!subject) return Result<void>::failure(subject.status());
75 if (!subject.value().isValid())
77 Diagnostic::error(DiagnosticCode::InvalidArgument, "cancel-window subject is nil", "subject"));
78
79 ActiveKey key{context.executionId, event.itemId.format()};
80 const auto found = active_.find(key);
81 if (found != active_.end()) {
82 if (found->second.subject == subject.value() && found->second.allows == allows &&
83 found->second.priority == binding.priority)
86 Diagnostic::error(DiagnosticCode::Conflict, "cancel-window key has different active data", "itemId"));
87 }
88 active_.emplace(std::move(key),
89 ActiveCancel{event.itemId, subject.value(), std::move(allows), binding.priority});
91}
92
94 const ActionTimelineEvent& event,
96 if (!supports(binding.kind))
98 Diagnostic::error(DiagnosticCode::Unsupported, "input adapter does not own this window kind", "kind"));
99 const ActiveKey key{context.executionId, event.itemId.format()};
100 const auto found = active_.find(key);
101 if (found == active_.end()) return Result<void>::success(Status::success(StatusCode::NoOp));
102 active_.erase(found);
104}
105
107 std::vector<std::string> result;
108 for (const auto& [key, window] : active_) {
109 (void)key;
110 if (window.subject != subject) continue;
111 result.insert(result.end(), window.allows.begin(), window.allows.end());
112 }
113 std::sort(result.begin(), result.end());
114 result.erase(std::unique(result.begin(), result.end()), result.end());
115 return result;
116}
117
119 const ActiveCancel* best = nullptr;
120 ActionExecutionId bestExecution{};
121 for (const auto& [key, window] : active_) {
122 if (window.subject != subject) continue;
123 if (std::find(window.allows.begin(), window.allows.end(), input) == window.allows.end()) continue;
124 if (!best || window.priority > best->priority ||
125 (window.priority == best->priority && key.first.value() < bestExecution.value())) {
126 best = &window;
127 bestExecution = key.first;
128 }
129 }
130 if (!best)
132 Diagnostic::error(DiagnosticCode::NotFound, "no cancel window matched input", "input"));
134 ActionCancelMatch{bestExecution, best->itemId, best->subject, std::string(input), best->priority});
135}
136
137} // namespace eve::action::input
Cancel-window projection for action combat.
double value
int subject
Definition AnimSmr.cpp:163
EvpackChunkInput input
Definition Evpack.cpp:170
std::uint32_t key
TokenKind kind
eve::action::ActionVfxBinding binding
PrimitiveHandle handle
bool found
double current
std::string resource
std::map< Cell, int > best
uint32_t index
const VegetationPresetContext & context
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
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
Strong, domain-neutral reference to a runtime subject.
Definition SubjectRef.h:26
Result< void > exit(const ActionStateWindowBinding &binding, const ActionTimelineEvent &event, const ActionNotifyContext &context) override
Exit.
Result< void > enter(const ActionStateWindowBinding &binding, const ActionTimelineEvent &event, const ActionNotifyContext &context) override
Enter.
bool supports(ActionStateWindowKind kind) const noexcept override
Supports.
std::vector< std::string > availableCancels(SubjectRef subject) const
Return sorted unique allow tags currently active for a subject.
ActionCancelWindowState(CancelSubjectResolver resolver)
Construct with a synchronous stable-subject resolver.
~ActionCancelWindowState() override
Action cancel window state.
Result< ActionCancelMatch > match(SubjectRef subject, std::string_view input) const
Resolve the highest-priority window that allows the semantic input.
void setEnabled(bool enabled)
Sets the enabled.
std::function< Result< SubjectRef >(ecs::EntityHandle)> CancelSubjectResolver
Resolves an owning stable subject from a generation-qualified ECS handle.
ActionStateWindowKind
Stable semantic kind for one built-in state window.
Context linking a routed event to its action execution.
Owning validated state-window request authored on an action timeline.
Owning event projection returned by the runtime sampler.
Owning cancel match between an input/ability tag and an active window.