Added but didn't test state-struct and entity lookup, entity tagging and entity registry functionality

This commit is contained in:
Eric-Paul Ickhorn 2024-01-29 19:48:56 +01:00
parent 3f7da48836
commit 6979728a96
Signed by: epickh
GPG Key ID: F5EBBE013924D95F
8 changed files with 498 additions and 20 deletions

View File

@ -57,10 +57,10 @@ function compile_module_c_sources {
MODULE_NAME=$1 MODULE_NAME=$1
get_include_path_configuration $MODULE_NAME get_include_path_configuration $MODULE_NAME
echo $INCLUDE_STATEMENTS
MODULE_SOURCE_PATH="$REPOSITORY_FOLDER/$MODULE_NAME/src-c/" MODULE_SOURCE_PATH="$REPOSITORY_FOLDER/$MODULE_NAME/src-c/"
MODULE_OBJECTS_FOLDER="$MAIN_OBJECTS_FOLDER/$MODULE_NAME/" MODULE_OBJECTS_FOLDER="$MAIN_OBJECTS_FOLDER/$MODULE_NAME/"
rm -r $MODULE_OBJECTS_FOLDER
mkdir -p $MODULE_OBJECTS_FOLDER mkdir -p $MODULE_OBJECTS_FOLDER
# Loop through all files in the 'src-c'-folder and hand them over to GCC # Loop through all files in the 'src-c'-folder and hand them over to GCC

View File

@ -6,59 +6,53 @@
#include <librr/types.h> #include <librr/types.h>
#include <librr/linear_algebra.h> #include <librr/linear_algebra.h>
typedef void * MtType;
typedef void * MtEntity; typedef void * MtEntity;
/// @brief: An MtTask is a piece of functionality with an own state/context which will be executed on the same thread or set of threads. /// @brief: An MtTask is a piece of functionality with an own state/context which will be executed on the same thread or set of threads.
typedef void * MtTask; typedef void * MtTask;
typedef void * MtState; typedef void * MtState;
typedef void (*MtEffectorFn) (MtEntity entity, void *userdata, usz_t invocation_id);
typedef void (*MtTaskMainFn) (MtTask task, void *userdata);
typedef void (*mt_type_effector_fn) (MtType type, void *userdata, usz_t invocation);
typedef void (*mt_entity_effector_fn) (MtEntity entity, void *userdata, usz_t invocation);
typedef void (*mt_task_main_fn) (MtTask task, void *userdata);
typedef struct typedef struct
{ {
char *task_name; char *task_name;
usz_t min_num_threads; usz_t min_num_threads;
usz_t max_num_threads; usz_t max_num_threads;
MtTaskMainFn continuous_threads[4];
void *userdata; void *userdata;
} MtTaskCreationInfo; } MtTaskCreationInfo;
MtState mt_create_state(char *app_name); MtState mt_initialize(char *app_name);
void mt_cleanup(MtState state); void mt_cleanup(MtState state);
void mt_start(MtState state); void mt_start(MtState state);
MtType mt_register_type(char *identifier); MtEntity mt_summon(MtState state);
void mt_forget_type(MtType type);
MtEntity mt_make(MtType type); void mt_add_create_effector(MtState state, char *effector_name, MtEffectorFn function, void *userdata);
void mt_add_registration_effector(MtState state, char *effector_name, mt_type_effector_fn function, void *userdata); void mt_add_delete_effector(MtState state, char *effector_name, MtEffectorFn function, void *userdata);
void mt_add_create_effector(MtType type, char *effector_name, mt_entity_effector_fn function, void *userdata); void mt_add_entity_effector(MtState state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, void *userdata);
void mt_add_delete_effector(MtType type, char *effector_name, mt_entity_effector_fn function, void *userdata); void mt_add_tick_effector(MtState state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, void *userdata);
void mt_add_entity_tick_effector(MtType type, char *effector_name, usz_t ticks_delta, mt_entity_effector_fn function, void *userdata);
void mt_add_tick_effector(MtState state, char *effector_name, usz_t ticks_delta, mt_entity_effector_fn function, void *userdata);
void mt_remove_effector(MtState state, const char *effector_name); void mt_remove_effector(MtState state, const char *effector_name);
/// @brief Adds a tick effector which only acts upon entitys with certain tags. /// @brief Adds a tick effector which only acts upon entitys with certain tags.
/// @param type The type for which to add the tick effector. /// @param state The state in which the tick effector should reside.
/// @param effector_name The name of the effector. This will be copied into the effector's structure. /// @param effector_name The name of the effector. This will be copied into the effector's structure.
/// @param ticks_delta The wanted number of ticks between two invocations of the effector /// @param ticks_delta The wanted number of ticks between two invocations of the effector.
/// @param function The function to call for an entity if it contains all necessary tags. /// @param function The function to call for an entity if it contains all necessary tags.
/// @param tag_names A nullpointer-terminated list of tag-ids that must be present in an entity for that entity to be effected. /// @param tag_names A nullpointer-terminated list of tag-ids that must be present in an entity for that entity to be effected.
void mt_add_tagged_tick_effector(MtType type, char *effector_name, usz_t ticks_delta, mt_entity_effector_fn function, char **tag_names); void mt_add_tagged_tick_effector(MtState state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, char **tag_names);
void mt_tag_i64(MtEntity entity, char *name, i64_t integer); void mt_tag_i64(MtEntity entity, char *name, i64_t integer);
void mt_tag_f64(MtEntity entity, char *name, f64_t real); void mt_tag_f64(MtEntity entity, char *name, f64_t real);
void mt_tag_str(MtEntity entity, char *name, char *string); void mt_tag_str(MtEntity entity, char *name, char *string);
void mt_tag_ptr(MtEntity entity, char *name, void *pointer); void mt_tag_ptr(MtEntity entity, char *name, void *pointer);
void mt_tag_vec2(MtEntity entity, char *name, rr_vec2f_s vector); void mt_tag_vec2(MtEntity entity, char *name, rr_vec2f_s vector);
void mt_tag_vec3(MtEntity entity, char *name, rr_vec2f_s vector); void mt_tag_vec3(MtEntity entity, char *name, rr_vec3f_s vector);
void mt_tag_vec4(MtEntity entity, char *name, rr_vec4f_s vector); void mt_tag_vec4(MtEntity entity, char *name, rr_vec4f_s vector);
void mt_untag(MtEntity entity, char *name); void mt_untag(MtEntity entity, char *name);

109
core/inc-c/entity.h Normal file
View File

@ -0,0 +1,109 @@
#ifndef MT_ENTITY_POOL_H
#define MT_ENTITY_POOL_H
#include <librr/types.h>
#include <librr/linear_algebra.h>
typedef struct MtEntityLookupTree MtEntityLookupTree;
typedef struct MtEntityListL1 MtEntityListL1;
typedef struct MtEntityListL2 MtEntityListL2;
typedef struct MtEntityListL3 MtEntityListL3;
typedef struct MtEntityPool MtEntityPool;
typedef struct MtEntityRegistry MtEntityRegistry;
typedef struct MtEntity * MtEntity;
typedef struct MtTag * MtTag;
struct MtEntityPool
{
usz_t capacity;
struct MtEntity *entities;
struct MtEntity *first_free;
MtEntityPool *continuation;
};
struct MtEntityLookupTree
{
MtEntityListL1 *sublists[256];
};
struct MtEntityListL1
{
MtEntityListL2 *sublists[256];
};
struct MtEntityListL2
{
MtEntityListL3 *sublists[256];
};
struct MtEntityListL3
{
struct MtEntity *entities[256];
};
struct MtEntityRegistry
{
MtEntityPool pool;
MtEntityLookupTree lookup;
};
struct MtEntity
{
void *parent_state;
MtEntity pool_next_free;
u32_t identifier;
u16_t tags_capacity;
u16_t num_tags;
struct MtTag *tags;
};
struct MtTag
{
u32_t identifier;
union MtTagData
{
i64_t integer;
f64_t real;
char *string;
void *pointer;
rr_vec2f_s vec2f;
rr_vec3f_s vec3f;
rr_vec4f_s vec4f;
} data;
};
MtEntityRegistry mt_create_entity_registry();
void mt_delete_entity_registry(MtEntityRegistry *entity_list);
MtEntity mt_create_entity(void *state_voidptr, u32_t identifier);
MtEntity mt_get_entity(void *state_voidptr, u32_t identifier);
void mt_tag_i64(MtEntity entity, char *name, i64_t integer);
void mt_tag_f64(MtEntity entity, char *name, f64_t real);
void mt_tag_str(MtEntity entity, char *name, char *string);
void mt_tag_ptr(MtEntity entity, char *name, void *pointer);
void mt_tag_vec2(MtEntity entity, char *name, rr_vec2f_s vector);
void mt_tag_vec3(MtEntity entity, char *name, rr_vec3f_s vector);
void mt_tag_vec4(MtEntity entity, char *name, rr_vec4f_s vector);
void mt_untag(MtEntity entity, char *name);
i64_t mt_get_i64_tag(MtEntity entity, char *name);
f64_t mt_get_f64_tag(MtEntity entity, char *name);
char * mt_get_str_tag(MtEntity entity, char *name);
void * mt_get_ptr_tag(MtEntity entity, char *name);
rr_vec2f_s mt_get_vec2_tag(MtEntity entity, char *name);
rr_vec3f_s mt_get_vec3_tag(MtEntity entity, char *name);
rr_vec4f_s mt_get_vec4_tag(MtEntity entity, char *name);
MtEntityPool mt_create_entity_pool(usz_t capacity);
void mt_delete_entity_pool(MtEntityPool *pool);
MtEntity mt_get_entity_pool_slot(MtEntityPool *pool);
#endif // MT_ENTITY_POOL_H

27
core/inc-c/state.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef MT_STATE_H
#define MT_STATE_H
#include <tag_registry.h>
#include <entity.h>
#include <librr/types.h>
#include <librr/alloc/generic.h>
typedef struct MtState * MtState;
struct MtState
{
char *app_name;
MtTagRegistry tag_registry;
MtEntityRegistry entity_list;
};
MtState mt_initialize(char *app_name);
void mt_cleanup(MtState state);
void mt_start(MtState state);
MtEntity mt_summon(MtState state);
#endif // MT_STATE_H

View File

@ -0,0 +1,57 @@
#include <entity.h>
#include <state.h>
#include <stdlib.h>
MtEntity mt_create_entity(void *state_voidptr, u32_t identifier)
{
MtState state = state_voidptr;
MtEntityListL1 *level1 = state->entity_list.lookup.sublists[identifier >> 24];
if(level1 == NULL)
{
state->entity_list.lookup.sublists[identifier >> 24] = calloc(sizeof(MtEntityListL1), 1);
level1 = state->entity_list.lookup.sublists[identifier >> 24];
}
MtEntityListL2 *level2 = level1->sublists[(identifier >> 16) & 0xff];
if(level2 == NULL)
{
level1->sublists[(identifier >> 16) & 0xff] = calloc(sizeof(MtEntityListL2), 1);
level2 = level1->sublists[(identifier >> 16) & 0xff];
}
MtEntityListL3 *level3 = level2->sublists[(identifier >> 8) & 0xff];
if(level3 == NULL)
{
level2->sublists[(identifier >> 8) & 0xff] = calloc(sizeof(MtEntityListL3), 1);
level3 = level2->sublists[(identifier >> 8) & 0xff];
}
MtEntity entity = level3->entities[identifier & 0xff];
if(entity == NULL)
{
entity = mt_get_entity_pool_slot(&state->entity_list.pool);
}
return entity;
}
MtEntity mt_get_entity(void *state_voidptr, u32_t identifier)
{
MtState state = state_voidptr;
MtEntityListL1 *level1 = state->entity_list.lookup.sublists[identifier >> 24];
if(level1 == NULL)
return NULL;
MtEntityListL2 *level2 = level1->sublists[(identifier >> 16) & 0xff];
if(level2 == NULL)
return NULL;
MtEntityListL3 *level3 = level2->sublists[(identifier >> 8) & 0xff];
if(level3 == NULL)
return NULL;
MtEntity entity = level3->entities[identifier & 0xff];
if(entity == NULL)
return NULL;
return entity;
}

View File

@ -0,0 +1,143 @@
#include <entity.h>
#include <librr/memory.h>
#include <stdlib.h>
void mt_delete_entity(MtEntity entity);
MtEntityLookupTree mt_create_entity_lookup_tree();
void mt_delete_entity_lookup_tree(MtEntityLookupTree lookup_tree);
MtEntityRegistry mt_create_entity_registry()
{
MtEntityRegistry entity_registry;
entity_registry.lookup = mt_create_entity_lookup_tree();
return entity_registry;
}
void mt_delete_entity_registry(MtEntityRegistry *entity_registry)
{
mt_delete_entity_pool(&entity_registry->pool);
}
MtEntityLookupTree mt_create_entity_lookup_tree()
{
MtEntityLookupTree lookup_tree;
rr_memset(&lookup_tree.sublists[0], sizeof(MtEntityListL1 *) * 256, 0x00);
return lookup_tree;
}
void mt_delete_entity_lookup_tree(MtEntityLookupTree lookup_tree)
{
usz_t level1_index = 0;
while(level1_index < 256)
{
if(lookup_tree.sublists[level1_index] == NULL)
{
++level1_index;
continue;
}
MtEntityListL1 *level1_list = lookup_tree.sublists[level1_index];
usz_t level2_index = 0;
while(level2_index < 256)
{
MtEntityListL2 *level2_list = level1_list->sublists[level2_index];
if(level2_list == NULL)
{
++level2_index;
continue;
}
usz_t level3_index = 0;
while(level3_index)
{
MtEntityListL3 *level3_list = level2_list->sublists[level3_index];
if(level3_list == NULL)
{
++level3_index;
continue;
}
usz_t entity_index = 0;
while(entity_index)
{
MtEntity entity = level3_list->entities[entity_index];
if(entity == NULL)
{
++entity_index;
continue;
}
mt_delete_entity(entity);
++entity_index;
}
free(level3_list);
++level3_index;
}
free(level2_list);
++level2_index;
}
free(level1_list);
++level1_index;
}
}
void mt_delete_entity(MtEntity entity)
{
if(entity->tags != NULL)
free(entity->tags);
}
void mt_reset_entity_pool_allocation(MtEntityPool *pool)
{
usz_t entity_index = 0;
while(entity_index < pool->capacity)
{
pool->entities[entity_index].pool_next_free = &pool->entities[entity_index+1];
++entity_index;
}
pool->entities[pool->capacity - 1].pool_next_free = NULL;
}
MtEntityPool mt_create_entity_pool(usz_t capacity)
{
MtEntityPool pool;
pool.capacity = capacity;
pool.entities = calloc(sizeof(struct MtEntity), pool.capacity);
mt_reset_entity_pool_allocation(&pool);
pool.first_free = &pool.entities[0];
pool.continuation = NULL;
return pool;
}
void mt_delete_entity_pool(MtEntityPool *pool)
{
if(pool->continuation != NULL)
{
mt_delete_entity_pool(pool->continuation);
free(pool->continuation);
}
free(pool->entities);
}
MtEntity mt_get_entity_pool_slot(MtEntityPool *pool)
{
if(pool->first_free == NULL)
{
if(pool->continuation == NULL)
{
pool->continuation = malloc(sizeof(MtEntityPool));
*pool->continuation = mt_create_entity_pool(pool->capacity * 2);
}
return mt_get_entity_pool_slot(pool->continuation);
}
MtEntity allocated = pool->first_free;
pool->first_free = allocated->pool_next_free;
return allocated;
}

119
core/src-c/entity_tagging.c Normal file
View File

@ -0,0 +1,119 @@
#include <entity.h>
#include <state.h>
#include <stdlib.h>
MtTag mt_get_entity_tag_slot(MtEntity entity, char *name)
{
MtState state = entity->parent_state;
// Find the correct slot if it already exist
u32_t tag_id = mt_get_tag_id(&state->tag_registry, name);
usz_t tag_index = 0;
while(tag_index < entity->num_tags)
{
if(entity->tags[tag_index].identifier == tag_id)
return &entity->tags[tag_index];
++tag_index;
}
// Create a new slot if needed
if(entity->num_tags >= entity->tags_capacity)
{
entity->tags_capacity *= 2;
if(entity->tags_capacity == 0)
entity->tags_capacity = 4;
entity->tags = realloc(entity->tags, sizeof(struct MtTag) * entity->tags_capacity);
}
return &entity->tags[entity->num_tags++];
}
void mt_tag_i64(MtEntity entity, char *name, i64_t integer)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.integer = integer;
}
void mt_tag_f64(MtEntity entity, char *name, f64_t real)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.real = real;
}
void mt_tag_str(MtEntity entity, char *name, char *string)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.string = string;
}
void mt_tag_ptr(MtEntity entity, char *name, void *pointer)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.pointer = pointer;
}
void mt_tag_vec2(MtEntity entity, char *name, rr_vec2f_s vector)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.vec2f = vector;
}
void mt_tag_vec3(MtEntity entity, char *name, rr_vec3f_s vector)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.vec3f = vector;
}
void mt_tag_vec4(MtEntity entity, char *name, rr_vec4f_s vector)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
tag->data.vec4f = vector;
}
void mt_untag(MtEntity entity, char *name);
i64_t mt_get_i64_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.integer;
}
f64_t mt_get_f64_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.real;
}
char * mt_get_str_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.string;
}
void * mt_get_ptr_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.pointer;
}
rr_vec2f_s mt_get_vec2_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.vec2f;
}
rr_vec3f_s mt_get_vec3_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.vec3f;
}
rr_vec4f_s mt_get_vec4_tag(MtEntity entity, char *name)
{
MtTag tag = mt_get_entity_tag_slot(entity, name);
return tag->data.vec4f;
}

29
core/src-c/state.c Normal file
View File

@ -0,0 +1,29 @@
#include <state.h>
#include <librr/strutil.h>
#include <librr/memory.h>
#include <stdlib.h>
MtState mt_initialize(char *app_name)
{
usz_t len_app_name = rr_measure_string(app_name);
MtState state = malloc(sizeof(struct MtState));
state->app_name = malloc(len_app_name + 1);
rr_memcopy(state->app_name, app_name, len_app_name + 1);
state->tag_registry = mt_create_tag_registry(state);
return state;
}
void mt_cleanup(MtState state)
{
mt_delete_entity_registry(&state->entity_list);
free(state);
}
/* TODO: This function should start a new thread with a worker system.
void mt_start(MtState state)
{
}
*/