Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
Handle.h
Go to the documentation of this file.
1
6
7#pragma once
8#ifndef ECS__HANDLE_H__
9#define ECS__HANDLE_H__
10
11#include "API.h"
12
13#pragma warning(push)
14
15// warning C4293: '<<': shift count negative or too big, undefined behavior
16// note we are using a static_assert to ensure this won't be the case.
17#pragma warning(disable: 4293)
18
19namespace ECS { namespace util {
20
21 namespace Internal
22 {
34
35 template<
36 typename handle_value_type,
37 size_t version_bits,
38 size_t index_bits
39 >
40 union Handle
41 {
42 static_assert(sizeof(handle_value_type) * CHAR_BIT >= (version_bits + index_bits), "Invalid handle layout. More bits used than base value type can hold!");
43
44 using value_type = handle_value_type;
45
46 static constexpr size_t NUM_VERSION_BITS { version_bits };
47 static constexpr size_t NUM_INDEX_BITS { index_bits };
48
49
50 static constexpr value_type MIN_VERISON { 0 };
51 static constexpr value_type MAX_VERSION { ((value_type)1 << NUM_VERSION_BITS) - 2U };
52 static constexpr value_type MAX_INDICES { ((value_type)1 << NUM_INDEX_BITS) - 2U };
53
54 static constexpr value_type INVALID_HANDLE { std::numeric_limits<value_type>::max() };
55
56 private:
57
59
60 public:
61
62 struct
63 {
66 };
67
68
70 {}
71
74 {}
75
77 index(index),
79 {}
80
81 inline operator value_type() const { return value; }
82
83 inline bool operator==(const Handle& other) const { return this->version == other.version && this->index == other.index; }
84 inline bool operator!=(const Handle& other) const { return this->version != other.version || this->index != other.index; }
85 };
86 } // namespace Internal
87
88
89
94
95
99#ifdef ECS_64BIT
101#else
103#endif
104
105
106 template<class T, class handle_type, size_t grow = 1024>
108 {
109 using Handle = handle_type;
110
111 private:
112
113 using TableEntry = std::pair<typename Handle::value_type, T*>;
114
115 std::vector<TableEntry> m_Table;
116
117
119 {
120 size_t oldSize = this->m_Table.size();
121
122 assert(oldSize < Handle::MAX_INDICES && "Max table capacity reached!");
123
124 size_t newSize = std::min(oldSize + grow, Handle::MAX_INDICES);
125
126 this->m_Table.resize(newSize);
127
128 for (typename Handle::value_type i = oldSize; i < newSize; ++i)
129 this->m_Table[i] = TableEntry(Handle::MIN_VERISON, nullptr);
130 }
131
132 public:
133
135 {
136 this->GrowTable();
137 }
138
140 {}
141
142 Handle AcquireHandle(T* rawObject)
143 {
144 typename Handle::value_type i = 0;
145 for (; i < this->m_Table.size(); ++i)
146 {
147 if (this->m_Table[i].second == nullptr)
148 {
149 this->m_Table[i].second = rawObject;
150
151 this->m_Table[i].first = ((this->m_Table[i].first + 1) > Handle::MAX_VERSION) ? Handle::MIN_VERISON : this->m_Table[i].first + 1;
152
153 return Handle(i, this->m_Table[i].first);
154 }
155 }
156
157 // grow table
158 this->GrowTable();
159
160 this->m_Table[i].first = 1;
161 this->m_Table[i].second = rawObject;
162
163 return Handle(i, this->m_Table[i].first);
164 }
165
167 {
168 assert((handle.index < this->m_Table.size() && handle.version == this->m_Table[handle.index].first) && "Invalid handle!");
169 this->m_Table[handle.index].second = nullptr;
170 }
171
187
188 inline bool IsExpired(Handle handle) const
189 {
190 return this->m_Table[handle.index].first != handle.version;
191 }
192
207
208 inline Handle operator[](typename Handle::value_type index) const
209 {
210 assert(index < this->m_Table.size() && "Invalid handle!");
211 return Handle(index, this->m_Table[index].first);
212 }
213
228
229 inline T* operator[](Handle handle)
230 {
231 assert((handle.index < this->m_Table.size() && handle.version == this->m_Table[handle.index].first) && "Invalid handle!");
232 return (this->m_Table[handle.index].first == handle.version ? this->m_Table[handle.index].second : nullptr);
233 }
234
235 }; // class HandleTable
236
237}} // namespace ECS::util
238
239#pragma warning(pop)
240
241#endif // ! ECS__HANDLE_H__
handle_type Handle
Definition: Handle.h:109
void ReleaseHandle(Handle handle)
Definition: Handle.h:166
std::pair< typename Handle::value_type, T * > TableEntry
Definition: Handle.h:113
bool IsExpired(Handle handle) const
Definition: Handle.h:188
T * operator[](Handle handle)
Definition: Handle.h:229
Handle operator[](typename Handle::value_type index) const
Definition: Handle.h:208
std::vector< TableEntry > m_Table
Definition: Handle.h:115
Handle AcquireHandle(T *rawObject)
Definition: Handle.h:142
Internal::Handle< u32, 12, 20 > Handle32
Definition: Handle.h:93
Handle(value_type index, value_type version)
Definition: Handle.h:76
handle_value_type value_type
Definition: Handle.h:44
Handle(value_type value)
Definition: Handle.h:72
static constexpr value_type MIN_VERISON
Definition: Handle.h:50
static constexpr size_t NUM_INDEX_BITS
Definition: Handle.h:47
static constexpr value_type MAX_VERSION
Definition: Handle.h:51
static constexpr size_t NUM_VERSION_BITS
Definition: Handle.h:46
static constexpr value_type INVALID_HANDLE
Definition: Handle.h:54
bool operator==(const Handle &other) const
Definition: Handle.h:83
static constexpr value_type MAX_INDICES
Definition: Handle.h:52
bool operator!=(const Handle &other) const
Definition: Handle.h:84