TachyonUI 0.1.0
High-performance UI for building tools.
Loading...
Searching...
No Matches
gui_id_manager.h
Go to the documentation of this file.
1#pragma once
2
4
5#include <stdint.h>
6#include <source_location>
7#include <vector>
8#include <string_view>
9
10// Uncomment to enable debug ID tracking
11//#define TACHYON_ID_DEBUG
12
13// ID system: static, dynamic and ranged identifiers for GUI elements.
14namespace tachyon
15{
18
19 struct ID;
27 {
28 // ------------------------------------------------------------------------
29 // Constructor
30 // ------------------------------------------------------------------------
31 public: IDManager()
32 {
33 m_parent_stack.reserve(4096);
34 m_static_slots.reserve(4096);
35 m_static_free_list.reserve(4096);
36 }
37
38 // ------------------------------------------------------------------------
39 // Frame Management
40 // ------------------------------------------------------------------------
41
44 public: [[nodiscard]] bool BeginFrame();
45
47 public: void EndFrame();
48
50 public: [[nodiscard]] inline bool IsInsideFrame() const { return !m_parent_stack.empty(); }
51
52 // ------------------------------------------------------------------------
53 // Parent Stack
54 // ------------------------------------------------------------------------
55
58 public: [[nodiscard]] bool PushParent(ID parent_id);
59
61 public: [[nodiscard]] bool PopParent();
62
63 // ------------------------------------------------------------------------
64 // Static IDs
65 // ------------------------------------------------------------------------
66
68 public: [[nodiscard]] ID CreateStaticID();
69
72 public: bool ReleaseStaticID(ID id);
73
74 // Tests reach it through IDManagerTestAccess (defined in the tests).
75 private: bool SetGenerationForSlot(uint32_t index, int32_t generation);
76 friend struct IDManagerTestAccess;
77
79 public: bool IsStaticIDValid(ID id) const;
80
81 // ------------------------------------------------------------------------
82 // Dynamic IDs
83 // ------------------------------------------------------------------------
84
85 private: [[nodiscard]] ID AllocateDynamicID(uint64_t hash);
86
87#ifdef TACHYON_SUPPORT_CPP20
90 public: [[nodiscard]] inline ID AllocateDynamicID(const std::source_location location = std::source_location::current())
91 {
92 return AllocateDynamicID(location.file_name(), location.line());
93 }
94#endif
95
98 public: [[nodiscard]] ID AllocateDynamicID(std::string_view file, int line);
99
102 public: [[nodiscard]] ID AllocateDynamicID(std::string_view hint);
103
105 public: [[nodiscard]] bool IsDynamicIDValid(ID id) const;
106
107 // ------------------------------------------------------------------------
108 // Ranged IDs
109 // ------------------------------------------------------------------------
110
111 private: [[nodiscard]] ID AllocateRangedID(uint32_t size, uint64_t hash);
112
113#ifdef TACHYON_SUPPORT_CPP20
116 public: [[nodiscard]] inline ID AllocateRangedID(uint32_t size, const std::source_location location = std::source_location::current())
117 {
118 return AllocateRangedID(size, location.file_name(), location.line());
119 }
120#endif
123 public: [[nodiscard]] ID AllocateRangedID(uint32_t size, std::string_view file, int line);
124
126 public: [[nodiscard]] ID AllocateRangedID(uint32_t size, std::string_view hint);
127
129 public: uint32_t GetRangeSize(ID ranged_id) const;
130
132 public: bool IsRangedIDValid(ID id) const;
133
136 public: [[nodiscard]] ID GetSubID(ID ranged_id, uint32_t index) const;
137
139 public: bool IsSubRangeIDValid(ID id) const;
140
141 // ------------------------------------------------------------------------
142 // Parent Stack Utilities
143 // ------------------------------------------------------------------------
144
146 public: bool IsInParentStack(ID id) const;
147
149 public: ID GetStackParent() const;
150
151
152 // ------------------------------------------------------------------------
153 // Validation
154 // ------------------------------------------------------------------------
155
157 public: bool IsIDValid(ID id) const;
158
161 public: inline size_t GetStaticIDCount() const { return m_static_id_count; }
162 public: inline size_t GetDynamicIDCount() const { return m_dynamic_id_total; }
163 public: inline size_t GetRangedIDCount() const { return m_ranged_count; }
165
166
167
168 private:
169 struct ParentData
170 {
171 ID id;
172 };
173
174 // Parent stack for hierarchical hashing
175 std::vector<ParentData> m_parent_stack;
176 // Dynamic IDs made so far this frame per call site (or hint) and parent: only a
177 // repeat of the same site renumbers, so a widget appearing elsewhere doesn't. A flat
178 // open-addressed table: a slot stamped with an older frame is empty, so a new frame
179 // clears nothing and allocates nothing once the table has grown.
180 struct SiteSlot { uint64_t site = 0; uint32_t count = 0; uint32_t frame = 0; };
181 std::vector<SiteSlot> m_site_slots = std::vector<SiteSlot>(1024);
182 uint32_t m_site_used = 0;
183 uint32_t m_frame = 0;
184 uint32_t NextSiteCount(uint64_t site);
185
186 // Static ID management (slot map with generations)
187 std::vector<int32_t> m_static_slots;
188 std::vector<uint32_t> m_static_free_list;
189 size_t m_static_id_count = 0;
190
191 // Dynamic ID tracking
192 size_t m_dynamic_id_total = 0;
193
194 // Ranged ID tracking
195 size_t m_ranged_count = 0;
196
197#ifdef TACHYON_ID_DEBUG
198 std::vector<ID> m_debug_dynamic_ids;
199 std::vector<ID> m_debug_ranges;
200#endif
201 };
202
204} // namespace tachyon
ID GetSubID(ID ranged_id, uint32_t index) const
The ID of item index (< range size) in a ranged ID, for indexed content such as list rows.
bool IsInsideFrame() const
True between BeginFrame and EndFrame.
Definition gui_id_manager.h:50
ID AllocateRangedID(uint32_t size, std::string_view file, int line)
A ranged ID of size sub-IDs from file and line (FILE, LINE) and the parent stack.
size_t GetDynamicIDCount() const
Live static IDs, and dynamic / ranged IDs made so far this frame.
Definition gui_id_manager.h:162
bool PopParent()
Pops the last PushParent. Never pops the root; false on underflow or outside a frame.
bool IsStaticIDValid(ID id) const
True if the slot is active and the generation matches.
ID GetStackParent() const
The innermost parent; Invalid at the root or outside a frame.
ID AllocateDynamicID(std::string_view file, int line)
A dynamic ID from file and line (FILE, LINE) and the parent stack; different per call site.
void EndFrame()
Clears the parent stack; reports misuse when a PushParent was left unpopped.
size_t GetStaticIDCount() const
Live static IDs, and dynamic / ranged IDs made so far this frame.
Definition gui_id_manager.h:161
friend struct IDManagerTestAccess
Definition gui_id_manager.h:76
IDManager()
Definition gui_id_manager.h:31
bool BeginFrame()
Resets the parent stack and dynamic/ranged counters.
ID AllocateRangedID(uint32_t size, std::string_view hint)
A ranged ID of size sub-IDs from hint and the parent stack; different per hint.
uint32_t GetRangeSize(ID ranged_id) const
The number of sub-IDs in a ranged ID; 0 (and a misuse report) for other modes.
bool ReleaseStaticID(ID id)
Frees the slot and bumps its generation, invalidating copies of id.
bool IsRangedIDValid(ID id) const
Debug: checks stored ranges (slow). Release: true for any non-Invalid Ranged ID.
bool IsInParentStack(ID id) const
True when id is anywhere on the parent stack. Slow: linear search.
bool IsIDValid(ID id) const
True when id is valid for its mode (see the Is*IDValid functions); slow in debug builds.
bool IsSubRangeIDValid(ID id) const
Debug: checks stored ranges (slow). Release: true for any non-Invalid SubRange ID.
bool PushParent(ID parent_id)
Makes parent_id the parent: dynamic and ranged IDs created under it inherit its hash.
bool IsDynamicIDValid(ID id) const
Debug: checks the tracking list (slow). Release: true for any non-Invalid Dynamic ID.
ID CreateStaticID()
A persistent ID tracked by slot and generation; release it with ReleaseStaticID.
ID AllocateDynamicID(std::string_view hint)
A dynamic ID from hint and the parent stack; different per hint.
size_t GetRangedIDCount() const
Live static IDs, and dynamic / ranged IDs made so far this frame.
Definition gui_id_manager.h:163
Definition gui_logging.h:24
A 64-bit element ID whose bit layout depends on its IDMode.
Definition gui_id.h:23