Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
nonfragmenting_relation_store.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstdint>
5
6#include "gaia/cnt/darray.h"
7#include "gaia/core/utility.h"
8#include "gaia/ecs/id.h"
9
10namespace gaia {
11 namespace ecs {
12 namespace detail {
15 private:
17 cnt::darray<Entity> srcToTgt;
19 cnt::darray<uint32_t> srcToTgtIdx;
21 uint32_t srcToTgtCnt = 0;
24
25 public:
29 const auto required = (uint32_t)source.id() + 1;
30 if (srcToTgt.size() >= required)
31 return;
32
33 const auto oldSize = (uint32_t)srcToTgt.size();
34 auto newSize = oldSize == 0 ? 16U : oldSize;
35 while (newSize < required)
36 newSize *= 2U;
37
38 srcToTgt.resize(newSize, EntityBad);
39 srcToTgtIdx.resize(newSize, BadIndex);
40 }
41
45 const auto required = target.id() + 1;
46 if (tgtToSrc.size() >= required)
47 return;
48
49 const auto oldSize = (uint32_t)tgtToSrc.size();
50 auto newSize = oldSize == 0 ? 16U : oldSize;
51 while (newSize < required)
52 newSize *= 2U;
53
54 tgtToSrc.resize(newSize);
55 }
56
60 GAIA_NODISCARD Entity target(Entity source) const {
61 if (source.id() >= srcToTgt.size())
62 return EntityBad;
63
64 return srcToTgt[source.id()];
65 }
66
70 GAIA_NODISCARD const cnt::darray<Entity>* sources(Entity target) const {
71 if (target.id() >= tgtToSrc.size())
72 return nullptr;
73
74 const auto& sources = tgtToSrc[target.id()];
75 return sources.empty() ? nullptr : &sources;
76 }
77
80 GAIA_NODISCARD uint32_t source_count() const {
81 return srcToTgtCnt;
82 }
83
87 out.reserve(out.size() + srcToTgtCnt);
88 GAIA_FOR((uint32_t)srcToTgt.size()) {
89 if (srcToTgt[i] == EntityBad)
90 continue;
91
92 out.push_back((EntityId)i);
93 }
94 }
95
100 GAIA_ASSERT(target.id() < tgtToSrc.size());
101 if (target.id() >= tgtToSrc.size())
102 return;
103
104 auto& sources = tgtToSrc[target.id()];
105 const auto idx = source.id() < srcToTgtIdx.size() ? srcToTgtIdx[source.id()] : BadIndex;
106 GAIA_ASSERT(idx != BadIndex && idx < sources.size());
107 if (idx == BadIndex || idx >= sources.size())
108 return;
109
110 const auto lastIdx = (uint32_t)sources.size() - 1;
111 if (idx != lastIdx) {
112 const auto movedSource = sources[lastIdx];
113 sources[idx] = movedSource;
114 GAIA_ASSERT(movedSource.id() < srcToTgtIdx.size());
115 srcToTgtIdx[movedSource.id()] = idx;
116 }
117
119 }
120
125 GAIA_NODISCARD bool set(Entity source, Entity target) {
127 const auto oldTarget = srcToTgt[source.id()];
128 if (oldTarget != EntityBad) {
129 if (oldTarget == target)
130 return false;
131
132 remove_target_source(oldTarget, source);
133 } else {
134 ++srcToTgtCnt;
135 }
136
138 auto& sources = tgtToSrc[target.id()];
139 srcToTgt[source.id()] = target;
140 srcToTgtIdx[source.id()] = (uint32_t)sources.size();
141 sources.push_back(source);
142
143 return true;
144 }
145
150 GAIA_NODISCARD bool remove(Entity source, Entity target) {
151 const auto oldTarget = this->target(source);
152 if (oldTarget == EntityBad)
153 return false;
154 if (target != EntityBad && oldTarget != target)
155 return false;
156
157 remove_target_source(oldTarget, source);
158 srcToTgt[source.id()] = EntityBad;
159 srcToTgtIdx[source.id()] = BadIndex;
160 GAIA_ASSERT(srcToTgtCnt > 0);
161 --srcToTgtCnt;
162 return true;
163 }
164
167 GAIA_NODISCARD bool empty() const {
168 return srcToTgtCnt == 0;
169 }
170 };
171 } // namespace detail
172 } // namespace ecs
173} // namespace gaia
Array with variable size of elements of type.
Definition darray_impl.h:27
void reserve(size_type cap)
Ensures storage for at least the requested number of elements.
Definition darray_impl.h:223
GAIA_NODISCARD size_type size() const noexcept
Returns the number of elements.
Definition darray_impl.h:504
void resize(size_type count)
Changes the number of elements.
Definition darray_impl.h:240
GAIA_NODISCARD bool empty() const noexcept
Checks whether the container has no elements.
Definition darray_impl.h:510
void pop_back() noexcept
Removes the last element.
Definition darray_impl.h:342
void push_back(const T &arg)
Appends an element.
Definition darray_impl.h:309
Identifier of an entity or component instance in the world. Packs the entity index,...
Definition id.h:296
GAIA_NODISCARD constexpr auto id() const noexcept
Entity index in the entity array.
Definition id.h:359
Storage for exclusive relation pairs that do not fragment archetypes.
Definition nonfragmenting_relation_store.h:14
void collect_source_ids(cnt::darray< EntityId > &out) const
Appends ids of all bound source entities.
Definition nonfragmenting_relation_store.h:86
GAIA_NODISCARD bool remove(Entity source, Entity target)
Removes source from the store.
Definition nonfragmenting_relation_store.h:150
GAIA_NODISCARD const cnt::darray< Entity > * sources(Entity target) const
Returns sources currently bound to target.
Definition nonfragmenting_relation_store.h:70
GAIA_NODISCARD Entity target(Entity source) const
Returns the target currently bound to source.
Definition nonfragmenting_relation_store.h:60
GAIA_NODISCARD bool set(Entity source, Entity target)
Binds source to target.
Definition nonfragmenting_relation_store.h:125
void ensure_target_capacity(Entity target)
Ensures target-indexed storage can hold target.
Definition nonfragmenting_relation_store.h:44
void remove_target_source(Entity target, Entity source)
Removes source from the source bucket for target.
Definition nonfragmenting_relation_store.h:99
GAIA_NODISCARD uint32_t source_count() const
Returns the number of active source bindings.
Definition nonfragmenting_relation_store.h:80
GAIA_NODISCARD bool empty() const
Checks whether the store has no source bindings.
Definition nonfragmenting_relation_store.h:167
void ensure_source_capacity(Entity source)
Ensures source-indexed storage can hold source.
Definition nonfragmenting_relation_store.h:28