Air-Trap 1.0.0
A multiplayer R-Type clone game engine built with C++23 and ECS architecture
Loading...
Searching...
No Matches
Registry.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** R-Type
4** File description:
5** Registry.cpp
6*/
7
8/*
9** MIT License
10**
11** Copyright (c) 2025 Robin Toillon
12**
13** Permission is hereby granted, free of charge, to any person obtaining
14** a copy of this software and associated documentation files (the
15** "Software"), to deal in the Software without restriction, including
16** without limitation the rights to use, copy, modify, merge, publish,
17** distribute, sublicense, and/or sell copies of the Software, and to
18** permit persons to whom the Software is furnished to do so, subject to
19** the following conditions:
20**
21** The above copyright notice and this permission notice shall be
22** included in all copies or substantial portions of the Software.
23**
24** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31*/
32
42#include "RType/Assert.hpp"
44
45namespace rtp::ecs
46{
48 // Public API
50
51 auto Registry::spawn(void) -> std::expected<Entity, rtp::Error>
52 {
53 std::unique_lock lock(this->_mutex);
54
55 if (!this->_freeIndices.empty()) {
56 std::size_t idx = this->_freeIndices.front();
57 this->_freeIndices.pop_front();
58
59 return Entity(idx, this->_generations[idx]);
60 }
61
62 if (this->_generations.size() >= Entity::MAX_INDEX)
63 return std::unexpected{Error::failure(ErrorCode::RegistryFull,
64 "Registry: Max entities reached, cannot spawn new entity.")};
65
66 std::size_t idx = this->_generations.size();
67
68 this->_generations.push_back(0);
69
70 return Entity(idx, 0);
71 }
72
74 {
75 std::unique_lock lock(this->_mutex);
76
77 std::uint32_t idx = entity.index();
78
79 if (idx >= this->_generations.size() ||
80 this->_generations[idx] != entity.generation())
81 return;
82
83 for (auto &pair : this->_arrays)
84 pair.second->erase(entity);
85
86 this->_generations[idx]++;
87 this->_freeIndices.push_back(idx);
88 }
89
90 bool Registry::isAlive(Entity entity) const noexcept
91 {
92 std::shared_lock lock(this->_mutex);
93
94 std::uint32_t idx = entity.index();
95
96 if (idx >= this->_generations.size())
97 return false;
98
99 return this->_generations[idx] == entity.generation();
100 }
101
102 void Registry::clear(void) noexcept
103 {
104 std::unique_lock lock(this->_mutex);
105
106 for (auto &pair : this->_arrays)
107 pair.second->clear();
108
109 this->_generations.clear();
110 this->_freeIndices.clear();
111 }
112
113 void Registry::purge(void) noexcept
114 {
115 std::unique_lock lock(this->_mutex);
116
117 for (auto &pair : this->_arrays)
118 pair.second->clear();
119
120 this->_freeIndices.clear();
121
122 auto idxs = std::views::iota(0uz, this->_generations.size())
123 | std::views::filter([this](std::size_t i) { return this->_generations[i] != 0; });
124 std::ranges::copy(idxs, std::back_inserter(this->_freeIndices));
125 }
126
127 std::size_t Registry::entityCount(void) const noexcept
128 {
129 std::shared_lock lock(this->_mutex);
130 return this->_generations.size() - this->_freeIndices.size();
131 }
132}
Assertion and verification macros for runtime checks.
static auto failure(ErrorCode code, std::format_string< Args... > fmt, Args &&...args) -> Error
Create a failure-level error.
Represents an entity in the ECS (Entity-Component-System) architecture.
Definition Entity.hpp:63
constexpr std::uint32_t index(void) const
constexpr std::uint32_t generation(void) const
static constexpr std::uint32_t MAX_INDEX
Definition Entity.hpp:65
auto spawn(void) -> std::expected< Entity, rtp::Error >
Definition Registry.cpp:51
std::size_t entityCount(void) const noexcept
Definition Registry.cpp:127
std::deque< std::size_t > _freeIndices
Recyclable entity indices.
Definition Registry.hpp:105
void kill(Entity entity)
Definition Registry.cpp:73
std::unordered_map< std::type_index, std::unique_ptr< ISparseArray > > _arrays
Registered component arrays.
Definition Registry.hpp:103
std::vector< std::uint32_t > _generations
Generation counters for entities.
Definition Registry.hpp:104
void clear(void) noexcept
Definition Registry.cpp:102
std::shared_mutex _mutex
Mutex for thread-safe operations.
Definition Registry.hpp:106
bool isAlive(Entity entity) const noexcept
Definition Registry.cpp:90
void purge(void) noexcept
Definition Registry.cpp:113
File : RenderSystem.hpp License: MIT Author : Elias Josué HAJJAR LLAUQUEN elias-josue....
@ RegistryFull
Entity registry has reached maximum capacity.