载入中...
搜索中...
未找到
GameEvent.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
6#include "common/Identity.h"
7#include "common/Module.h"
8#include "common/Result.h"
9#include "common/Revision.h"
11#include "common/Snapshot.h"
12#include "common/Time.h"
13
14#include <cstdint>
15#include <deque>
16#include <functional>
17#include <memory>
18#include <optional>
19#include <ostream>
20#include <string>
21#include <string_view>
22#include <utility>
23#include <variant>
24#include <vector>
25
26namespace eve::game_event {
27
32
42
50public:
52 enum class Kind : uint8_t { None, Id, Legacy };
53
55 CorrelationId() = default;
56
58 [[nodiscard]] static CorrelationId fromEventId(EventId value) {
59 CorrelationId result;
60 result.kind_ = value.isNil() ? Kind::None : Kind::Id;
61 result.id_ = value;
62 return result;
63 }
64
66 [[nodiscard]] static CorrelationId fromLegacy(std::string value) {
67 CorrelationId result;
68 result.kind_ = value.empty() ? Kind::None : Kind::Legacy;
69 result.legacy_ = std::move(value);
70 return result;
71 }
72
74 [[nodiscard]] Kind kind() const noexcept { return kind_; }
75
77 [[nodiscard]] bool isCanonical() const noexcept { return kind_ != Kind::Legacy; }
78
80 [[nodiscard]] std::string format() const { return kind_ == Kind::Id ? id_.format() : legacy_; }
81
82 friend bool operator==(const CorrelationId&, const CorrelationId&) noexcept = default;
83
84private:
85 Kind kind_ = Kind::None;
86 EventId id_;
87 std::string legacy_;
88};
89
97public:
99 enum class Kind : uint8_t { None, Event, Command, Legacy };
100
102 CausationRef() = default;
103
105 [[nodiscard]] static CausationRef fromEventId(EventId value) {
106 CausationRef result;
107 if (!value.isNil()) {
108 result.kind_ = Kind::Event;
109 result.value_ = std::move(value);
110 }
111 return result;
112 }
113
116 CausationRef result;
117 if (!value.isNil()) {
118 result.kind_ = Kind::Command;
119 result.value_ = std::move(value);
120 }
121 return result;
122 }
123
125 [[nodiscard]] static CausationRef fromLegacy(std::string value) {
126 CausationRef result;
127 result.kind_ = value.empty() ? Kind::None : Kind::Legacy;
128 result.value_ = std::move(value);
129 return result;
130 }
131
133 [[nodiscard]] Kind kind() const noexcept { return kind_; }
134
136 [[nodiscard]] bool isCanonical() const noexcept { return kind_ != Kind::Legacy; }
137
139 [[nodiscard]] std::string format() const {
140 if (kind_ == Kind::Event) return std::get<EventId>(value_).format();
141 if (kind_ == Kind::Command) return std::get<CommandId>(value_).format();
142 if (kind_ == Kind::Legacy) return std::get<std::string>(value_);
143 return {};
144 }
145
146 friend bool operator==(const CausationRef&, const CausationRef&) noexcept = default;
147
148private:
149 Kind kind_ = Kind::None;
150 std::variant<std::monostate, EventId, CommandId, std::string> value_;
151};
152
154inline std::ostream& operator<<(std::ostream& stream, CorrelationId::Kind kind) {
155 switch (kind) {
156 case CorrelationId::Kind::None: return stream << "none";
157 case CorrelationId::Kind::Id: return stream << "id";
158 case CorrelationId::Kind::Legacy: return stream << "legacy";
159 }
160 return stream << "unknown";
161}
162
164inline std::ostream& operator<<(std::ostream& stream, CausationRef::Kind kind) {
165 switch (kind) {
166 case CausationRef::Kind::None: return stream << "none";
167 case CausationRef::Kind::Event: return stream << "event";
168 case CausationRef::Kind::Command: return stream << "command";
169 case CausationRef::Kind::Legacy: return stream << "legacy";
170 }
171 return stream << "unknown";
172}
173
209
214template <class Payload>
220
221class GameEventLog;
222
225public:
227 int read(int maxCount);
229 int batchCount() const;
237 const GameEvent* batchAt(int index) const;
239 [[nodiscard]] EventSequence position() const;
241 void seek(EventSequence sequence);
243 void seek(uint64_t sequence);
244
245private:
246 friend class GameEventLog;
248
249 GameEventLog* stream_ = nullptr;
250 EventSequence nextSequence_ = EventSequence(1);
251 std::vector<const GameEvent*> batch_;
252};
253
262public:
263 // The stream owns move-only members (std::vector<std::unique_ptr<EventConsumer>>),
264 // so it is not copyable; dllexport must not instantiate the implicitly declared
265 // copy operations, whose bodies cannot compile. Deleting the copies is a no-op and
266 // the defaulted moves keep the previous implicit behaviour.
267 GameEventLog(const GameEventLog&) = delete;
273
275 GameEventLog() = default;
276
278 explicit GameEventLog(eve::PersistentId instanceId) : instanceId_(instanceId) {}
279
285 explicit GameEventLog(eve::UuidEntropySource entropy, eve::UuidClock clock = {});
286
295 [[nodiscard]] eve::Result<EventSequence> append(GameEvent envelope);
296
305 template <class Payload>
308 GameEvent envelope, const Payload& payload,
309 const std::function<eve::Result<std::string>(const Payload&)>& encode) {
310 if (!encode) {
313 eve::DiagnosticCode::InvalidArgument, "event payload encoder must not be empty"));
314 }
315 auto encoded = encode(payload);
316 if (!encoded) return eve::Result<EventSequence>::failure(encoded.status());
317 envelope.payload = std::move(encoded).takeValue();
319 return append(std::move(envelope));
320 }
321
331 [[nodiscard]] const GameEvent* find(EventSequence sequence) const;
339 [[nodiscard]] const GameEvent* find(uint64_t sequence) const;
341 int queryType(const std::string& type);
343 int querySource(const std::string& source);
345 int querySubject(const std::string& subject);
347 int querySequence(EventSequence firstSequence);
349 int querySequence(uint64_t firstSequence);
351 const GameEvent* queryAt(int index) const;
353 int size() const;
355 const GameEvent* at(int index) const;
357 [[nodiscard]] EventConsumer* newConsumer(EventSequence firstSequence = EventSequence(1));
359 [[nodiscard]] EventConsumer* newConsumer(uint64_t firstSequence);
361 void clearBefore(EventSequence firstSequence);
363 void clearBefore(uint64_t firstSequence);
365 void clear();
367 void reset();
369 std::string snapshotJson() const;
376 [[nodiscard]] eve::Result<void> restore(std::string_view json);
377
379 [[nodiscard]] eve::Result<eve::SnapshotEnvelope> snapshot(const eve::SnapshotHashProvider& hashProvider) const;
386 [[nodiscard]] eve::Result<void> restoreSnapshot(const eve::SnapshotEnvelope& snapshot,
387 const eve::SnapshotHashProvider& hashProvider);
389 [[nodiscard]] eve::Result<std::string> snapshotEnvelopeJson(const eve::SnapshotHashProvider& hashProvider) const;
391 [[nodiscard]] eve::Result<void> restoreSnapshotJson(std::string_view json,
392 const eve::SnapshotHashProvider& hashProvider);
393
394private:
395 friend class EventConsumer;
396 [[nodiscard]] EventSequence oldestSequence() const;
397
398 std::optional<eve::UuidV7Generator> eventIdGenerator_;
399 eve::PersistentId instanceId_;
402 EventSequence nextSequence_ = EventSequence(1);
403 std::deque<GameEvent> events_;
404 std::vector<const GameEvent*> query_;
405 std::vector<std::unique_ptr<EventConsumer>> consumers_;
406};
407
409class GameEventModule : public Module {
410public:
413 GameEventModule() = default;
415 ~GameEventModule() override = default;
416
426 [[nodiscard("event stream ownership must be retained or explicitly handled")]] static GameEventLog* newLog();
427
428private:
429 std::vector<std::unique_ptr<GameEventLog>> streams_;
430};
431
432} // namespace eve::game_event
double value
Value::Object payload
int subject
Definition AnimSmr.cpp:163
Stream-local event ordering value.
#define EVENGINE_API_FOUNDATION
每个链接组(link group)各自的导出宏。
Definition Export.h:106
Strong identity values shared by persistence, content and logical-name APIs.
TokenKind kind
std::array< float, 3 > position
std::unique_ptr< gpgpu::Sequence > sequence
Definition OnnxGpgpu.cpp:43
Move-only, checked operation results for the common layer.
Monotonic state revision for concurrency and change checks.
Persistent data-contract version identity.
Versioned, integrity-checked persistence envelopes.
Common time values and an injectable deterministic simulation clock.
float size
Definition TreeMesh.cpp:156
uint32_t index
const UnitySourceAsset & source
std::size_t at
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
Human-readable, scoped identifier in the form namespace:name.
Definition Identity.h:411
EVENGINE_API_FOUNDATION public API.
Definition Module.h:46
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
Id128 public API.
Definition Identity.h:112
std::string format() const
Formats the ID in lower-case canonical UUID text.
Definition Identity.h:173
static constexpr Id128 nil() noexcept
Returns the all-zero nil value.
Definition Identity.h:142
static constexpr StrongUint64 zero() noexcept
Returns the zero value for this strong type.
Tagged direct causation reference to an event or command.
Definition GameEvent.h:96
static CausationRef fromEventId(EventId value)
Creates a causation reference to an event.
Definition GameEvent.h:105
CausationRef()=default
Constructs an absent causation reference.
bool isCanonical() const noexcept
Returns whether this reference uses the canonical ID form.
Definition GameEvent.h:136
std::string format() const
Returns the stable UUID or compatibility text projection.
Definition GameEvent.h:139
friend bool operator==(const CausationRef &, const CausationRef &) noexcept=default
static CausationRef fromLegacy(std::string value)
Creates a compatibility-only arbitrary string causation.
Definition GameEvent.h:125
Kind kind() const noexcept
Returns the tagged causation kind.
Definition GameEvent.h:133
static CausationRef fromCommandId(CommandId value)
Creates a causation reference to a command.
Definition GameEvent.h:115
Strong business-workflow correlation identity.
Definition GameEvent.h:49
Kind kind() const noexcept
Returns the tagged correlation kind.
Definition GameEvent.h:74
static CorrelationId fromLegacy(std::string value)
Creates a compatibility-only arbitrary string correlation.
Definition GameEvent.h:66
bool isCanonical() const noexcept
Returns whether this reference uses the canonical ID form.
Definition GameEvent.h:77
std::string format() const
Returns the stable ID or compatibility text projection.
Definition GameEvent.h:80
CorrelationId()=default
Constructs an absent correlation reference.
friend bool operator==(const CorrelationId &, const CorrelationId &) noexcept=default
static CorrelationId fromEventId(EventId value)
Creates a canonical correlation ID from an EventId.
Definition GameEvent.h:58
Independent sequence cursor used to consume an GameEventLog in batches.
Definition GameEvent.h:224
Deterministic in-memory stream of topic-neutral event envelopes.
Definition GameEvent.h:261
GameEventLog & operator=(GameEventLog &&)=default
Operator =.
GameEventLog()=default
Creates a stream without an implicit entropy source.
GameEventLog(eve::PersistentId instanceId)
Creates a stream with a persistent snapshot identity.
Definition GameEvent.h:278
GameEventLog(GameEventLog &&)=default
Game event log.
eve::Result< EventSequence > appendTyped(GameEvent envelope, const Payload &payload, const std::function< eve::Result< std::string >(const Payload &)> &encode)
Encodes a strongly typed domain payload and appends its envelope.
Definition GameEvent.h:307
GameEventLog(const GameEventLog &)=delete
GameEventLog & operator=(const GameEventLog &)=delete
Script module factory for generic GameEventLog objects.
Definition GameEvent.h:409
~GameEventModule() override=default
Releases GameEventModule resources.
static GameEventLog * newLog()
Allocates a module-owned event stream. @ownership Borrowed from the manager-owned GameEvent module; t...
GameEventModule()=default
Constructs a GameEventModule.
std::ostream & operator<<(std::ostream &stream, CorrelationId::Kind kind)
Writes a correlation representation tag for diagnostics.
Definition GameEvent.h:154
std::function< std::chrono::system_clock::time_point()> UuidClock
Clock callback used by the injectable UUIDv7 generator.
Definition Identity.h:469
StrongUuid< detail::CommandIdTag > CommandId
Stable command identity for causal references.
Definition Identity.h:288
detail::StrongUint64< detail::SchemaVersionTag > SchemaVersion
Persistent data-format version; not a runtime replacement generation.
std::function< bool(std::span< std::uint8_t > bytes)> UuidEntropySource
Entropy callback used by UUIDv7 generation.
Definition Identity.h:466
detail::StrongUint64< detail::SimulationTickTag > SimulationTick
Deterministic simulation time step; it is not wall-clock time.
Definition Time.h:31
StrongUuid< detail::EventIdTag > EventId
Stable event identity for event envelopes and causal references.
Definition Identity.h:285
detail::StrongUint64< detail::EventSequenceTag > EventSequence
Stream-local event ordering value; it is not a global event identity.
std::function< Result< ContentId >(std::string_view canonicalInput)> SnapshotHashProvider
Injected content-digest implementation used by snapshots.
Definition Snapshot.h:36
Stable outer format shared by persistence and cross-process snapshots.
Definition Snapshot.h:46
Envelope metadata shared by event domains.
Definition GameEvent.h:183
std::string source
Stable source reference, owned by this envelope.
Definition GameEvent.h:191
std::string type
Compatibility event name and diagnostic topic.
Definition GameEvent.h:189
EventSequence sequence
Sequence assigned by the owning stream; it is never global identity.
Definition GameEvent.h:187
EventId eventId
Stable event identity; nil is allowed only for legacy transient events.
Definition GameEvent.h:185
std::string payload
Canonical serialized payload at the stream persistence boundary.
Definition GameEvent.h:207
SchemaVersion schemaVersion
Version of the payload schema, not a stream or runtime generation.
Definition GameEvent.h:201
SchemaId schemaId
Logical schema identifier for the typed payload codec.
Definition GameEvent.h:199
uint32_t flags
Domain-defined bit flags; their meanings belong to the schema.
Definition GameEvent.h:205
SimulationTick tick
Deterministic simulation time at which the event was emitted.
Definition GameEvent.h:203
std::string subject
Stable subject reference, owned by this envelope.
Definition GameEvent.h:193
CorrelationId correlation
Business workflow correlation reference.
Definition GameEvent.h:197
CausationRef causation
Direct causation reference, normally an event or command ID.
Definition GameEvent.h:195
Strongly typed event value used before serialization into a stream.
Definition GameEvent.h:216