Skip to main content

DenseRuntimeHandleRegistry.ixx File

Dense registry mapping strong identifiers to contiguous runtime indices. More...

Included Headers

#include <vector> #include <helios/helios_config.h> #include <cassert> #include <optional> #include <string> #include <algorithm> #include <helios.core.types> #include <helios.core.data.RuntimeHandle> #include <helios.core.data.StrongId>

Namespaces Index

namespacehelios
namespacecore

Core utilities shared across the helios engine. More...

namespacecontainer

Generic container types shared across the engine. More...

Classes Index

classDenseRuntimeHandleRegistry<StrongIdentifier, RuntimeId>

Maps strong identifiers to dense, contiguous runtime indices. More...

Description

Dense registry mapping strong identifiers to contiguous runtime indices.

File Listing

The file content with the documentation metadata removed is:

1/**
2 * @file DenseRuntimeHandleRegistry.ixx
3 * @brief Dense registry mapping strong identifiers to contiguous runtime indices.
4 */
5module;
6
7#include <vector>
8#include <helios/helios_config.h>
9#include <cassert>
10#include <optional>
11#include <string>
12#include <algorithm>
13
14export module helios.core.container.DenseRuntimeHandleRegistry;
15
16import helios.core.data.StrongId;
17import helios.core.data.RuntimeHandle;
18import helios.core.types;
19
20using namespace helios::core::types;
21using namespace helios::core::data;
22export namespace helios::core::container {
23
24 /**
25 * @brief Maps strong identifiers to dense, contiguous runtime indices.
26 *
27 * @details `DenseRuntimeHandleRegistry` maintains a compact vector of
28 * `StrongId` values. The position of each entry in the vector serves as
29 * its `RuntimeId`, enabling O(1) access in downstream pools that are
30 * indexed by the same `RuntimeId`.
31 *
32 * Registration is idempotent: calling `getOrCreate()` with an already
33 * registered identifier returns the existing handle without duplication.
34 *
35 * ## Complexity
36 *
37 * - `has()` / `runtimeId()` — O(n) linear scan.
38 * - `getOrCreate()` — O(n) lookup + amortised O(1) append on miss.
39 *
40 * ## Usage
41 *
42 * ```cpp
43 * using MeshHandleRegistry =
44 * DenseRuntimeHandleRegistry<MeshId, MeshRuntimeId>;
45 *
46 * MeshHandleRegistry registry;
47 * auto handle = registry.getOrCreate("player_mesh");
48 * auto runtimeId = handle.runtimeId; // dense index into MeshPool
49 * bool exists = registry.has(MeshId{"player_mesh"});
50 * ```
51 *
52 * @tparam StrongIdentifier A `StrongId<Tag>` type used as the stable key.
53 * @tparam RuntimeId An unsigned integer type (typically `uint32_t`) used as
54 * the dense index.
55 *
56 * @see RuntimeHandle
57 * @see StrongId
58 */
59 template<typename StrongIdentifier, typename RuntimeId>
61
62 /**
63 * @brief Dense storage of registered strong-ID values.
64 *
65 * @details The index of each entry is its corresponding `RuntimeId`.
66 */
67 std::vector<StrongId_t> ids_;
68
69 public:
70
71 /**
72 * @brief Constructs the registry with a reserved capacity.
73 *
74 * @param defaultCapacity Initial capacity hint for the internal vector.
75 */
76 explicit DenseRuntimeHandleRegistry(const size_t defaultCapacity = DEFAULT_RUNTIME_HANDLE_REGISTRY_CAPACITY) {
77 ids_.reserve(defaultCapacity);
78 }
79
80 /**
81 * @brief Checks whether a strong identifier is registered.
82 *
83 * @param strongId The identifier to look up.
84 *
85 * @return True if the identifier is present.
86 */
87 [[nodiscard]] bool has(StrongIdentifier strongId) const noexcept {
88 return std::ranges::find(ids_, strongId.value()) != ids_.end();
89 }
90
91 /**
92 * @brief Returns the runtime index for a registered identifier.
93 *
94 * @param strongId The identifier to look up.
95 *
96 * @return The associated `RuntimeId`, or `std::nullopt` if not registered.
97 */
98 [[nodiscard]] std::optional<RuntimeId> runtimeId(StrongIdentifier strongId) const noexcept {
99 auto it = std::ranges::find(ids_, strongId.value());
100
101 if (it == ids_.end()) {
102 return std::nullopt;
103 }
104
105 return RuntimeId{static_cast<RuntimeId>(
106 std::distance(ids_.begin(), it))
107 };
108 }
109
110 /**
111 * @brief Returns an existing handle or creates a new one from a string key.
112 *
113 * @details Constructs a `StrongIdentifier` from `strId` and delegates
114 * to the `StrongIdentifier` overload.
115 *
116 * @param strId String key that is hashed into a `StrongIdentifier`.
117 *
118 * @return The existing or newly created handle.
119 */
121 return getOrCreate(StrongIdentifier{std::move(strId)});
122 }
123
124 /**
125 * @brief Returns an existing handle or registers a new entry.
126 *
127 * @details If the identifier is already registered, the existing
128 * handle is returned. Otherwise a new entry is appended and a fresh
129 * `RuntimeId` is assigned.
130 *
131 * @param strongId The identifier to register.
132 *
133 * @return The existing or newly created handle.
134 *
135 * @pre The registry must not have reached its reserved capacity.
136 */
138 const auto rid = runtimeId(strongId);
139 if (rid.has_value()) {
140 return RuntimeHandle<StrongIdentifier, RuntimeId>(strongId, *rid);
141 }
142
143 assert(ids_.size() < ids_.capacity() && "DenseRuntimeHandleRegistry capacity exceeded");
144 ids_.push_back(strongId.value());
146 strongId,
147 RuntimeId{static_cast<RuntimeId>(ids_.size() - 1)}
148 };
149 }
150 };
151
152}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.