CoriEngine
Loading...
Searching...
No Matches
DisposableEntityPool.hpp
Go to the documentation of this file.
1#pragma once
2#include "Entity.hpp"
3#include "SceneHandle.hpp"
4#include "Core/Error.hpp"
5
6namespace Cori {
7 namespace World {
19 template <uint16_t PoolSize>
21 public:
23 m_Mask.set();
24 m_FreeIndexes.reserve(PoolSize);
25 }
26
33 void Init(SceneHandle scene, std::function<Entity(SceneHandle&)>&& compositor, std::function<void(Entity&)>&& resetter) {
34 for (uint16_t i = 0; i < PoolSize; ++i) {
35 Entity entity = compositor(scene);
36 entity.SetActive(false);
37 m_Pool[i] = entity;
38 m_FreeIndexes.push_back(i);
39 }
40
41 m_Resetter = resetter;
42 m_Initialized = true;
43 }
44
49 std::expected<std::pair<Entity, uint16_t>, Core::PossibleErrors<Core::CoriError<uint16_t>, Core::CoriError<>>> GetFreeEntity() {
50 if (m_Initialized) {
51 if (m_Mask.count() > 0) {
52 uint16_t freeIndex = m_FreeIndexes.back();
53 m_FreeIndexes.pop_back();
54 m_Mask[freeIndex] = false;
55 Entity entity = m_Pool[freeIndex];
56 entity.SetActive(true);
57 return std::make_pair(entity, freeIndex);
58 }
59
60 return std::unexpected(Core::CoriError<uint16_t>("Ran out of free indexes, all entities are currently busy.", "Pool Capacity", PoolSize));
61 }
62
63 return std::unexpected(Core::CoriError("Disposable entity pool is not initialized, call Init first!"));
64 }
65
66
72 std::expected<Entity, Core::PossibleErrors<Core::CoriError<uint16_t>, Core::CoriError<>>> GetEntityAtIndex(const uint16_t index) {
73 if (m_Initialized) {
74 if (index < m_FreeIndexes.size()) {
75 return m_Pool[index];
76 }
77
78 return std::unexpected(Core::CoriError<uint16_t>(std::format("Index '{}' out of bounds.", index), "Pool Capacity", PoolSize));
79 }
80
81 return std::unexpected(Core::CoriError("Disposable entity pool is not initialized, call Init first!"));
82 }
83
88 void FreeIndex(const uint16_t slot) {
89 if (!m_Mask[slot] && m_Initialized) {
90 m_FreeIndexes.push_back(slot);
91 m_Mask[slot] = true;
92 Entity entity = m_Pool[slot];
93 m_Resetter(entity);
94 entity.SetActive(false);
95 }
96 }
97
102 [[nodiscard]] uint16_t Capacity() const {
103 return PoolSize;
104 }
105
110 [[nodiscard]] uint16_t Size() const {
111 return m_FreeIndexes.size();
112 }
113
117 void FreeAll() {
118 for (uint16_t i = 0; i < PoolSize; ++i) {
119 FreeIndex(i);
120 }
121 }
122
123 private:
124 std::vector<uint16_t> m_FreeIndexes;
125 std::array<Entity, PoolSize> m_Pool;
126 std::function<void(Entity&)> m_Resetter;
127 std::bitset<PoolSize> m_Mask;
128 bool m_Initialized{ false };
129 };
130 }
131}
Custom error class mainly used in std::expected.
Definition Error.hpp:27
This class utilizes std::variant to hold one of the possible exception types.
Definition Error.hpp:156
void Init(SceneHandle scene, std::function< Entity(SceneHandle &)> &&compositor, std::function< void(Entity &)> &&resetter)
Initializes the pool.
void FreeAll()
Frees all indexes at once.
uint16_t Size() const
Returns the amount of free entities currently present in the pool.
std::expected< Entity, Core::PossibleErrors< Core::CoriError< uint16_t >, Core::CoriError<> > > GetEntityAtIndex(const uint16_t index)
Retries the entity at a particular index, regardless if it's free or not.
void FreeIndex(const uint16_t slot)
Frees the entity at the given index, a resetter will be run for the entity at the specified index,...
uint16_t Capacity() const
Returns the total capacity of the pool, how many entities can it fit in total.
std::expected< std::pair< Entity, uint16_t >, Core::PossibleErrors< Core::CoriError< uint16_t >, Core::CoriError<> > > GetFreeEntity()
Finds a free entity in a pool (if any) in O(1) time. After retrieving the entity will be considered b...
Entities are the essential part of WorldSystem.
Definition Entity.hpp:25
void SetActive(const bool state)
Changes the activity state of the entity.
Definition Entity.cpp:7
A handle for the scene, checks for scene validity before any call to the scene, if scene is invalid a...
Anything connected to WorldSystem (ECS) is in this namespace.
Global engine namespace.