载入中...
搜索中...
未找到
Container.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
16#include "common/Generation.h"
17#include "common/Identity.h"
18#include "common/Result.h"
19#include "common/Revision.h"
20
21#include <cmath>
22#include <compare>
23#include <cstddef>
24#include <cstdint>
25#include <functional>
26#include <memory>
27#include <optional>
28#include <string>
29#include <string_view>
30#include <type_traits>
31#include <utility>
32#include <variant>
33#include <vector>
34
35namespace eve::game_event {
36struct GameEvent;
37}
38
39namespace eve::container {
40
41struct ContainerObject;
42
45public:
47 ContainerId() = default;
49 explicit ContainerId(std::string value) : value_(std::move(value)) {}
50
52 [[nodiscard]] static std::optional<ContainerId> from(std::string_view value) {
53 if (value.empty()) return std::nullopt;
55 return ContainerId(std::string(value));
56 }
58 [[nodiscard]] bool isValid() const noexcept { return !value_.empty(); }
60 [[nodiscard]] const std::string& value() const noexcept { return value_; }
61 friend bool operator==(const ContainerId&, const ContainerId&) noexcept = default;
62
63private:
64 std::string value_;
65};
66
69public:
71 MembershipId() = default;
73 explicit MembershipId(std::string value) : value_(std::move(value)) {}
74
76 [[nodiscard]] static std::optional<MembershipId> from(std::string_view value) {
77 if (value.empty()) return std::nullopt;
79 return MembershipId(std::string(value));
80 }
82 [[nodiscard]] bool isValid() const noexcept { return !value_.empty(); }
84 [[nodiscard]] const std::string& value() const noexcept { return value_; }
85 friend bool operator==(const MembershipId&, const MembershipId&) noexcept = default;
86
87private:
88 std::string value_;
89};
90
92class Capacity {
93public:
95 [[nodiscard]] static constexpr Capacity fixed(std::size_t value) noexcept { return Capacity(value, false); }
97 [[nodiscard]] static constexpr Capacity unlimited() noexcept { return Capacity(0, true); }
98 [[nodiscard]] constexpr bool isUnlimited() const noexcept { return unlimited_; }
99 [[nodiscard]] constexpr std::size_t value() const noexcept { return value_; }
100
101private:
102 constexpr Capacity(std::size_t value, bool unlimited) noexcept : value_(value), unlimited_(unlimited) {}
103 std::size_t value_ = 0;
104 bool unlimited_ = false;
105};
106
108enum class Ordering : std::uint8_t {
109 Unordered,
110 Insertion,
111 Stack,
112 Queue,
114};
115
118public:
120 constexpr SlotIndex() noexcept = default;
122 explicit constexpr SlotIndex(std::int32_t value) noexcept : value_(value) {}
124 [[nodiscard]] static constexpr SlotIndex invalid() noexcept { return SlotIndex(-1); }
126 [[nodiscard]] constexpr bool isValid() const noexcept { return value_ >= 0; }
128 [[nodiscard]] constexpr std::int32_t value() const noexcept { return value_; }
130 friend constexpr bool operator==(const SlotIndex&, const SlotIndex&) noexcept = default;
132 friend constexpr auto operator<=>(const SlotIndex&, const SlotIndex&) noexcept = default;
133
134private:
135 std::int32_t value_ = -1;
136};
137
139class Filter {
140public:
141 using Predicate = std::function<Result<void>(const ContainerObject&)>;
142
144 Filter() = default;
146 explicit Filter(Predicate predicate) : predicate_(std::move(predicate)) {}
147
149 [[nodiscard]] Result<void> evaluate(const struct ContainerObject& object) const {
150 if (!predicate_) return Result<void>::success();
152 return predicate_(object);
153 }
155 [[nodiscard]] bool empty() const noexcept { return !predicate_; }
156
157private:
158 Predicate predicate_;
159};
160
164 virtual ~ContainerObjectPayload() = default;
165};
166
170 std::string type;
171 std::vector<std::string> tags;
172 std::uint32_t quantity = 1;
173 std::shared_ptr<const ContainerObjectPayload> payload;
174};
175
182
188
193 std::vector<MembershipEntry> entries;
194};
195
203
205enum class ContainerEventKind : std::uint8_t {
206 Enter,
207 Exit,
208 Accepted,
209 Rejected,
210};
211
221[[nodiscard]] inline const char* containerEventTypeName(ContainerEventKind kind) noexcept {
222 switch (kind) {
223 case ContainerEventKind::Enter: return "container.enter";
224 case ContainerEventKind::Exit: return "container.exit";
225 case ContainerEventKind::Accepted: return "container.accepted";
226 case ContainerEventKind::Rejected: return "container.rejected";
227 }
228 return "container.rejected";
229}
230
232inline constexpr std::string_view containerEventSchemaName = "container:event";
233
245using GameEventSink = std::function<void(const game_event::GameEvent&)>;
246
257[[nodiscard]] inline EventId deterministicContainerEventId(const ContainerId& container, const MembershipId& object,
258 ContainerEventKind kind, std::uint64_t serial) noexcept {
259 auto mix = [](std::uint64_t value, std::string_view text) noexcept {
260 for (const unsigned char byte : text) {
261 value ^= byte;
262 value *= 1099511628211ull;
263 }
264 return value;
265 };
266 std::uint64_t first = mix(14695981039346656037ull, container.value());
267 first = mix(first, object.value());
268 first = mix(first, std::string_view(containerEventTypeName(kind)));
269 std::uint64_t second = mix(1099511628211ull ^ serial, object.value());
270 second = mix(second, container.value());
271 second ^= serial + 0x9e3779b97f4a7c15ull;
272
274 for (std::size_t index = 0; index < sizeof(first); ++index)
275 bytes[index] = static_cast<std::uint8_t>((first >> (index * 8u)) & 0xffu);
276 for (std::size_t index = 0; index < sizeof(second); ++index)
277 bytes[sizeof(first) + index] = static_cast<std::uint8_t>((second >> (index * 8u)) & 0xffu);
278 // Mark the derived value as a conventional UUID variant/version while
279 // retaining deterministic bytes.
280 bytes[6] = static_cast<std::uint8_t>((bytes[6] & 0x0fu) | 0x50u);
281 bytes[8] = static_cast<std::uint8_t>((bytes[8] & 0x3fu) | 0x80u);
283 return EventId(bytes);
284}
285
288public:
297 public:
299 virtual ~PreparedState() = default;
300
302 virtual void commit() noexcept = 0;
303
305 virtual void rollback() noexcept = 0;
306 };
307
308 virtual ~IContainer() = default;
309
311 [[nodiscard]] virtual const ContainerDescriptor& descriptor() const noexcept = 0;
313 [[nodiscard]] virtual Result<ContainerSnapshot> snapshot() const = 0;
315 [[nodiscard]] virtual Result<void> validateInsert(
316 const ContainerObject& object, std::optional<SlotIndex> destination,
317 std::optional<MembershipId> ignoredObject = std::nullopt) const = 0;
318
329 [[nodiscard]] virtual Result<std::unique_ptr<PreparedState>> prepare(const ContainerSnapshot& expected,
330 const ContainerSnapshot& candidate) = 0;
331};
332
343
351using TransferEventSink = std::function<void(const TransferEvent&)>;
352
355 IContainer* source = nullptr;
356 IContainer* destination = nullptr;
358 std::optional<SlotIndex> sourceSlot;
359 std::optional<SlotIndex> destinationSlot;
360 std::optional<Revision> expectedSourceRevision;
361 std::optional<Revision> expectedDestinationRevision;
362};
363
374
381public:
389 [[nodiscard]] static Result<TransferReceipt> transfer(const TransferRequest& request,
390 TransferEventSink eventSink = {});
391};
392
393// ---- Strong coordinate-space zone contract --------------------------------
394
396struct ScreenSpace {};
398struct World2DSpace {};
400struct World3DSpace {};
402struct GridSpace {};
403
404template <class Space>
407 float x = 0.f;
408 float y = 0.f;
409};
410
412template <>
415 float x = 0.f;
416 float y = 0.f;
417 float z = 0.f;
418};
419
420template <class Space>
422struct Rectangle {
424 float width = 0.f;
425 float height = 0.f;
426};
427
428template <class Space>
430struct Circle {
432 float radius = 0.f;
433};
434
436struct Box3D {
438 float width = 0.f;
439 float height = 0.f;
440 float depth = 0.f;
441};
442
448
449template <class Space>
452 using type = std::variant<Rectangle<Space>, Circle<Space>>;
453};
454
455template <>
458 using type = std::variant<Box3D, Sphere3D>;
459};
460
461template <class Space>
463
466
471template <class Space>
473class Zone {
474public:
484 Capacity capacity = Capacity::unlimited(),
485 AcceptedCondition accepted = {}) {
486 if (!id.isValid()) {
490 Diagnostic::error(DiagnosticCode::InvalidArgument, "zone id must not be empty"));
491 }
492 if (!validShape(shape)) {
496 Diagnostic::error(DiagnosticCode::InvalidArgument, "zone shape must have positive dimensions"));
497 }
499 return Result<Zone>::success(Zone(std::move(id), std::move(shape), capacity, std::move(accepted)));
500 }
501
508 [[nodiscard]] static Result<Zone> create(ZoneShape<Space> shape, Capacity capacity = Capacity::unlimited(),
509 AcceptedCondition accepted = {}) {
511 return create(ContainerId("zone:anonymous"), std::move(shape), capacity, std::move(accepted));
512 }
513
515 [[nodiscard]] bool isValid() const noexcept { return valid_; }
516
518 [[nodiscard]] const ContainerId& id() const noexcept { return id_; }
519
521 [[nodiscard]] bool hasIdentity() const noexcept { return id_.isValid(); }
522
524 [[nodiscard]] bool contains(Coordinate<Space> point) const noexcept {
525 return std::visit(
526 [point](const auto& shape) {
527 using Shape = std::decay_t<decltype(shape)>;
529 if constexpr (std::is_same_v<Space, World3DSpace>) {
531 if constexpr (std::is_same_v<Shape, Box3D>) {
532 return point.x >= shape.origin.x && point.y >= shape.origin.y && point.z >= shape.origin.z &&
533 point.x <= shape.origin.x + shape.width && point.y <= shape.origin.y + shape.height &&
534 point.z <= shape.origin.z + shape.depth;
535 } else {
536 const float dx = point.x - shape.center.x;
537 const float dy = point.y - shape.center.y;
538 const float dz = point.z - shape.center.z;
539 return dx * dx + dy * dy + dz * dz <= shape.radius * shape.radius;
540 }
541 } else if constexpr (std::is_same_v<Shape, Rectangle<Space>>) {
542 return point.x >= shape.origin.x && point.y >= shape.origin.y &&
543 point.x <= shape.origin.x + shape.width && point.y <= shape.origin.y + shape.height;
544 } else {
545 const float dx = point.x - shape.center.x;
546 const float dy = point.y - shape.center.y;
547 return dx * dx + dy * dy <= shape.radius * shape.radius;
548 }
549 },
550 shape_);
551 }
552
554 [[nodiscard]] Result<void> accepts(const ContainerObject& object) const { return accepted_.evaluate(object); }
556 [[nodiscard]] const AcceptedCondition& acceptedCondition() const noexcept { return accepted_; }
558 [[nodiscard]] Capacity capacity() const noexcept { return capacity_; }
560 [[nodiscard]] const ZoneShape<Space>& shape() const noexcept { return shape_; }
561
562private:
564 : id_(std::move(id)),
565 shape_(std::move(shape)),
566 capacity_(capacity),
567 accepted_(std::move(accepted)),
568 valid_(true) {}
569
570 [[nodiscard]] static bool validShape(const ZoneShape<Space>& shape) noexcept {
571 return std::visit(
572 [](const auto& value) {
573 using Shape = std::decay_t<decltype(value)>;
574 if constexpr (std::is_same_v<Shape, Rectangle<Space>>) {
575 return std::isfinite(value.origin.x) && std::isfinite(value.origin.y) &&
576 std::isfinite(value.width) && std::isfinite(value.height) && value.width > 0.f &&
577 value.height > 0.f;
578 } else if constexpr (std::is_same_v<Shape, Box3D>) {
579 return std::isfinite(value.origin.x) && std::isfinite(value.origin.y) &&
580 std::isfinite(value.origin.z) && std::isfinite(value.width) && std::isfinite(value.height) &&
581 std::isfinite(value.depth) && value.width > 0.f && value.height > 0.f && value.depth > 0.f;
582 } else if constexpr (std::is_same_v<Space, World3DSpace>) {
583 return std::isfinite(value.center.x) && std::isfinite(value.center.y) &&
584 std::isfinite(value.center.z) && std::isfinite(value.radius) && value.radius > 0.f;
585 } else {
586 return std::isfinite(value.center.x) && std::isfinite(value.center.y) &&
587 std::isfinite(value.radius) && value.radius > 0.f;
588 }
589 },
590 shape);
591 }
592
593 ContainerId id_;
594 ZoneShape<Space> shape_;
595 Capacity capacity_;
596 AcceptedCondition accepted_;
597 bool valid_ = false;
598};
599
600} // namespace eve::container
601
602namespace std {
603template <>
605struct hash<eve::container::ContainerId> {
607 size_t operator()(const eve::container::ContainerId& value) const noexcept { return hash<string>{}(value.value()); }
608};
609template <>
611struct hash<eve::container::MembershipId> {
613 size_t operator()(const eve::container::MembershipId& value) const noexcept {
614 return hash<string>{}(value.value());
615 }
616};
617} // namespace std
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::array< std::uint8_t, 32 > hash
Definition Evpack.cpp:172
#define EVENGINE_API_FOUNDATION
每个链接组(link group)各自的导出宏。
Definition Export.h:106
Runtime replacement generation for stale-handle rejection.
const GltfImportRequest & request
std::uint32_t capacity
ShaderImageInput shape
std::int32_t second
std::int32_t first
Strong identity values shared by persistence, content and logical-name APIs.
std::uint32_t height
std::uint32_t width
std::string text
TokenKind kind
std::uint64_t bytes
float radius
std::string id
Definition PlayHost.cpp:108
Move-only, checked operation results for the common layer.
Monotonic state revision for concurrency and change checks.
float dz
float dy
float dx
uint64_t serial
Definition UISystem.cpp:68
uint32_t index
const UnitySourceAsset & source
std::uint32_t depth
glm::vec3 point
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
Non-negative capacity measured in membership slots.
Definition Container.h:92
static constexpr Capacity fixed(std::size_t value) noexcept
Construct a fixed capacity.
Definition Container.h:95
constexpr std::size_t value() const noexcept
Definition Container.h:99
constexpr bool isUnlimited() const noexcept
Definition Container.h:98
static constexpr Capacity unlimited() noexcept
Construct an unbounded capacity.
Definition Container.h:97
Strong identity of one runtime or persistent container.
Definition Container.h:44
ContainerId(std::string value)
Constructs a ContainerId.
Definition Container.h:49
friend bool operator==(const ContainerId &, const ContainerId &) noexcept=default
static std::optional< ContainerId > from(std::string_view value)
Construct a valid ID, rejecting an empty value.
Definition Container.h:52
bool isValid() const noexcept
Return whether this ID is usable by a transfer request.
Definition Container.h:58
ContainerId()=default
Constructs a ContainerId.
const std::string & value() const noexcept
Return the owned stable spelling.
Definition Container.h:60
Extensible filter result used by container and zone acceptance rules.
Definition Container.h:139
std::function< Result< void >(const ContainerObject &)> Predicate
Definition Container.h:141
Filter(Predicate predicate)
Constructs a Filter.
Definition Container.h:146
Filter()=default
Constructs a Filter.
Result< void > evaluate(const struct ContainerObject &object) const
Evaluate the filter; an empty filter accepts every object.
Definition Container.h:149
bool empty() const noexcept
Empty.
Definition Container.h:155
Detached state prepared for an atomic container replacement.
Definition Container.h:296
virtual ~PreparedState()=default
Releases PreparedState resources.
virtual void rollback() noexcept=0
Abandon an unpublished stage; the operation is non-throwing.
virtual void commit() noexcept=0
Publish the staged state; the operation is non-throwing.
Borrowed container implementation owned by a domain adapter.
Definition Container.h:287
virtual const ContainerDescriptor & descriptor() const noexcept=0
Return immutable container metadata.
virtual Result< std::unique_ptr< PreparedState > > prepare(const ContainerSnapshot &expected, const ContainerSnapshot &candidate)=0
Prepare an exact replacement from expected to candidate.
virtual Result< void > validateInsert(const ContainerObject &object, std::optional< SlotIndex > destination, std::optional< MembershipId > ignoredObject=std::nullopt) const =0
Validate insertion while optionally ignoring one moved object.
virtual Result< ContainerSnapshot > snapshot() const =0
Return current lossless state without retaining adapter pointers.
Strong identity of an object which can have one container membership.
Definition Container.h:68
bool isValid() const noexcept
Return whether this identity is usable.
Definition Container.h:82
static std::optional< MembershipId > from(std::string_view value)
Construct a valid membership ID, rejecting an empty value.
Definition Container.h:76
friend bool operator==(const MembershipId &, const MembershipId &) noexcept=default
MembershipId()=default
Constructs a MembershipId.
const std::string & value() const noexcept
Return the owned stable spelling.
Definition Container.h:84
MembershipId(std::string value)
Constructs a MembershipId.
Definition Container.h:73
Explicit slot number; it never implicitly converts to an integer.
Definition Container.h:117
static constexpr SlotIndex invalid() noexcept
Invalid.
Definition Container.h:124
constexpr std::int32_t value() const noexcept
Value.
Definition Container.h:128
constexpr SlotIndex() noexcept=default
Constructs a SlotIndex.
friend constexpr bool operator==(const SlotIndex &, const SlotIndex &) noexcept=default
Operator ==.
constexpr bool isValid() const noexcept
True when valid.
Definition Container.h:126
friend constexpr auto operator<=>(const SlotIndex &, const SlotIndex &) noexcept=default
Operator <=>.
Atomic preflight/prepare/commit coordinator for one or two adapters.
Definition Container.h:380
Shape-bounded, capacity-limited zone in one compile-time coordinate space.
Definition Container.h:473
bool contains(Coordinate< Space > point) const noexcept
Test a point from exactly this zone's coordinate space.
Definition Container.h:524
const ZoneShape< Space > & shape() const noexcept
Return the immutable shape in this zone's coordinate space.
Definition Container.h:560
Capacity capacity() const noexcept
Return the maximum number of memberships accepted by this zone.
Definition Container.h:558
static Result< Zone > create(ZoneShape< Space > shape, Capacity capacity=Capacity::unlimited(), AcceptedCondition accepted={})
Validate and construct an anonymous compatibility zone.
Definition Container.h:508
static Result< Zone > create(ContainerId id, ZoneShape< Space > shape, Capacity capacity=Capacity::unlimited(), AcceptedCondition accepted={})
Validate and construct a named zone.
Definition Container.h:483
const ContainerId & id() const noexcept
Return the stable identity supplied at construction.
Definition Container.h:518
bool isValid() const noexcept
Return whether this factory-created zone contains valid geometry.
Definition Container.h:515
const AcceptedCondition & acceptedCondition() const noexcept
Return the side-effect-free accepted condition.
Definition Container.h:556
bool hasIdentity() const noexcept
Return whether this zone has a usable stable identity.
Definition Container.h:521
Result< void > accepts(const ContainerObject &object) const
Test the zone's accepted-condition without mutating membership.
Definition Container.h:554
Id128 public API.
Definition Identity.h:112
std::array< std::uint8_t, 16 > Bytes
Definition Identity.h:114
typename ZoneShapeTraits< Space >::type ZoneShape
Definition Container.h:462
constexpr std::string_view containerEventSchemaName
Canonical schema name for container lifecycle envelopes.
Definition Container.h:232
std::function< void(const TransferEvent &)> TransferEventSink
Synchronous callback receiving a committed transfer payload.
Definition Container.h:351
Filter AcceptedCondition
Accepted-condition callback for a zone, shared with container filters.
Definition Container.h:465
ContainerEventKind
Lifecycle outcome represented by every container-domain event.
Definition Container.h:205
const char * containerEventTypeName(ContainerEventKind kind) noexcept
Stable event type spelling shared by all container adapters.
Definition Container.h:221
Ordering
Stable order semantics owned by a container adapter.
Definition Container.h:108
std::function< void(const game_event::GameEvent &)> GameEventSink
Callback receiving a canonical game_event envelope.
Definition Container.h:245
EventId deterministicContainerEventId(const ContainerId &container, const MembershipId &object, ContainerEventKind kind, std::uint64_t serial) noexcept
Derives a deterministic event identity for an adapter lifecycle event.
Definition Container.h:257
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16
detail::StrongUint64< detail::GenerationTag > Generation
Registry/object replacement generation used to reject stale handles.
Definition Generation.h:13
detail::StrongUint64< detail::RevisionTag > Revision
Monotonic content/state revision used for optimistic-concurrency checks.
Definition Revision.h:13
StrongUuid< detail::EventIdTag > EventId
Stable event identity for event envelopes and causal references.
Definition Identity.h:285
Axis-aligned 3D box for World3DSpace zones.
Definition Container.h:436
Coordinate< World3DSpace > origin
Definition Container.h:437
Circle public API.
Definition Container.h:430
Coordinate< Space > center
Definition Container.h:431
Static metadata and acceptance policy of a container.
Definition Container.h:197
Opaque, owning payload supplied by a domain adapter during transfer.
Definition Container.h:162
virtual ~ContainerObjectPayload()=default
Releases ContainerObjectPayload resources.
Generic object facts used by filters and transfer diagnostics.
Definition Container.h:168
std::shared_ptr< const ContainerObjectPayload > payload
Definition Container.h:173
std::vector< std::string > tags
Definition Container.h:171
Lossless snapshot of one container at one revision.
Definition Container.h:190
std::vector< MembershipEntry > entries
Definition Container.h:193
Coordinate public API.
Definition Container.h:406
GridSpace public API.
Definition Container.h:402
Complete adapter-owned state used to build a candidate replacement.
Definition Container.h:184
One object-to-slot relationship, including the observed generation.
Definition Container.h:177
Rectangle public API.
Definition Container.h:422
Coordinate< Space > origin
Definition Container.h:423
Coordinate-space tags; distinct types prevent accidental mixing.
Definition Container.h:396
Spherical 3D shape for World3DSpace zones.
Definition Container.h:444
Coordinate< World3DSpace > center
Definition Container.h:445
Strong event payload emitted only after a transfer is fully committed.
Definition Container.h:334
Observable receipt for one committed or explicit no-op transfer.
Definition Container.h:365
Requested optimistic-concurrency transfer. All pointers are borrowed.
Definition Container.h:354
std::optional< Revision > expectedDestinationRevision
Definition Container.h:361
std::optional< SlotIndex > destinationSlot
Definition Container.h:359
std::optional< Revision > expectedSourceRevision
Definition Container.h:360
std::optional< SlotIndex > sourceSlot
Definition Container.h:358
World2DSpace public API.
Definition Container.h:398
World3DSpace public API.
Definition Container.h:400
std::variant< Box3D, Sphere3D > type
Definition Container.h:458
ZoneShapeTraits public API.
Definition Container.h:451
std::variant< Rectangle< Space >, Circle< Space > > type
Definition Container.h:452
Envelope metadata shared by event domains.
Definition GameEvent.h:183