Support tagging entities in ECS
The ECS previously wasn't capable of adding tags to the entities; the 'C' of ECS wasn't there. The tagging still needs some tests.
This commit is contained in:
parent
81e10aa64b
commit
25399640a4
|
@ -2,6 +2,7 @@
|
||||||
#ifndef VOXULA_H
|
#ifndef VOXULA_H
|
||||||
#define VOXULA_H
|
#define VOXULA_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <voxula/internals/utility.h>
|
#include <voxula/internals/utility.h>
|
||||||
|
@ -19,6 +20,11 @@ vecs_s * vecs_new();
|
||||||
void vecs_free(vecs_s *ecs);
|
void vecs_free(vecs_s *ecs);
|
||||||
|
|
||||||
vecs_entity_s vecs_summon(vecs_s *ecs);
|
vecs_entity_s vecs_summon(vecs_s *ecs);
|
||||||
void vecs_vanish(vecs_entity_s *entity);
|
void vecs_vanish(vecs_entity_s entity);
|
||||||
|
|
||||||
|
bool vecs_has(vecs_entity_s entity, const char *name);
|
||||||
|
void vecs_tag(vecs_entity_s entity, const char *name);
|
||||||
|
void * vecs_attach(vecs_entity_s entity, const char *name, uint32_t size);
|
||||||
|
void vecs_detach(vecs_entity_s entity, const char *name);
|
||||||
|
|
||||||
#endif // VOXULA_H
|
#endif // VOXULA_H
|
||||||
|
|
|
@ -15,6 +15,6 @@ struct vecs_entity
|
||||||
};
|
};
|
||||||
|
|
||||||
vecs_entity_s vecs_summon(void *ecs_pointer);
|
vecs_entity_s vecs_summon(void *ecs_pointer);
|
||||||
void vecs_vanish(vecs_entity_s *entity);
|
void vecs_vanish(vecs_entity_s entity);
|
||||||
|
|
||||||
#endif // VECS_ENTITY_H
|
#endif // VECS_ENTITY_H
|
||||||
|
|
|
@ -6,46 +6,16 @@
|
||||||
|
|
||||||
#include <voxula/internals/utility.h>
|
#include <voxula/internals/utility.h>
|
||||||
#include <voxula/internals/ecs/lookup.h>
|
#include <voxula/internals/ecs/lookup.h>
|
||||||
|
#include <voxula/internals/ecs/tag.h>
|
||||||
|
|
||||||
typedef struct vecs vecs_s;
|
typedef struct vecs vecs_s;
|
||||||
typedef struct vecs_shadow vecs_shadow_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
|
struct vecs_shadow
|
||||||
{
|
{
|
||||||
vx_uuid_d identifier;
|
vx_uuid_d identifier;
|
||||||
|
|
||||||
vecs_tag_s *first_tag;
|
void *first_tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vecs
|
struct vecs
|
||||||
|
@ -57,13 +27,7 @@ struct vecs
|
||||||
vx_uuid_table_s *uuid_table;
|
vx_uuid_table_s *uuid_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
vecs_s * vecs_new();
|
vecs_s * vecs_new(vx_uuid_table_s *uuid_table);
|
||||||
void vecs_free(vecs_s *ecs);
|
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
|
#endif // VECS_H
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
#ifndef VOXULA_ECS_TAG_H
|
||||||
|
#define VOXULA_ECS_TAG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <voxula/internals/ecs/entity.h>
|
||||||
|
#include <voxula/internals/ecs/tag.h>
|
||||||
|
|
||||||
|
typedef struct vecs_tag_name_resolver vecs_tag_name_resolver_s;
|
||||||
|
typedef struct vecs_tag_name vecs_tag_name_s;
|
||||||
|
typedef struct vecs_tag vecs_tag_s;
|
||||||
|
|
||||||
|
struct vecs_tag_name
|
||||||
|
{
|
||||||
|
vx_uuid_d uuid;
|
||||||
|
uint32_t length;
|
||||||
|
char *string;
|
||||||
|
vecs_tag_s *first_user;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
vecs_tag_name_resolver_s vecs_create_tag_name_resolver(vx_uuid_table_s *uuid_table);
|
||||||
|
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 // VOXULA_ECS_TAG_H
|
|
@ -16,10 +16,3 @@ vecs_entity_s vecs_summon(void *ecs_pointer)
|
||||||
vecs_register_entity(&ecs->lookup_map, shadow);
|
vecs_register_entity(&ecs->lookup_map, shadow);
|
||||||
return entity;
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#include <voxula/internals/ecs/lookup.h>
|
#include <voxula/internals/ecs/lookup.h>
|
||||||
|
#include <voxula/internals/ecs/tag.h>
|
||||||
#include <voxula/internals/ecs/head.h>
|
#include <voxula/internals/ecs/head.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
vecs_s * vecs_new()
|
vecs_s * vecs_new(vx_uuid_table_s *uuid_table)
|
||||||
{
|
{
|
||||||
vecs_s *ecs = malloc(sizeof(vecs_s));
|
vecs_s *ecs = malloc(sizeof(vecs_s));
|
||||||
ecs->resolver = vecs_create_tag_name_resolver();
|
ecs->resolver = vecs_create_tag_name_resolver(uuid_table);
|
||||||
ecs->lookup_map = vecs_create_lookup_map();
|
ecs->lookup_map = vecs_create_lookup_map(uuid_table);
|
||||||
ecs->shadow_pool = vx_new_pool(sizeof(vecs_shadow_s), 8192);
|
ecs->shadow_pool = vx_new_pool(sizeof(vecs_shadow_s), 8192);
|
||||||
ecs->tag_pool = vx_new_pool(sizeof(vecs_tag_s), 32768);
|
ecs->tag_pool = vx_new_pool(sizeof(vecs_tag_s), 32768);
|
||||||
ecs->uuid_table = vx_new_uuid_table();
|
ecs->uuid_table = uuid_table;
|
||||||
return ecs;
|
return ecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
#include <voxula/internals/ecs/head.h>
|
#include <voxula/internals/ecs/head.h>
|
||||||
|
#include <voxula/internals/ecs/tag.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
vecs_tag_name_resolver_s vecs_create_tag_name_resolver()
|
vecs_tag_name_resolver_s vecs_create_tag_name_resolver(vx_uuid_table_s *uuid_table)
|
||||||
{
|
{
|
||||||
vecs_tag_name_resolver_s resolver;
|
vecs_tag_name_resolver_s resolver;
|
||||||
resolver.names_capacity = 1024;
|
resolver.names_capacity = 1024;
|
||||||
resolver.num_names = 0;
|
resolver.num_names = 0;
|
||||||
resolver.names = malloc(resolver.names_capacity * sizeof(vecs_tag_name_s));
|
resolver.names = malloc(resolver.names_capacity * sizeof(vecs_tag_name_s));
|
||||||
resolver.string_arena = vx_new_arena(16384);
|
resolver.string_arena = vx_new_arena(16384);
|
||||||
|
resolver.uuid_table = uuid_table;
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ vecs_tag_name_s * vecs_force_create_tag_name(vecs_tag_name_resolver_s *resolver,
|
||||||
tag_name->length = len_name;
|
tag_name->length = len_name;
|
||||||
tag_name->string = vx_arena_dupe_string(resolver->string_arena, name);
|
tag_name->string = vx_arena_dupe_string(resolver->string_arena, name);
|
||||||
tag_name->uuid = vx_new_uuid(resolver->uuid_table);
|
tag_name->uuid = vx_new_uuid(resolver->uuid_table);
|
||||||
|
tag_name->first_user = NULL;
|
||||||
return tag_name;
|
return tag_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
#include <voxula/internals/ecs/tag.h>
|
||||||
|
#include <voxula/internals/ecs/head.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
vecs_tag_s * vecs_find_tag_in_entity(vecs_entity_s entity, const char *name)
|
||||||
|
{
|
||||||
|
vecs_s *ecs = entity.head_structure;
|
||||||
|
vecs_shadow_s *shadow = vecs_lookup_entity(&ecs->lookup_map, entity.uuid);
|
||||||
|
if( ! shadow)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
vecs_tag_name_s *tag_name = vecs_search_tag_name(&ecs->resolver, name);
|
||||||
|
vecs_tag_s *tag = shadow->first_tag;
|
||||||
|
while(tag != NULL)
|
||||||
|
{
|
||||||
|
if(tag->name->uuid == tag_name->uuid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tag = tag->next_in_chain;
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
vecs_tag_s * vecs_make_tag_in_entity(vecs_entity_s entity, const char *name)
|
||||||
|
{
|
||||||
|
vecs_s *ecs = entity.head_structure;
|
||||||
|
vecs_shadow_s *shadow = vecs_lookup_entity(&ecs->lookup_map, entity.uuid);
|
||||||
|
vecs_tag_name_s *tag_name = vecs_make_tag_name(&ecs->resolver, name);
|
||||||
|
vecs_tag_s *tag = shadow->first_tag;
|
||||||
|
while(tag)
|
||||||
|
{
|
||||||
|
if(tag->name->uuid == tag_name->uuid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tag = tag->next_in_chain;
|
||||||
|
}
|
||||||
|
if( ! tag)
|
||||||
|
{
|
||||||
|
tag = vx_pool(ecs->tag_pool);
|
||||||
|
tag->name = tag_name;
|
||||||
|
tag->next_in_chain = shadow->first_tag;
|
||||||
|
shadow->first_tag = tag;
|
||||||
|
tag->next_with_same_name = tag_name->first_user;
|
||||||
|
tag_name->first_user = tag;
|
||||||
|
if(tag->next_with_same_name)
|
||||||
|
{
|
||||||
|
tag->next_with_same_name->previous_with_same_name = tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vecs_has(vecs_entity_s entity, const char *name)
|
||||||
|
{
|
||||||
|
vecs_tag_s *tag = vecs_find_tag_in_entity(entity, name);
|
||||||
|
if(tag == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vecs_tag(vecs_entity_s entity, const char *name)
|
||||||
|
{
|
||||||
|
vecs_tag_s *tag = vecs_make_tag_in_entity(entity, name);
|
||||||
|
tag->pointer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * vecs_attach(vecs_entity_s entity, const char *name, uint32_t size)
|
||||||
|
{
|
||||||
|
vecs_tag_s *tag = vecs_make_tag_in_entity(entity, name);
|
||||||
|
|
||||||
|
tag->pointer = malloc(size);
|
||||||
|
return tag->pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vecs_detach(vecs_entity_s entity, const char *name)
|
||||||
|
{
|
||||||
|
vecs_tag_s *tag = vecs_find_tag_in_entity(entity, name);
|
||||||
|
if( ! tag)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(tag->next_with_same_name)
|
||||||
|
{
|
||||||
|
tag->next_with_same_name->previous_with_same_name = tag->previous_with_same_name;
|
||||||
|
}
|
||||||
|
if(tag->previous_with_same_name)
|
||||||
|
{
|
||||||
|
tag->previous_with_same_name->next_with_same_name = tag->next_with_same_name;
|
||||||
|
}
|
||||||
|
vx_unpool(tag);
|
||||||
|
}
|
Loading…
Reference in New Issue