Add first, inperformant version of ECS
The ECS can't handle many entities in this state; it is really slow. This commit also doesn't contain any tests for its functions.
This commit is contained in:
parent
0408d19a72
commit
e3e4e5ee84
|
@ -0,0 +1,24 @@
|
|||
|
||||
#ifndef VOXULA_H
|
||||
#define VOXULA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <voxula/internals/utility.h>
|
||||
|
||||
typedef void vecs_s;
|
||||
typedef struct vecs_entity vecs_entity_s;
|
||||
|
||||
struct vecs_entity
|
||||
{
|
||||
vecs_s *ecs;
|
||||
vx_uuid_d uuid;
|
||||
};
|
||||
|
||||
vecs_s * vecs_new();
|
||||
void vecs_free(vecs_s *ecs);
|
||||
|
||||
vecs_entity_s vecs_summon(vecs_s *ecs);
|
||||
void vecs_vanish(vecs_entity_s *entity);
|
||||
|
||||
#endif // VOXULA_H
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef VECS_ENTITY_H
|
||||
#define VECS_ENTITY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <voxula/internals/utility.h>
|
||||
|
||||
typedef struct vecs_entity vecs_entity_s;
|
||||
|
||||
struct vecs_entity
|
||||
{
|
||||
void *head_structure;
|
||||
vx_uuid_d uuid;
|
||||
};
|
||||
|
||||
vecs_entity_s vecs_summon(void *ecs_pointer);
|
||||
void vecs_vanish(vecs_entity_s *entity);
|
||||
|
||||
#endif // VECS_ENTITY_H
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
#ifndef VECS_H
|
||||
#define VECS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <voxula/internals/utility.h>
|
||||
#include <voxula/internals/ecs/lookup.h>
|
||||
|
||||
typedef struct vecs vecs_s;
|
||||
typedef struct vecs_shadow vecs_shadow_s;
|
||||
typedef struct vecs_tag vecs_tag_s;
|
||||
|
||||
typedef struct vecs_tag_name_resolver vecs_tag_name_resolver_s;
|
||||
typedef struct vecs_tag_name vecs_tag_name_s;
|
||||
|
||||
struct vecs_tag_name
|
||||
{
|
||||
vx_uuid_d uuid;
|
||||
uint32_t length;
|
||||
char *string;
|
||||
};
|
||||
|
||||
struct vecs_tag_name_resolver
|
||||
{
|
||||
uint32_t names_capacity;
|
||||
uint32_t num_names;
|
||||
vecs_tag_name_s *names;
|
||||
vx_uuid_table_s *uuid_table;
|
||||
vx_arena_s *string_arena;
|
||||
};
|
||||
|
||||
struct vecs_tag
|
||||
{
|
||||
void *pointer;
|
||||
|
||||
vecs_tag_s *next_in_chain;
|
||||
|
||||
vecs_tag_name_s *name;
|
||||
vecs_tag_s *next_with_same_name;
|
||||
vecs_tag_s *previous_with_same_name;
|
||||
};
|
||||
|
||||
struct vecs_shadow
|
||||
{
|
||||
vx_uuid_d identifier;
|
||||
|
||||
vecs_tag_s *first_tag;
|
||||
};
|
||||
|
||||
struct vecs
|
||||
{
|
||||
vx_pool_s *tag_pool;
|
||||
vx_pool_s *shadow_pool;
|
||||
vecs_tag_name_resolver_s resolver;
|
||||
vecs_entity_map_s lookup_map;
|
||||
vx_uuid_table_s *uuid_table;
|
||||
};
|
||||
|
||||
vecs_s * vecs_new();
|
||||
void vecs_free(vecs_s *ecs);
|
||||
|
||||
vecs_tag_name_resolver_s vecs_create_tag_name_resolver();
|
||||
void vecs_delete_tag_name_resolver(vecs_tag_name_resolver_s *resolver);
|
||||
|
||||
vecs_tag_name_s * vecs_make_tag_name(vecs_tag_name_resolver_s *resolver, const char *name);
|
||||
vecs_tag_name_s * vecs_search_tag_name(vecs_tag_name_resolver_s *resolver, const char *name);
|
||||
|
||||
#endif // VECS_H
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
#ifndef VOXULA_ENTITY_LOOKUP_H
|
||||
#define VOXULA_ENTITY_LOOKUP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include <voxula/internals/utility.h>
|
||||
|
||||
typedef struct vecs_entity_map vecs_entity_map_s;
|
||||
typedef struct vecs_entity_entry vecs_entity_entry_s;
|
||||
|
||||
struct vecs_entity_entry
|
||||
{
|
||||
void *shadow;
|
||||
};
|
||||
|
||||
struct vecs_entity_map
|
||||
{
|
||||
uint32_t entries_capacity;
|
||||
uint32_t num_entries;
|
||||
vecs_entity_entry_s *entries;
|
||||
};
|
||||
|
||||
vecs_entity_map_s vecs_create_lookup_map();
|
||||
void vecs_delete_lookup_map(vecs_entity_map_s *map);
|
||||
|
||||
void * vecs_lookup_entity(vecs_entity_map_s *map, vx_uuid_d uuid);
|
||||
void vecs_register_entity(vecs_entity_map_s *map, void *shadow_ptr);
|
||||
void vecs_unregister_entity(vecs_entity_map_s *map, void *shadow_ptr);
|
||||
|
||||
#endif // VOXULA_ENTITY_LOOKUP_H
|
|
@ -0,0 +1,25 @@
|
|||
#include <voxula/internals/ecs/entity.h>
|
||||
#include <voxula/internals/ecs/head.h>
|
||||
|
||||
vecs_entity_s vecs_summon(void *ecs_pointer)
|
||||
{
|
||||
vecs_s *ecs = ecs_pointer;
|
||||
|
||||
vecs_entity_s entity;
|
||||
entity.head_structure = ecs;
|
||||
entity.uuid = vx_new_uuid(ecs->uuid_table);
|
||||
|
||||
vecs_shadow_s *shadow = vx_pool(ecs->shadow_pool);
|
||||
shadow->identifier = entity.uuid;
|
||||
shadow->first_tag = NULL;
|
||||
|
||||
vecs_register_entity(&ecs->lookup_map, shadow);
|
||||
return entity;
|
||||
}
|
||||
|
||||
void vecs_vanish(vecs_entity_s *entity)
|
||||
{
|
||||
vecs_s *ecs = entity->head_structure;
|
||||
vecs_shadow_s *shadow = vecs_lookup_entity(&ecs->lookup_map, entity->uuid);
|
||||
vecs_unregister_entity(&ecs->lookup_map, shadow);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include <voxula/internals/ecs/lookup.h>
|
||||
#include <voxula/internals/ecs/head.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
vecs_s * vecs_new()
|
||||
{
|
||||
vecs_s *ecs = malloc(sizeof(vecs_s));
|
||||
ecs->resolver = vecs_create_tag_name_resolver();
|
||||
ecs->lookup_map = vecs_create_lookup_map();
|
||||
ecs->shadow_pool = vx_new_pool(sizeof(vecs_shadow_s), 8192);
|
||||
ecs->tag_pool = vx_new_pool(sizeof(vecs_tag_s), 32768);
|
||||
ecs->uuid_table = vx_new_uuid_table();
|
||||
return ecs;
|
||||
}
|
||||
|
||||
void vecs_free(vecs_s *ecs)
|
||||
{
|
||||
vecs_delete_tag_name_resolver(&ecs->resolver);
|
||||
vx_free_pool(ecs->shadow_pool);
|
||||
vx_free_pool(ecs->tag_pool);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include <voxula/internals/ecs/lookup.h>
|
||||
#include <voxula/internals/ecs/head.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
vecs_entity_map_s vecs_create_lookup_map()
|
||||
{
|
||||
vecs_entity_map_s map;
|
||||
map.num_entries = 0;
|
||||
map.entries_capacity = 8192;
|
||||
map.entries = malloc(map.entries_capacity * sizeof(vx_uuid_entry_s));
|
||||
return map;
|
||||
}
|
||||
|
||||
void vecs_delete_lookup_map(vecs_entity_map_s *map)
|
||||
{
|
||||
free(map->entries);
|
||||
}
|
||||
|
||||
void * vecs_lookup_entity(vecs_entity_map_s *map, vx_uuid_d uuid)
|
||||
{
|
||||
uint32_t entry_index = 0;
|
||||
while(entry_index < map->num_entries)
|
||||
{
|
||||
vecs_shadow_s *shadow = map->entries[entry_index].shadow;
|
||||
if(shadow->identifier == uuid)
|
||||
{
|
||||
return shadow;
|
||||
}
|
||||
++entry_index;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vecs_register_entity(vecs_entity_map_s *map, void *shadow_ptr)
|
||||
{
|
||||
vecs_entity_entry_s *entry = &map->entries[map->num_entries];
|
||||
entry->shadow = shadow_ptr;
|
||||
++map->num_entries;
|
||||
}
|
||||
|
||||
void vecs_unregister_entity(vecs_entity_map_s *map, void *shadow_ptr)
|
||||
{
|
||||
vecs_shadow_s *shadow = shadow_ptr;
|
||||
uint32_t entry_index = 0;
|
||||
while(entry_index < map->num_entries)
|
||||
{
|
||||
vecs_shadow_s *entry = map->entries[entry_index].shadow;
|
||||
if(entry->identifier == shadow->identifier)
|
||||
{
|
||||
map->entries[entry_index] = map->entries[map->num_entries - 1];
|
||||
break;
|
||||
}
|
||||
++entry_index;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#include <voxula/internals/ecs/head.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
vecs_tag_name_resolver_s vecs_create_tag_name_resolver()
|
||||
{
|
||||
vecs_tag_name_resolver_s resolver;
|
||||
resolver.names_capacity = 1024;
|
||||
resolver.num_names = 0;
|
||||
resolver.names = malloc(resolver.names_capacity * sizeof(vecs_tag_name_s));
|
||||
resolver.string_arena = vx_new_arena(16384);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
void vecs_delete_tag_name_resolver(vecs_tag_name_resolver_s *resolver)
|
||||
{
|
||||
vx_free_arena(resolver->string_arena);
|
||||
free(resolver->names);
|
||||
}
|
||||
|
||||
vecs_tag_name_s * vecs_force_create_tag_name(vecs_tag_name_resolver_s *resolver, const char *name)
|
||||
{
|
||||
uint32_t len_name = strlen(name);
|
||||
vecs_tag_name_s *tag_name = &resolver->names[resolver->num_names];
|
||||
++resolver->num_names;
|
||||
tag_name->length = len_name;
|
||||
tag_name->string = vx_arena_dupe_string(resolver->string_arena, name);
|
||||
tag_name->uuid = vx_new_uuid(resolver->uuid_table);
|
||||
return tag_name;
|
||||
}
|
||||
|
||||
vecs_tag_name_s * vecs_make_tag_name(vecs_tag_name_resolver_s *resolver, const char *name)
|
||||
{
|
||||
vecs_tag_name_s *tag_name = vecs_search_tag_name(resolver, name);
|
||||
if(tag_name)
|
||||
{
|
||||
return tag_name;
|
||||
}
|
||||
return vecs_force_create_tag_name(resolver, name);
|
||||
}
|
||||
|
||||
vecs_tag_name_s * vecs_search_tag_name(vecs_tag_name_resolver_s *resolver, const char *string)
|
||||
{
|
||||
uint32_t len_string = strlen(string);
|
||||
uint32_t name_index = 0;
|
||||
while(name_index < resolver->num_names)
|
||||
{
|
||||
vecs_tag_name_s *name = &resolver->names[name_index];
|
||||
if(name->length != len_string)
|
||||
{
|
||||
++name_index;
|
||||
continue;
|
||||
}
|
||||
if( ! memcmp(name->string, string, name->length))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
++name_index;
|
||||
}
|
||||
return NULL;
|
||||
}
|
Loading…
Reference in New Issue