|
|
@ -9,6 +9,7 @@ |
|
|
|
#include <typeinfo> |
|
|
|
#include <typeinfo> |
|
|
|
#include <unordered_map> |
|
|
|
#include <unordered_map> |
|
|
|
#include <optional> |
|
|
|
#include <optional> |
|
|
|
|
|
|
|
#include <memory> |
|
|
|
|
|
|
|
|
|
|
|
namespace DinkyECS |
|
|
|
namespace DinkyECS |
|
|
|
{ |
|
|
|
{ |
|
|
@ -16,8 +17,6 @@ namespace DinkyECS |
|
|
|
|
|
|
|
|
|
|
|
const Entity NONE = 0; |
|
|
|
const Entity NONE = 0; |
|
|
|
|
|
|
|
|
|
|
|
using EntityMap = std::unordered_map<Entity, size_t>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
template <typename T> |
|
|
|
struct ComponentStorage { |
|
|
|
struct ComponentStorage { |
|
|
|
std::vector<T> data; |
|
|
|
std::vector<T> data; |
|
|
@ -29,17 +28,22 @@ namespace DinkyECS |
|
|
|
std::any data; |
|
|
|
std::any data; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
typedef std::queue<Event> EventQueue; |
|
|
|
using EntityMap = std::unordered_map<Entity, size_t>; |
|
|
|
|
|
|
|
using EventQueue = std::queue<Event>; |
|
|
|
|
|
|
|
using TypeMap = std::unordered_map<std::type_index, std::any>; |
|
|
|
|
|
|
|
|
|
|
|
struct World { |
|
|
|
struct World { |
|
|
|
unsigned long entity_count = NONE+1; |
|
|
|
unsigned long entity_count = NONE+1; |
|
|
|
std::unordered_map<std::type_index, EntityMap> $components; |
|
|
|
std::unordered_map<std::type_index, EntityMap> $components; |
|
|
|
std::unordered_map<std::type_index, std::any> $facts; |
|
|
|
std::shared_ptr<TypeMap> $facts = nullptr; |
|
|
|
std::unordered_map<std::type_index, EventQueue> $events; |
|
|
|
std::unordered_map<std::type_index, EventQueue> $events; |
|
|
|
std::unordered_map<std::type_index, std::any> $component_storages; |
|
|
|
std::unordered_map<std::type_index, std::any> $component_storages; |
|
|
|
std::unordered_map<std::type_index, std::queue<size_t>> $free_indices; |
|
|
|
std::unordered_map<std::type_index, std::queue<size_t>> $free_indices; |
|
|
|
std::unordered_map<Entity, bool> $constants; |
|
|
|
std::unordered_map<Entity, bool> $constants; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
World() : $facts(std::make_shared<TypeMap>()) |
|
|
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
|
|
|
Entity entity() { return ++entity_count; } |
|
|
|
Entity entity() { return ++entity_count; } |
|
|
|
|
|
|
|
|
|
|
|
void destroy(DinkyECS::Entity entity) { |
|
|
|
void destroy(DinkyECS::Entity entity) { |
|
|
@ -135,26 +139,26 @@ namespace DinkyECS |
|
|
|
|
|
|
|
|
|
|
|
template <typename Comp> |
|
|
|
template <typename Comp> |
|
|
|
void set_the(Comp val) { |
|
|
|
void set_the(Comp val) { |
|
|
|
$facts.insert_or_assign(std::type_index(typeid(Comp)), val); |
|
|
|
$facts->insert_or_assign(std::type_index(typeid(Comp)), val); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename Comp> |
|
|
|
template <typename Comp> |
|
|
|
Comp &get_the() { |
|
|
|
Comp &get_the() { |
|
|
|
auto comp_id = std::type_index(typeid(Comp)); |
|
|
|
auto comp_id = std::type_index(typeid(Comp)); |
|
|
|
dbc::check($facts.contains(comp_id), |
|
|
|
dbc::check($facts->contains(comp_id), |
|
|
|
fmt::format("!!!! ATTEMPT to access world fact that hasn't " |
|
|
|
fmt::format("!!!! ATTEMPT to access world fact that hasn't " |
|
|
|
"been set yet: {}", |
|
|
|
"been set yet: {}", |
|
|
|
typeid(Comp).name())); |
|
|
|
typeid(Comp).name())); |
|
|
|
|
|
|
|
|
|
|
|
// use .at to get std::out_of_range if fact not set
|
|
|
|
// use .at to get std::out_of_range if fact not set
|
|
|
|
std::any &res = $facts.at(comp_id); |
|
|
|
std::any &res = $facts->at(comp_id); |
|
|
|
return std::any_cast<Comp &>(res); |
|
|
|
return std::any_cast<Comp &>(res); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename Comp> |
|
|
|
template <typename Comp> |
|
|
|
bool has_the() { |
|
|
|
bool has_the() { |
|
|
|
auto comp_id = std::type_index(typeid(Comp)); |
|
|
|
auto comp_id = std::type_index(typeid(Comp)); |
|
|
|
return $facts.contains(comp_id); |
|
|
|
return $facts->contains(comp_id); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename Comp> |
|
|
|
template <typename Comp> |
|
|
|