General codebase improvements and a fix for a bug in the tag registry

This commit is contained in:
Eric-Paul Ickhorn 2024-01-31 00:58:11 +01:00
parent 275dbdc748
commit 53a63e61db
Signed by: epickh
GPG Key ID: F5EBBE013924D95F
9 changed files with 113 additions and 58 deletions

View File

@ -133,6 +133,9 @@ case $1 in
"b" | "build-dependencies") "b" | "build-dependencies")
build_dependencies build_dependencies
;; ;;
"t" | "test")
./build_tests.bash
;;
"h" | "help") "h" | "help")
echo "Known Actions:" echo "Known Actions:"
echo "[ d | dbg | debug ]: Build in the debug profile; build with debug symbols." echo "[ d | dbg | debug ]: Build in the debug profile; build with debug symbols."

View File

@ -4,6 +4,7 @@ cd $(dirname "$(pwd)/$0")
REPOSITORY_FOLDER=$(pwd) REPOSITORY_FOLDER=$(pwd)
MAIN_OBJECTS_FOLDER="$REPOSITORY_FOLDER/.build/objects/" MAIN_OBJECTS_FOLDER="$REPOSITORY_FOLDER/.build/objects/"
CC_OPTIONS="-g3 -Wall -Wextra -Wpedantic"
DEFAULT_INCLUDE_PATHS=" DEFAULT_INCLUDE_PATHS="
-I .build/depends/libRR/Core/core/exports/ -I .build/depends/libRR/Core/core/exports/
-I .build/depends/libRR/Core/platform/exports/ -I .build/depends/libRR/Core/platform/exports/
@ -55,7 +56,7 @@ function compile_single_test() {
get_include_path_configuration $TEST_PATH get_include_path_configuration $TEST_PATH
get_linkage_path_configuration $TEST_PATH get_linkage_path_configuration $TEST_PATH
gcc -g3 -o $TEST_PATH/$TEST_NAME.elf $TEST_PATH/*.c $LINKAGE_PATHS $INCLUDE_STATEMENTS gcc $CC_OPTIONS -o $TEST_PATH/$TEST_NAME.elf $TEST_PATH/*.c $LINKAGE_PATHS $INCLUDE_STATEMENTS
} }
function compile_all_tests_of_module() { function compile_all_tests_of_module() {

View File

@ -6,14 +6,14 @@
#include <librr/types.h> #include <librr/types.h>
#include <librr/linear_algebra.h> #include <librr/linear_algebra.h>
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 (*MtEffectorFn) (MtEntity *entity, void *userdata, usz_t invocation_id);
typedef void (*MtTaskMainFn) (MtTask task, void *userdata); typedef void (*MtTaskMainFn) (MtTask *task, void *userdata);
typedef struct typedef struct
{ {
@ -27,18 +27,18 @@ typedef struct
MtState mt_initialize(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);
MtEntity mt_summon(MtState state); MtEntity * mt_summon(MtState *state);
void mt_drop(MtEntity entity); void mt_drop(MtEntity *entity);
void mt_add_create_effector(MtState state, char *effector_name, MtEffectorFn function, void *userdata); void mt_add_create_effector(MtState *state, char *effector_name, MtEffectorFn function, void *userdata);
void mt_add_delete_effector(MtState state, char *effector_name, MtEffectorFn function, void *userdata); void mt_add_delete_effector(MtState *state, char *effector_name, MtEffectorFn function, void *userdata);
void mt_add_entity_effector(MtState state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, void *userdata); void mt_add_entity_effector(MtState *state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, void *userdata);
void mt_add_tick_effector(MtState state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, void *userdata); void mt_add_tick_effector(MtState *state, char *effector_name, usz_t ticks_delta, MtEffectorFn 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 state The state in which the tick effector should reside. /// @param state The state in which the tick effector should reside.
@ -46,29 +46,29 @@ void mt_remove_effector(MtState state, const char *effector_name);
/// @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(MtState state, char *effector_name, usz_t ticks_delta, MtEffectorFn 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_vec3f_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);
i64_t mt_get_i64_tag(MtEntity entity, char *name); i64_t mt_get_i64_tag(MtEntity *entity, char *name);
f64_t mt_get_f64_tag(MtEntity entity, char *name); f64_t mt_get_f64_tag(MtEntity *entity, char *name);
char * mt_get_str_tag(MtEntity entity, char *name); char * mt_get_str_tag(MtEntity *entity, char *name);
void * mt_get_ptr_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_vec2f_s mt_get_vec2_tag(MtEntity *entity, char *name);
rr_vec3f_s mt_get_vec3_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); rr_vec4f_s mt_get_vec4_tag(MtEntity *entity, char *name);
MtTask mt_create_task(MtState state, MtTaskCreationInfo creation_info); MtTask mt_create_task(MtState *state, MtTaskCreationInfo creation_info);
void mt_delete_task(MtTask task); void mt_delete_task(MtTask *task);
void mt_task_remove_effector(MtTask task, const char *effector_name); void mt_task_remove_effector(MtTask *task, const char *effector_name);
#endif // MAINTREE_H #endif // MAINTREE_H

View File

@ -37,7 +37,7 @@ struct MtTagCollection
u32_t capacity; u32_t capacity;
u32_t usage; u32_t usage;
/// @brief An array of indices for the tag-registry's 'entries'-array. /// @brief An array of indices into the tag-registry's 'entries'-array.
u32_t *tag_indices; u32_t *tag_indices;
}; };

View File

@ -5,6 +5,10 @@
MtState * mt_initialize(char *app_name) MtState * mt_initialize(char *app_name)
{ {
if(app_name == NULL)
{
app_name = "Unnamed Application";
}
usz_t len_app_name = rr_measure_string(app_name); usz_t len_app_name = rr_measure_string(app_name);
MtState *state = malloc(sizeof(struct MtState)); MtState *state = malloc(sizeof(struct MtState));

View File

@ -82,9 +82,28 @@ u32_t mt_tag_label_to_hash(const char *tag_label, usz_t range)
MtTagEntry * mt_create_tag_hash_entry(MtTagRegistry *registry, const char *tag_label) MtTagEntry * mt_create_tag_hash_entry(MtTagRegistry *registry, const char *tag_label)
{ {
// Create a new entry in the flat array of entries
usz_t entry_index = registry->num_entries;
MtTagEntry *entry = &registry->entries[entry_index];
++registry->num_entries;
usz_t len_tag_label = rr_measure_string(tag_label);
// TODO: There MUST be an arena allocator for this!
entry->label = malloc(len_tag_label + 1);
rr_memcopy(entry->label, tag_label, len_tag_label+1);
entry->identifier = registry->next_identifier;
++registry->next_identifier;
// Create an entry in the lookup structure
u32_t collection_index = mt_tag_label_to_hash(tag_label, registry->num_collections); u32_t collection_index = mt_tag_label_to_hash(tag_label, registry->num_collections);
MtTagCollection *collection = &registry->collections[collection_index]; MtTagCollection *collection = &registry->collections[collection_index];
// Resize the collection to be larger if needed
if(collection->usage >= collection->capacity) if(collection->usage >= collection->capacity)
{ {
collection->capacity *= 2; collection->capacity *= 2;
@ -94,19 +113,10 @@ MtTagEntry * mt_create_tag_hash_entry(MtTagRegistry *registry, const char *tag_l
collection->tag_indices = realloc(collection->tag_indices, sizeof(u32_t) * collection->capacity); collection->tag_indices = realloc(collection->tag_indices, sizeof(u32_t) * collection->capacity);
rr_memset(&collection->tag_indices[collection->usage], collection->capacity - collection->usage, 0x00); rr_memset(&collection->tag_indices[collection->usage], collection->capacity - collection->usage, 0x00);
} }
MtTagEntry *entry = &registry->entries[collection->tag_indices[collection->usage]];
++registry->num_entries; collection->tag_indices[collection->usage] = entry_index;
++collection->usage; ++collection->usage;
usz_t len_tag_label = rr_measure_string(tag_label);
// TODO: There must be an arena allocator for this!
entry->label = malloc(len_tag_label + 1);
rr_memcopy(entry->label, tag_label, len_tag_label+1);
entry->identifier = registry->next_identifier;
++registry->next_identifier;
return entry; return entry;
} }

View File

@ -1,9 +1,13 @@
#include <maintree/maintree.h> #include <maintree/maintree.h>
#include <stdio.h>
int main(int argc, char **argv) int main()
{ {
MtState state = mt_initialize("Interface Test");; MtState *state = mt_initialize("Interface Test");;
MtEntity entity = mt_summon(state); MtEntity* entity = mt_summon(state);
mt_drop(entity); mt_drop(entity);
mt_cleanup(state); mt_cleanup(state);
puts("The program reached the end; this test is considered as passed. SUCCESS!");
puts("Note: A memory leak check utility should be used to verify the success.");
return 0;
} }

View File

@ -2,14 +2,43 @@
#include <librr/types.h> #include <librr/types.h>
#include <stdio.h> #include <stdio.h>
int main(int argc, char **argv) int main()
{ {
MtTagRegistry tag_registry = mt_create_tag_registry(NULL); MtTagRegistry tag_registry = mt_create_tag_registry(NULL);
u32_t some_tag = mt_get_tag_id(&tag_registry, "some_tag"); u32_t some_tag = mt_get_tag_id(&tag_registry, "some_tag");
u32_t another_tag = mt_get_tag_id(&tag_registry, "another_tag");
u32_t theres_more = mt_get_tag_id(&tag_registry, "there's more");
if(some_tag != mt_get_tag_id(&tag_registry, "some_tag")) if(some_tag != mt_get_tag_id(&tag_registry, "some_tag"))
{ {
puts("Inconsistent returned tag identifiers."); puts("Inconsistently returned tag identifier in test subject 1. ERROR!");
mt_delete_tag_registry(tag_registry);
return -1;
}
if(another_tag != mt_get_tag_id(&tag_registry, "another_tag"))
{
puts("Inconsistently returned tag identifier in test subject 2. ERROR!");
mt_delete_tag_registry(tag_registry);
return -1;
}
if(theres_more != mt_get_tag_id(&tag_registry, "there's more"))
{
puts("Inconsistently returned tag identifier in test subject 3. ERROR!");
mt_delete_tag_registry(tag_registry);
return -1;
}
if(some_tag == theres_more)
{
puts("Tags are being duplicated in test subject 4. ERROR!");
mt_delete_tag_registry(tag_registry);
return -1;
}
if(some_tag == another_tag)
{
puts("Tags are being duplicated in test subject 5. ERROR!");
mt_delete_tag_registry(tag_registry);
return -1;
} }
mt_delete_tag_registry(tag_registry); mt_delete_tag_registry(tag_registry);
puts("The identifier which is returned for a tag name is consistent. SUCCESS!");
return 0; return 0;
} }

View File

@ -3,17 +3,21 @@
#include <stdio.h> #include <stdio.h>
int main(int argc, char **argv) int main()
{ {
MtState *state = mt_initialize("Interface Test");; MtState *state = mt_initialize("Interface Test");;
MtEntity *entity = mt_summon(state); MtEntity *entity = mt_summon(state);
MtEntity *looked_up_entity = mt_get_entity(state, entity->identifier); MtEntity *looked_up_entity = mt_get_entity(state, entity->identifier);
if(entity != looked_up_entity) if(entity != looked_up_entity)
printf("Failed looking up entity; the pointers don't match:\nOriginal: %p\nLooked Up: %p\n", entity, looked_up_entity); {
else printf("Failed looking up entity; the pointers don't match:\nOriginal: %p\nLooked Up: %p\nERROR!", (void *) entity, (void *) looked_up_entity);
puts("The entity which was looked up from the identifier does match the original. SUCCESS!"); mt_drop(entity);
mt_cleanup(state);
return -1;
}
puts("The entity which was looked up from the identifier does match the original. SUCCESS!");
mt_drop(entity); mt_drop(entity);
mt_cleanup(state); mt_cleanup(state);
return 0;
} }