Now calling this DinkyECS and will use it in the game to move the enemies and such.

main
Zed A. Shaw 10 months ago
parent 085777706e
commit b9c27cd6ba
  1. 92
      dinkyecs.hpp
  2. 88
      scratchpad/myecstest.cpp

@ -0,0 +1,92 @@
#pragma once
#include <functional>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <any>
namespace DinkyECS {
typedef unsigned long Entity;
typedef std::unordered_map<Entity, std::any> EntityMap;
struct World {
unsigned long entity_count = 0;
std::unordered_map<std::type_index, EntityMap> $components;
std::unordered_map<std::type_index, std::any> $facts;
Entity entity() {
return ++entity_count;
}
template <typename Comp>
EntityMap& entity_map_for() {
return $components[std::type_index(typeid(Comp))];
}
template <typename Comp>
void set(Comp val) {
$facts[std::type_index(typeid(Comp))] = val;
}
template <typename Comp>
Comp &get() {
// use .at to get std::out_of_range if fact not set
std::any &res = $facts.at(std::type_index(typeid(Comp)));
return std::any_cast<Comp&>(res);
}
template <typename Comp>
void assign(Entity ent, Comp val) {
EntityMap &map = entity_map_for<Comp>();
map[ent] = val;
}
template <typename Comp>
Comp &component(Entity ent) {
EntityMap &map = entity_map_for<Comp>();
// use .at for bounds checking
std::any &res = map.at(ent);
return std::any_cast<Comp&>(res);
}
template<typename Comp>
void system(std::function<void(const Entity&, Comp&)> cb) {
EntityMap &map = entity_map_for<Comp>();
for(auto& [entity, any_comp] : map) {
Comp &res = std::any_cast<Comp&>(any_comp);
cb(entity, res);
}
}
template<typename Comp>
void remove(Entity ent) {
EntityMap &map = entity_map_for<Comp>();
map.erase(ent);
}
template<typename CompA, typename CompB>
void system(std::function<void(const Entity&, CompA&, CompB&)> cb) {
EntityMap &map_a = entity_map_for<CompA>();
EntityMap &map_b = entity_map_for<CompB>();
for(auto& [entity, any_a] : map_a) {
if(map_b.contains(entity)) {
CompA &res_a = std::any_cast<CompA&>(any_a);
CompB &res_b = component<CompB>(entity);
cb(entity, res_a, res_b);
}
}
}
template<typename CompA, typename CompB>
std::function<void()> runner(std::function<void(const Entity&, CompA&, CompB&)> cb) {
return [&]{
system<CompA, CompB>(cb);
};
}
};
}

@ -1,92 +1,10 @@
#include "dinkyecs.hpp"
#include <iostream>
#include <functional>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <fmt/core.h>
#include <any>
using namespace fmt;
typedef unsigned long Entity;
typedef std::unordered_map<Entity, std::any> EntityMap;
struct World {
unsigned long entity_count = 0;
std::unordered_map<std::type_index, EntityMap> $components;
std::unordered_map<std::type_index, std::any> $facts;
Entity entity() {
return ++entity_count;
}
template <typename Comp>
EntityMap& entity_map_for() {
return $components[std::type_index(typeid(Comp))];
}
template <typename Comp>
void set(Comp val) {
$facts[std::type_index(typeid(Comp))] = val;
}
template <typename Comp>
Comp &get() {
// use .at to get std::out_of_range if fact not set
std::any &res = $facts.at(std::type_index(typeid(Comp)));
return std::any_cast<Comp&>(res);
}
template <typename Comp>
void assign(Entity ent, Comp val) {
EntityMap &map = entity_map_for<Comp>();
map[ent] = val;
}
template <typename Comp>
Comp &component(Entity ent) {
EntityMap &map = entity_map_for<Comp>();
// use .at for bounds checking
std::any &res = map.at(ent);
return std::any_cast<Comp&>(res);
}
template<typename Comp>
void system(std::function<void(const Entity&, Comp&)> cb) {
EntityMap &map = entity_map_for<Comp>();
for(auto& [entity, any_comp] : map) {
Comp &res = std::any_cast<Comp&>(any_comp);
cb(entity, res);
}
}
template<typename Comp>
void remove(Entity ent) {
EntityMap &map = entity_map_for<Comp>();
map.erase(ent);
}
template<typename CompA, typename CompB>
void system(std::function<void(const Entity&, CompA&, CompB&)> cb) {
EntityMap &map_a = entity_map_for<CompA>();
EntityMap &map_b = entity_map_for<CompB>();
for(auto& [entity, any_a] : map_a) {
if(map_b.contains(entity)) {
CompA &res_a = std::any_cast<CompA&>(any_a);
CompB &res_b = component<CompB>(entity);
cb(entity, res_a, res_b);
}
}
}
template<typename CompA, typename CompB>
std::function<void()> runner(std::function<void(const Entity&, CompA&, CompB&)> cb) {
return [&]{
system<CompA, CompB>(cb);
};
}
};
using DinkyECS::Entity, DinkyECS::World;
struct Position {
double x, y;

Loading…
Cancel
Save