neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_ecs.hpp
Go to the documentation of this file.
1// i_ecs.hpp
2/*
3 * Copyright (c) 2018, 2020 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <unordered_map>
42#include <neolib/task/event.hpp>
48
49namespace neolib::ecs
50{
51 using neolib::to_const;
52
53 enum class ecs_flags : uint32_t
54 {
55 None = 0x0000,
56 PopulateEntityInfo = 0x0001,
57 Turbo = 0x0002,
58 CreatePaused = 0x0004,
59 NoThreads = 0x0008,
60
62 };
63
64 inline constexpr ecs_flags operator|(ecs_flags aLhs, ecs_flags aRhs)
65 {
66 return static_cast<ecs_flags>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
67 }
68
69 inline constexpr ecs_flags operator&(ecs_flags aLhs, ecs_flags aRhs)
70 {
71 return static_cast<ecs_flags>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
72 }
73
74 inline constexpr ecs_flags& operator|=(ecs_flags& aLhs, ecs_flags aRhs)
75 {
76 return aLhs = static_cast<ecs_flags>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
77 }
78
79 inline constexpr ecs_flags& operator&=(ecs_flags& aLhs, ecs_flags aRhs)
80 {
81 return aLhs = static_cast<ecs_flags>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
82 }
83
84 class i_ecs : public i_object
85 {
86 public:
87 declare_event(systems_paused)
88 declare_event(systems_resumed)
89 declare_event(entity_created, entity_id)
90 declare_event(entity_destroyed, entity_id)
91 declare_event(handle_updated, handle_id)
92 public:
93 struct entity_archetype_not_found : std::logic_error { entity_archetype_not_found() : std::logic_error("i_ecs::entity_archetype_not_found") {} };
94 struct component_not_found : std::logic_error { component_not_found() : std::logic_error("i_ecs::component_not_found") {} };
95 struct system_not_found : std::logic_error { system_not_found() : std::logic_error("i_ecs::system_not_found") {} };
96 struct uuid_exists : std::runtime_error { uuid_exists(const std::string& aContext) : std::runtime_error("i_ecs::uuid_exists: " + aContext) {} };
97 struct entity_ids_exhausted : std::runtime_error { entity_ids_exhausted() : std::runtime_error("i_ecs::entity_ids_exhausted") {} };
98 struct handle_ids_exhausted : std::runtime_error { handle_ids_exhausted() : std::runtime_error("i_ecs::handle_ids_exhausted") {} };
99 struct invalid_handle_id : std::logic_error { invalid_handle_id() : std::logic_error("i_ecs::invalid_handle_id") {} };
100 public:
101 typedef std::function<std::unique_ptr<i_component>()> component_factory;
102 typedef std::function<std::unique_ptr<i_shared_component>()> shared_component_factory;
103 typedef std::function<std::unique_ptr<i_system>()> system_factory;
104 protected:
105 typedef std::unordered_map<entity_archetype_id, std::shared_ptr<const i_entity_archetype>, quick_uuid_hash> archetype_registry_t;
106 typedef std::unordered_map<component_id, component_factory, quick_uuid_hash> component_factories_t;
107 typedef std::unordered_map<component_id, std::unique_ptr<i_component>, quick_uuid_hash> components_t;
108 typedef std::unordered_map<component_id, shared_component_factory, quick_uuid_hash> shared_component_factories_t;
109 typedef std::unordered_map<component_id, std::unique_ptr<i_shared_component>, quick_uuid_hash> shared_components_t;
110 typedef std::unordered_map<system_id, system_factory, quick_uuid_hash> system_factories_t;
111 typedef std::unordered_map<system_id, std::unique_ptr<i_system>, quick_uuid_hash> systems_t;
112 public:
113 typedef void* handle_t;
114 public:
115 virtual neolib::i_lockable& mutex() const = 0;
116 virtual neolib::thread_pool& thread_pool() const = 0; // todo: polymorphic threadpool
117 public:
118 virtual ecs_flags flags() const = 0;
119 virtual entity_id create_entity(const entity_archetype_id& aArchetypeId) = 0;
120 virtual void async_create_entity(const std::function<void()>& aCreator) = 0; // todo: polymorphic functor
122 virtual void destroy_entity(entity_id aEntityId, bool aNotify = true) = 0;
123 virtual void async_destroy_entity(entity_id aEntityId, bool aNotify = true) = 0;
125 public:
126 virtual bool run_threaded(const system_id& aSystemId) const = 0;
127 virtual bool all_systems_paused() const = 0;
128 virtual void pause_all_systems() = 0;
129 virtual void resume_all_systems() = 0;
130 public:
131 virtual const archetype_registry_t& archetypes() const = 0;
133 virtual const component_factories_t& component_factories() const = 0;
135 virtual const components_t& components() const = 0;
136 virtual components_t& components() = 0;
139 virtual const shared_components_t& shared_components() const = 0;
141 virtual const system_factories_t& system_factories() const = 0;
143 virtual const systems_t& systems() const = 0;
144 virtual systems_t& systems() = 0;
145 public:
146 virtual const i_entity_archetype& archetype(entity_archetype_id aArchetypeId) const = 0;
148 virtual bool component_instantiated(component_id aComponentId) const = 0;
149 virtual const i_component& component(component_id aComponentId) const = 0;
150 virtual i_component& component(component_id aComponentId) = 0;
151 virtual bool shared_component_instantiated(component_id aComponentId) const = 0;
152 virtual const i_shared_component& shared_component(component_id aComponentId) const = 0;
154 virtual bool system_instantiated(system_id aSystemId) const = 0;
155 virtual const i_system& system(system_id aSystemId) const = 0;
156 virtual i_system& system(system_id aSystemId) = 0;
157 public:
159 virtual void free_entity_id(entity_id aId) = 0;
160 public:
161 virtual bool archetype_registered(const i_entity_archetype& aArchetype) const = 0;
162 virtual void register_archetype(const i_entity_archetype& aArchetype) = 0;
163 virtual void register_archetype(std::shared_ptr<const i_entity_archetype> aArchetype) = 0;
164 virtual bool component_registered(component_id aComponentId) const = 0;
165 virtual void register_component(component_id aComponentId, component_factory aFactory) = 0;
166 virtual bool shared_component_registered(component_id aComponentId) const = 0;
167 virtual void register_shared_component(component_id aComponentId, shared_component_factory aFactory) = 0;
168 virtual bool system_registered(system_id aSystemId) const = 0;
169 virtual void register_system(system_id aSystemId, system_factory aFactory) = 0;
170 public:
171 virtual handle_t to_handle(handle_id aId) const = 0;
172 virtual handle_id add_handle(const std::type_info& aTypeInfo, handle_t aHandle) = 0;
173 virtual handle_t update_handle(handle_id aId, const std::type_info& aTypeInfo, handle_t aHandle) = 0;
175 // helpers
176 public:
177 template <typename... ComponentData>
178 entity_id create_entity(const entity_archetype_id& aArchetypeId, ComponentData&&... aComponentData);
179 template <typename Archetype, typename... ComponentData>
180 entity_id create_entity(const Archetype& aArchetype, ComponentData&&... aComponentData);
181 template <typename... ComponentData>
182 void async_create_entity(entity_archetype_id aArchetypeId, ComponentData... aComponentData);
183 template <typename Archetype, typename... ComponentData>
184 void async_create_entity(const Archetype& aArchetype, ComponentData... aComponentData);
185 public:
186 template <typename ComponentData, typename... ComponentDataRest>
187 void populate(entity_id aEntity, ComponentData&& aComponentData, ComponentDataRest&&... aComponentDataRest)
188 {
189 populate(aEntity, std::forward<ComponentData>(aComponentData));
190 populate(aEntity, std::forward<ComponentDataRest>(aComponentDataRest)...);
191 }
192 template <typename ComponentData>
193 void populate(entity_id aEntity, ComponentData&& aComponentData)
194 {
195 component<ecs_data_type_t<ComponentData>>().populate(aEntity, std::forward<ComponentData>(aComponentData));
196 }
197 template <typename ComponentData, typename... ComponentDataRest>
198 void populate_shared(const std::string& aName, ComponentData&& aComponentData, ComponentDataRest&&... aComponentDataRest)
199 {
200 populate_shared(aName, std::forward<ComponentData>(aComponentData));
201 populate_shared(aName, std::forward<ComponentDataRest>(aComponentDataRest)...);
202 }
203 template <typename ComponentData>
204 void populate_shared(const std::string& aName, ComponentData&& aComponentData)
205 {
206 shared_component<ecs_data_type_t<ComponentData>>().populate(aName, std::forward<ComponentData>(aComponentData));
207 }
208 template <typename ComponentData>
213 template <typename ComponentData>
218 template <typename ComponentData>
220 {
222 register_component<ecs_data_type_t<ComponentData>>();
224 }
225 template <typename ComponentData>
230 template <typename ComponentData>
235 template <typename ComponentData>
237 {
239 register_shared_component<ecs_data_type_t<ComponentData>>();
241 }
242 template <typename System>
247 template <typename System>
249 {
251 }
252 template <typename System>
254 {
256 register_system<ecs_data_type_t<System>>();
257 return const_cast<ecs_data_type_t<System>&>(to_const(*this).system<ecs_data_type_t<System>>());
258 }
259 public:
260 template <typename ComponentData>
265 template <typename ComponentData>
267 {
268 register_component(ecs_data_type_t<ComponentData>::meta::id(), [&]() { return std::unique_ptr<i_component>{std::make_unique<neolib::ecs::component<ecs_data_type_t<ComponentData>>>(*this)}; });
269 }
270 template <typename ComponentData>
275 template <typename ComponentData>
277 {
278 register_shared_component(ecs_data_type_t<ComponentData>::meta::id(), [&]() { return std::unique_ptr<i_shared_component>{std::make_unique<neolib::ecs::shared_component<ecs_data_type_t<ComponentData>>>(*this)}; });
279 }
280 template <typename System>
285 template <typename System>
287 {
290 [&]() { return std::unique_ptr<i_system>{std::make_unique<ecs_data_type_t<System>>(*this)}; });
291 }
292 public:
293 template <typename Handle>
294 Handle to_handle(handle_id aId) const
295 {
296 return reinterpret_cast<Handle>(to_handle(aId));
297 }
298 template <typename Context, typename Handle>
299 handle_id add_handle(Handle aHandle)
300 {
301 return add_handle(typeid(Context), reinterpret_cast<handle_t>(aHandle));
302 }
303 template <typename Context, typename Handle>
304 Handle update_handle(handle_id aId, Handle aHandle)
305 {
306 if constexpr(std::is_pointer<Handle>::value)
307 return reinterpret_cast<Handle>(update_handle(aId, typeid(Context), reinterpret_cast<handle_t>(aHandle)));
308 else
309 return static_cast<Handle>(reinterpret_cast<intptr_t>(update_handle(aId, typeid(Context), reinterpret_cast<handle_t>(aHandle))));
310 }
311 template <typename Handle>
313 {
314 if constexpr(std::is_pointer<Handle>::value)
315 return reinterpret_cast<Handle>(release_handle(aId));
316 else
317 return static_cast<Handle>(reinterpret_cast<intptr_t>(release_handle(aId)));
318 }
319 };
320
321 template <typename Data>
323 {
324 public:
326 iLock{ aEcs.shared_component<Data>().mutex() }
327 {
328 }
332 private:
333 std::scoped_lock<neolib::i_lockable> iLock;
334 };
335
336 const struct dont_lock_t {} dont_lock;
337
338 template <typename... Data>
340 {
341 private:
342 template <typename T, typename>
343 static T fwd(T o) { return o; }
344 template <typename Data2>
345 class proxy_mutex : public i_lockable
346 {
347 public:
348 struct not_linked : std::logic_error { not_linked() : std::logic_error{"neolib::neolib::ecs::scoped_component_lock::proxy_mutex::not_linked"} {} };
349 public:
350 proxy_mutex(const i_ecs& aEcs) :
351 iSubject{ &aEcs.component<Data2>().mutex() }
352 {
353 }
354 proxy_mutex(i_ecs& aEcs) :
355 iSubject{ &aEcs.component<Data2>().mutex() }
356 {
357 }
358 public:
359 void lock() noexcept override
360 {
361 if (linked())
362 subject().lock();
363 }
364 void unlock() noexcept override
365 {
366 if (linked())
367 subject().unlock();
368 }
369 bool try_lock() noexcept override
370 {
371 if (linked())
372 return subject().try_lock();
373 else
374 return false;
375 }
376 public:
377 i_lockable& subject()
378 {
379 if (linked())
380 return *iSubject;
381 throw not_linked();
382 }
383 public:
384 bool linked() const
385 {
386 return iSubject != nullptr;
387 }
388 i_lockable& unlink()
389 {
390 if (linked())
391 {
392 auto& link = *iSubject;
393 iSubject = nullptr;
394 return link;
395 }
396 throw not_linked();
397 }
398 private:
399 i_lockable* iSubject;
400 };
401 public:
403 iProxies{ fwd<const i_ecs&, Data>(aEcs)... }
404 {
405 lock();
406 }
408 iProxies{ fwd<i_ecs&, Data>(aEcs)... }
409 {
410 lock();
411 }
413 iProxies{ fwd<const i_ecs&, Data>(aEcs)... }
414 {
415 iDontUnlock.emplace();
416 }
418 iProxies{ fwd<i_ecs&, Data>(aEcs)... }
419 {
420 iDontUnlock.emplace();
421 }
423 {
424 if (!iDontUnlock)
425 unlock();
426 }
427 public:
428 void lock()
429 {
430 if constexpr (sizeof...(Data) >= 2)
431 std::lock(std::get<index_of_v<Data, Data...>>(iProxies)...);
432 else if constexpr (sizeof...(Data) == 1)
433 std::get<0>(iProxies).lock();
434 }
435 void unlock()
436 {
437 (std::get<index_of_v<Data, Data...>>(iProxies).unlock(), ...);
438 }
439 bool try_lock()
440 {
441 if constexpr (sizeof...(Data) >= 2)
442 return std::try_lock(std::get<index_of_v<Data, Data...>>(iProxies)...) == -1;
443 else if constexpr (sizeof...(Data) == 1)
444 return std::get<0>(iProxies).try_lock();
445 }
446 public:
447 template <typename Data2>
449 {
450 return std::get<index_of_v<Data2, Data...>>(iProxies).unlink();
451 }
452 template <typename Data2>
453 bool controlling() const
454 {
455 return std::get<index_of_v<Data2, Data...>>(iProxies).linked();
456 }
457 template <typename... Data2>
458 void lock_if()
459 {
460 (lock_if_impl<Data2>(), ...);
461 }
462 template <typename... Data2>
464 {
465 (unlock_if_impl<Data2>(), ...);
466 }
467 private:
468 template <typename Data2>
469 void lock_if_impl()
470 {
471 if (controlling<Data2>())
472 mutex<Data2>().lock();
473 }
474 template <typename Data2>
475 void unlock_if_impl()
476 {
477 if (controlling<Data2>())
478 mutex<Data2>().unlock();
479 }
480 private:
481 std::tuple<proxy_mutex<Data>...> iProxies;
482 std::optional<dont_lock_t> iDontUnlock;
483 };
484
485 template <typename... ComponentData>
486 inline entity_id i_ecs::create_entity(const entity_archetype_id& aArchetypeId, ComponentData&&... aComponentData)
487 {
489 auto newEntity = create_entity(aArchetypeId);
490 populate(newEntity, std::forward<ComponentData>(aComponentData)...);
491 archetype(aArchetypeId).populate_default_components(*this, newEntity);
492 return newEntity;
493 }
494
495 template <typename Archetype, typename... ComponentData>
496 inline entity_id i_ecs::create_entity(const Archetype& aArchetype, ComponentData&&... aComponentData)
497 {
498 if (!archetype_registered(aArchetype))
499 register_archetype(aArchetype);
500 return create_entity(aArchetype.id(), std::forward<ComponentData>(aComponentData)...);
501 }
502
503 template <typename... ComponentData>
504 inline void i_ecs::async_create_entity(entity_archetype_id aArchetypeId, ComponentData... aComponentData)
505 {
506 auto creator = [=, this]()
507 {
508 create_entity(aArchetypeId, aComponentData...);
509 };
510 async_create_entity(std::function<void()>{ creator });
511 }
512
513 template <typename Archetype, typename... ComponentData>
514 inline void i_ecs::async_create_entity(const Archetype& aArchetype, ComponentData... aComponentData)
515 {
516 auto creator = [=, this, &aArchetype]()
517 {
518 if (!archetype_registered(aArchetype))
519 register_archetype(aArchetype);
520 create_entity(aArchetype, aComponentData...);
521 };
522 async_create_entity(std::function<void()>{ creator });
523 }
524}
std::function< std::unique_ptr< i_component >()> component_factory
Definition i_ecs.hpp:101
virtual const system_factories_t & system_factories() const =0
const ecs_data_type_t< System > & system() const
Definition i_ecs.hpp:248
Handle update_handle(handle_id aId, Handle aHandle)
Definition i_ecs.hpp:304
virtual bool run_threaded(const system_id &aSystemId) const =0
virtual ecs_flags flags() const =0
virtual const components_t & components() const =0
virtual i_component & component(component_id aComponentId)=0
void register_system()
Definition i_ecs.hpp:286
virtual const i_component & component(component_id aComponentId) const =0
virtual const component_factories_t & component_factories() const =0
void register_shared_component()
Definition i_ecs.hpp:276
virtual const shared_component_factories_t & shared_component_factories() const =0
virtual shared_component_factories_t & shared_component_factories()=0
virtual bool shared_component_instantiated(component_id aComponentId) const =0
bool component_instantiated() const
Definition i_ecs.hpp:209
virtual const i_shared_component & shared_component(component_id aComponentId) const =0
virtual systems_t & systems()=0
Handle to_handle(handle_id aId) const
Definition i_ecs.hpp:294
virtual void commit_async_entity_creation()=0
void register_component()
Definition i_ecs.hpp:266
std::unordered_map< component_id, std::unique_ptr< i_component >, quick_uuid_hash > components_t
Definition i_ecs.hpp:107
std::unordered_map< component_id, component_factory, quick_uuid_hash > component_factories_t
Definition i_ecs.hpp:106
virtual void async_create_entity(const std::function< void()> &aCreator)=0
virtual components_t & components()=0
virtual void register_shared_component(component_id aComponentId, shared_component_factory aFactory)=0
const neolib::ecs::shared_component< ComponentData > & shared_component() const
Definition i_ecs.hpp:231
neolib::ecs::shared_component< ComponentData > & shared_component()
Definition i_ecs.hpp:236
virtual bool system_instantiated(system_id aSystemId) const =0
std::function< std::unique_ptr< i_shared_component >()> shared_component_factory
Definition i_ecs.hpp:102
virtual component_factories_t & component_factories()=0
Handle release_handle(handle_id aId)
Definition i_ecs.hpp:312
virtual void async_destroy_entity(entity_id aEntityId, bool aNotify=true)=0
std::function< std::unique_ptr< i_system >()> system_factory
Definition i_ecs.hpp:103
virtual handle_t update_handle(handle_id aId, const std::type_info &aTypeInfo, handle_t aHandle)=0
virtual i_system & system(system_id aSystemId)=0
handle_id add_handle(Handle aHandle)
Definition i_ecs.hpp:299
std::unordered_map< component_id, shared_component_factory, quick_uuid_hash > shared_component_factories_t
Definition i_ecs.hpp:108
bool component_registered() const
Definition i_ecs.hpp:261
virtual neolib::i_lockable & mutex() const =0
virtual void register_archetype(const i_entity_archetype &aArchetype)=0
virtual entity_id create_entity(const entity_archetype_id &aArchetypeId)=0
virtual shared_components_t & shared_components()=0
virtual const systems_t & systems() const =0
virtual void resume_all_systems()=0
virtual handle_t to_handle(handle_id aId) const =0
virtual bool shared_component_registered(component_id aComponentId) const =0
virtual bool component_registered(component_id aComponentId) const =0
virtual const i_system & system(system_id aSystemId) const =0
virtual neolib::thread_pool & thread_pool() const =0
virtual void pause_all_systems()=0
virtual void commit_async_entity_destruction()=0
declare_event(systems_paused) declare_event(systems_resumed) declare_event(entity_created
virtual void free_entity_id(entity_id aId)=0
virtual bool all_systems_paused() const =0
virtual const shared_components_t & shared_components() const =0
virtual void register_system(system_id aSystemId, system_factory aFactory)=0
virtual void destroy_entity(entity_id aEntityId, bool aNotify=true)=0
virtual archetype_registry_t & archetypes()=0
virtual const i_entity_archetype & archetype(entity_archetype_id aArchetypeId) const =0
std::unordered_map< component_id, std::unique_ptr< i_shared_component >, quick_uuid_hash > shared_components_t
Definition i_ecs.hpp:109
bool shared_component_instantiated() const
Definition i_ecs.hpp:226
std::unordered_map< system_id, system_factory, quick_uuid_hash > system_factories_t
Definition i_ecs.hpp:110
virtual handle_t release_handle(handle_id aId)=0
void populate_shared(const std::string &aName, ComponentData &&aComponentData)
Definition i_ecs.hpp:204
bool shared_component_registered() const
Definition i_ecs.hpp:271
neolib::ecs::component< ComponentData > & component()
Definition i_ecs.hpp:219
ecs_data_type_t< System > & system()
Definition i_ecs.hpp:253
virtual i_shared_component & shared_component(component_id aComponentId)=0
virtual bool archetype_registered(const i_entity_archetype &aArchetype) const =0
void populate(entity_id aEntity, ComponentData &&aComponentData, ComponentDataRest &&... aComponentDataRest)
Definition i_ecs.hpp:187
virtual const archetype_registry_t & archetypes() const =0
virtual bool component_instantiated(component_id aComponentId) const =0
std::unordered_map< system_id, std::unique_ptr< i_system >, quick_uuid_hash > systems_t
Definition i_ecs.hpp:111
void populate(entity_id aEntity, ComponentData &&aComponentData)
Definition i_ecs.hpp:193
bool system_instantiated() const
Definition i_ecs.hpp:243
virtual i_entity_archetype & archetype(entity_archetype_id aArchetypeId)=0
std::unordered_map< entity_archetype_id, std::shared_ptr< const i_entity_archetype >, quick_uuid_hash > archetype_registry_t
Definition i_ecs.hpp:105
virtual bool system_registered(system_id aSystemId) const =0
virtual void register_archetype(std::shared_ptr< const i_entity_archetype > aArchetype)=0
virtual void register_component(component_id aComponentId, component_factory aFactory)=0
virtual entity_id next_entity_id()=0
virtual handle_id add_handle(const std::type_info &aTypeInfo, handle_t aHandle)=0
bool system_registered() const
Definition i_ecs.hpp:281
void populate_shared(const std::string &aName, ComponentData &&aComponentData, ComponentDataRest &&... aComponentDataRest)
Definition i_ecs.hpp:198
virtual system_factories_t & system_factories()=0
const neolib::ecs::component< ComponentData > & component() const
Definition i_ecs.hpp:214
virtual void populate_default_components(i_ecs &aEcs, entity_id aEntity)=0
scoped_component_lock(i_ecs &aEcs, dont_lock_t)
Definition i_ecs.hpp:417
scoped_component_lock(const i_ecs &aEcs, dont_lock_t)
Definition i_ecs.hpp:412
scoped_component_lock(const i_ecs &aEcs)
Definition i_ecs.hpp:402
shared_component_scoped_lock(const i_ecs &aEcs)
Definition i_ecs.hpp:325
constexpr component_data_field_type & operator&=(component_data_field_type &aLhs, component_data_field_type aRhs)
const struct neolib::ecs::dont_lock_t dont_lock
id_t handle_id
Definition ecs_ids.hpp:50
constexpr component_data_field_type operator&(component_data_field_type aLhs, component_data_field_type aRhs)
id_t entity_id
Definition ecs_ids.hpp:51
constexpr component_data_field_type & operator|=(component_data_field_type &aLhs, component_data_field_type aRhs)
constexpr component_data_field_type operator|(component_data_field_type aLhs, component_data_field_type aRhs)
std::remove_cv_t< std::remove_reference_t< _Ty > > ecs_data_type_t
constexpr std::size_t index_of_v
Definition neolib.hpp:128
to_const_reference_t< T > to_const(T &&object)
Definition neolib.hpp:113
Definition plf_hive.h:79
constexpr T & get(neolib::variant< Types... > &var)
Definition variant.hpp:84
#define declare_event(declName,...)
Definition i_event.hpp:305
uuid_exists(const std::string &aContext)
Definition i_ecs.hpp:96
virtual void lock() noexcept=0