diff --git a/core/exports/maintree/maintree.h b/core/exports/maintree/maintree.h index 9769103..0a23179 100644 --- a/core/exports/maintree/maintree.h +++ b/core/exports/maintree/maintree.h @@ -18,28 +18,11 @@ typedef enum MT_TAG_VEC4 } MtTagType; -typedef void MtEntity; +typedef void MtEntity; +typedef void MtState; -/// @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 MtState; - -typedef void (*MtEffectorFn) (MtEntity *entity, void *userdata, usz_t invocation_id); -typedef void (*MtTaskMainFn) (MtTask *task, void *userdata); typedef bool_t (*MtQueryMatcherFn) (MtEntity *entity, void *userdata); -typedef struct -{ - char *task_name; - usz_t min_num_threads; - usz_t max_num_threads; - MtTaskMainFn continuous_threads[4]; - void *userdata; - -} MtTaskCreationInfo; - - - MtState * mt_initialize(char *app_name); void mt_cleanup(MtState *state); void mt_start(MtState *state); @@ -47,20 +30,6 @@ void mt_start(MtState *state); MtEntity * mt_summon(MtState *state); void mt_drop(MtEntity *entity); -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_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_remove_effector(MtState *state, const char *effector_name); - -/// @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 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 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. -void mt_add_tagged_tick_effector(MtState *state, char *effector_name, usz_t ticks_delta, MtEffectorFn function, char **tag_names); - usz_t mt_query(MtState *state, const char **tags, MtEntity **entities, usz_t count); usz_t mt_match_query(MtState *state, const char **tags, MtEntity **entities, usz_t count, MtQueryMatcherFn matcher, void *userdata); @@ -84,9 +53,4 @@ 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); -MtTask mt_create_task(MtState *state, MtTaskCreationInfo creation_info); -void mt_delete_task(MtTask *task); - -void mt_task_remove_effector(MtTask *task, const char *effector_name); - #endif // MAINTREE_H diff --git a/core/src-c/queries.c b/core/src-c/queries.c index 86791fd..b4f3311 100644 --- a/core/src-c/queries.c +++ b/core/src-c/queries.c @@ -1,5 +1,6 @@ #include #include +#include usz_t mt_find_tag_with_least_entries(MtState *state, const char **tags) { @@ -82,13 +83,9 @@ usz_t mt_query(MtState *state, const char **tags, MtEntity **entities, usz_t cou return num_written_entities; } -usz_t mt_match_query(MtState *state, const char **tags, MtEntity **entities, usz_t count, MtQueryMatcherFn matcher, void *userdata) +usz_t mt_match_query_with_few_entities(MtState *state, const char **tags, MtEntity **entities, usz_t count, + MtQueryMatcherFn matcher, void *userdata, usz_t num_matching_entities) { - usz_t num_matching_entities = mt_query(state, tags, entities, 0); - if(count == 0) - return num_matching_entities; - - // TODO: If 'num_matching_entities" is too big, this must be allocated on the heap! MtEntity *generally_matching_entities[num_matching_entities]; mt_query(state, tags, &generally_matching_entities[0], num_matching_entities); @@ -105,3 +102,35 @@ usz_t mt_match_query(MtState *state, const char **tags, MtEntity **entities, usz } return written_entities; } + +usz_t mt_match_query_with_many_entities(MtState *state, const char **tags, MtEntity **entities, usz_t count, + MtQueryMatcherFn matcher, void *userdata, usz_t num_matching_entities) +{ + MtEntity **generally_matching_entities = calloc(sizeof(MtEntity), num_matching_entities); + mt_query(state, tags, &generally_matching_entities[0], num_matching_entities); + + usz_t written_entities = 0; + usz_t entity_index = 0; + while((entity_index < num_matching_entities) && (written_entities < count)) + { + if(matcher(generally_matching_entities[entity_index], userdata)) + { + entities[written_entities] = generally_matching_entities[entity_index]; + ++written_entities; + } + ++entity_index; + } + free(generally_matching_entities); + return written_entities; +} + +usz_t mt_match_query(MtState *state, const char **tags, MtEntity **entities, usz_t count, MtQueryMatcherFn matcher, void *userdata) +{ + usz_t num_matching_entities = mt_query(state, tags, entities, 0); + if(count == 0) + return num_matching_entities; + + if(num_matching_entities > 1024) + return mt_match_query_with_many_entities(state, tags, entities, count, matcher, userdata, num_matching_entities); + return mt_match_query_with_few_entities(state, tags, entities, count, matcher, userdata, num_matching_entities); +} diff --git a/core/src-c/state.c b/core/src-c/state.c index 07be5cc..0507cfd 100644 --- a/core/src-c/state.c +++ b/core/src-c/state.c @@ -29,13 +29,6 @@ void mt_cleanup(MtState *state) free(state); } -/* TODO: This function should start a new thread with a worker system. -void mt_start(MtState state) -{ - -} -*/ - MtEntity * mt_summon(MtState *state) { return mt_create_entity(state, state->entity_registry.entity_id_counter++); diff --git a/core/src-c/tag_registry.c b/core/src-c/tag_registry.c index 7cca3b5..a74ad57 100644 --- a/core/src-c/tag_registry.c +++ b/core/src-c/tag_registry.c @@ -39,8 +39,10 @@ void mt_delete_all_tag_registry_entries(MtTagRegistry registry) { MtTagEntry entry = registry.entries[index]; if(entry.label != NULL) + { free(entry.label); - + free(entry.entity_identifiers); + } ++index; } free(registry.entries);