From 93a7f31757881fa15c1d86b6389108d1c8c9d495 Mon Sep 17 00:00:00 2001 From: NukeBird Date: Thu, 20 Mar 2025 18:12:46 +0300 Subject: [PATCH] make/destroy world/entities --- CMakeLists.txt | 4 +-- tests/zecsy.c | 47 +++++++++++++++++++++++++++-- zecsy.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b50986..ee5e299 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) option(BUILD_ZECSY_TESTS "Build tests?" ON) -add_library(zecsy STATIC zecsy.h) +add_library(zecsy STATIC zecsy.h stb_ds.h) set_target_properties(zecsy PROPERTIES LINKER_LANGUAGE C) if(${BUILD_ZECSY_TESTS}) @@ -21,5 +21,5 @@ if(${BUILD_ZECSY_TESTS}) FetchContent_MakeAvailable(clove-unit) add_executable(tests tests/zecsy.c) - target_link_libraries(tests clove-unit) + target_link_libraries(tests clove-unit zecsy) endif() diff --git a/tests/zecsy.c b/tests/zecsy.c index f6c9067..05b4087 100644 --- a/tests/zecsy.c +++ b/tests/zecsy.c @@ -1,9 +1,52 @@ +#include #define CLOVE_IMPLEMENTATION #include -CLOVE_TEST(oh_hi_mark) +#define ZECSY_IMPLEMENTATION +#include "../zecsy.h" + +CLOVE_TEST(make_and_delete_empty_world) { - CLOVE_IS_TRUE(true); + world* w = NULL; + make_world(&w); + + CLOVE_NOT_NULL(w); + CLOVE_SIZET_EQ(RESERVED_ENTITY_ID + 1, w->entity_id_counter); + CLOVE_SIZET_EQ(0, w->alive_entities); + + destroy_world(&w); + CLOVE_NULL(w); +} + +CLOVE_TEST(pass_null_to_world_free) +{ + world* w = NULL; + destroy_world(&w); + + CLOVE_NULL(w); +} + +CLOVE_TEST(alive_entities) +{ + world* w = NULL; + make_world(&w); + + entity_id e = make_entity(w); + CLOVE_SIZET_NE(e, RESERVED_ENTITY_ID); + CLOVE_IS_TRUE(world_has_entity(w, e)); + destroy_world(&w); +} + +CLOVE_TEST(dead_entities) +{ + world* w = NULL; + make_world(&w); + + entity_id e = make_entity(w); + destroy_entity(w, e); + CLOVE_IS_FALSE(world_has_entity(w, e)); + + destroy_world(&w); } CLOVE_RUNNER() diff --git a/zecsy.h b/zecsy.h index 5fad448..aedaee5 100644 --- a/zecsy.h +++ b/zecsy.h @@ -1,8 +1,89 @@ #ifndef __ZECSY_H #define __ZECSY_H +#define STB_DS_IMPLEMENTATION +#include "stb_ds.h" +#include +#include + +#define RESERVED_ENTITY_ID 0 +typedef size_t entity_id; + +typedef struct +{ + struct{entity_id key; int value;}* entity_map; + entity_id entity_id_counter; + entity_id alive_entities; +} world; + +void make_world(world** w); +void destroy_world(world** w); + +entity_id make_entity(world* w); +void destroy_entity(world* w, entity_id e); + +int world_has_entity(world* w, entity_id e); + #endif // !__ZECSY_H +#define ZECSY_IMPLEMENTATION //TODO: REMOVE #ifdef ZECSY_IMPLEMENTATION +void make_world(world** w) +{ + if(!w) + return; + + (*w) = malloc(sizeof(world)); + + (**w) = (world) + { + .entity_map = NULL, + .entity_id_counter = RESERVED_ENTITY_ID + 1, + .alive_entities = 0, + }; +} + +void destroy_world(world** w) +{ + if(!w || !(*w)) + return; + + if((*w)->entity_map) + hmfree((*w)->entity_map); + + free((*w)); + (*w) = NULL; +} + +entity_id make_entity(world* w) +{ + entity_id e = RESERVED_ENTITY_ID; + + if(w) + { + e = w->entity_id_counter++; + hmput(w->entity_map, e, 1); + w->alive_entities++; + } + + return e; +} + +void destroy_entity(world* w, entity_id e) +{ + if(w) + hmdel(w->entity_map, e); +} + +int world_has_entity(world* w, entity_id e) +{ + if(w) + { + return hmgeti(w->entity_map, e) != -1; + } + + return 0; +} + #endif // ZECSY_IMPLEMENTATION