#include #define MAX_ENTITIES 1000 #define MAX_COMPONENTS 16 class NewWorld: public Spatial { GDCLASS(NewWorld, Spatial) class EntityManager { List available_entities; int entity_count; uint32_t signatures[MAX_ENTITIES]; public: EntityManager() { int e; for (e = 0; e < MAX_ENTITIES; e++) { available_entities.push_back(e); signatures[e] = 0U; } entity_count = 0; } int create_entity() { int ret; if (entity_count >= MAX_ENTITIES || available_entities.size() == 0) return -1; ret = available_entities.front()->get(); available_entities.pop_front(); entity_count++; return ret; } void destroy_entity(int e) { if (e >= MAX_ENTITIES) return; entity_count--; available_entities.push_back(e); signatures[e] = 0U; } inline void set_signature(int e, uint32_t sig) { signatures[e] = sig; } inline uint32_t get_signature(int e) { return signatures[e]; } }; class IComponentArray { public: virtual ~IComponentArray() = default; virtual void destroyed(int entity) = 0; }; template class ComponentArray: public IComponentArray { Vector component_array; HashMap entity_to_index; HashMap index_to_entity; size_t size; public: void insert_data(int entity, T component) { if (entity_to_index.has(entity)) return; size_t new_index = size; entity_to_index[entity] = new_index; index_to_entity[new_index] = entity; component_array[new_index] = component; size++; } void remove_data(int entity) { if (!entity_to_index.has(entity)) return; size_t removed_index = entity_to_index[entity]; size_t last_index = size - 1; component_array[removed_index] = component_array[last_index]; int last_entity = index_to_entity[last_index]; entity_to_index[last_entity] = removed_index; index_to_entity[removed_index] = last_entity; entity_to_index.erase(entity); index_to_entity.erase(last_index); size--; } T *get(int entity) { if (!entity_to_index.has(entity)) { return NULL; } return &component_array[entity_to_index[entity]]; } void destroyed(int entity) override { remove_data(entity); } }; #define __REFLECT_NAME(N) #N class ComponentManager { HashMap component_types{}; HashMap component_arrays{}; int next_component_type{}; template ComponentArray *get_component_array() { const char* type_name = __REFLECT_NAME(T); if (!component_types.has(type_name)) return NULL; return static_cast >(component_arrays[type_name]); } public: template void register_component() { const char* type_name = __REFLECT_NAME(T); component_types[type_name] = next_component_type; component_arrays[type_name] = memnew(ComponentArray()); next_component_type++; } template int get_component_type() { const char* type_name = __REFLECT_NAME(T); return component_types[type_name] * component_types.has(type_name) - 1 * (!component_types.has(type_name)); } template void add_component(int entity, T component) { get_component_array()->insert_data(entity, component); } template void remove_component(int entity) { get_component_array()->remove(entity); } template T &get_component(int entity) { get_component_array()->get_data(entity); } void destroyed(int entity) { const char * const *e = component_arrays.next(NULL); while (e) { component_arrays[*e]->destroyed(entity); e = component_arrays.next(e); } } }; class System { public: Vector entities; }; class SystemManager { HashMap systems; HashMap signatures; public: template T *register_system() { const char* type_name = __REFLECT_NAME(T); T * system = memnew(T); systems[type_name] = system; return system; } template void set_signature(uint32_t signature) { const char* type_name = __REFLECT_NAME(T); signatures[type_name] = signature; } void destroyed(int entity) { const char * const * e = systems.next(NULL); while (e) { systems[*e]->entities.erase(entity); e = systems.next(e); } } void signature_changed(int entity, uint32_t signature) { const char * const * e = systems.next(NULL); while (e) { if ((signature & signatures[*e]) == signatures[*e]) systems[*e]->entities.push_back(entity); else systems[*e]->entities.erase(entity); e = systems.next(e); } } }; ComponentManager cman; EntityManager eman; SystemManager sman; };