From 011e960cfc034588a9d36634bf702888e96cac11 Mon Sep 17 00:00:00 2001 From: Ulysse Cura Date: Fri, 24 Jul 2026 03:23:53 +0200 Subject: [PATCH] Moved ecs.c into core and added much better error and debug handling. --- .ccls | 8 +- Makefile | 6 +- NCurses_Core | 1 - SDL2_Core | 2 +- src/Makefile | 12 +- src/{ecs => }/components/animation_system.c | 10 +- .../components/headers/animation_system.h | 6 +- .../components/headers/components.def | 0 src/{ecs => }/components/headers/components.h | 0 .../components/headers/player_system.h | 0 .../components/headers/sprite_component.h | 4 +- .../components/headers/transform_component.h | 0 src/{ecs => }/components/player_system.c | 10 +- src/{ecs => }/components/sprite_component.c | 13 +- .../components/transform_component.c | 0 src/ecs/ecs.c | 163 ---------- src/ecs/headers/ecs.h | 78 ----- src/game.c | 68 +++-- src/headers/events.h | 12 - src/headers/game.h | 47 --- src/main.c | 281 ------------------ 21 files changed, 83 insertions(+), 638 deletions(-) delete mode 160000 NCurses_Core rename src/{ecs => }/components/animation_system.c (95%) rename src/{ecs => }/components/headers/animation_system.h (100%) rename src/{ecs => }/components/headers/components.def (100%) rename src/{ecs => }/components/headers/components.h (100%) rename src/{ecs => }/components/headers/player_system.h (100%) rename src/{ecs => }/components/headers/sprite_component.h (81%) rename src/{ecs => }/components/headers/transform_component.h (100%) rename src/{ecs => }/components/player_system.c (92%) rename src/{ecs => }/components/sprite_component.c (72%) rename src/{ecs => }/components/transform_component.c (100%) delete mode 100644 src/ecs/ecs.c delete mode 100644 src/ecs/headers/ecs.h delete mode 100644 src/headers/events.h delete mode 100644 src/headers/game.h delete mode 100644 src/main.c diff --git a/.ccls b/.ccls index 904a51b..421a3a6 100644 --- a/.ccls +++ b/.ccls @@ -1,9 +1,9 @@ gcc # Headers --Isrc/headers --Isrc/ecs/headers --Isrc/ecs/components/headers +-Isrc/components/headers -ISDL2_Core/src/headers #-INCurses_Core/src/headers -Iassets/asset_builder/src/headers --DASSET_FILE_NAME="$(make print-ASSET_OUTPUT)" \ No newline at end of file +# Macros +-DASSET_FILE_NAME="$(make print-ASSET_OUTPUT)" +-DDEBUG=1 diff --git a/Makefile b/Makefile index 4c41a37..ccb5c0f 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,13 @@ SHELL = /usr/bin/env bash BUILD_DIR = build # Source output target name -SOURCE_OUTPUT := $(BUILD_DIR)/2D_Engine +SOURCE_OUTPUT = $(BUILD_DIR)/2D_Engine # Core output target name -CORE_OUTPUT := $(BUILD_DIR)/libcore.a +CORE_OUTPUT = $(BUILD_DIR)/libcore.a # Assets output -ASSET_OUTPUT := $(BUILD_DIR)/game.data +ASSET_OUTPUT = $(BUILD_DIR)/game.data # Verbosity Q := @ diff --git a/NCurses_Core b/NCurses_Core deleted file mode 160000 index 911bdd7..0000000 --- a/NCurses_Core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 911bdd7999a5c8af912ea3d23ba86140541fd064 diff --git a/SDL2_Core b/SDL2_Core index d193aa5..2e1eaf4 160000 --- a/SDL2_Core +++ b/SDL2_Core @@ -1 +1 @@ -Subproject commit d193aa5fd49666be31f2b97e6dcc9a0788d58d7d +Subproject commit 2e1eaf4c1c512761c7585267175bed420154172d diff --git a/src/Makefile b/src/Makefile index 6f0ee32..21504c9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,12 +1,10 @@ # Source files SOURCES := \ - main.c \ game.c \ - ecs/ecs.c \ - ecs/components/transform_component.c \ - ecs/components/sprite_component.c \ - ecs/components/animation_system.c \ - ecs/components/player_system.c + components/transform_component.c \ + components/sprite_component.c \ + components/animation_system.c \ + components/player_system.c # Compiler and flags SRC_CC = gcc @@ -23,7 +21,7 @@ SRC_CFLAGS = --std=c17 --pedantic -O0 -g \ -Wold-style-definition # DEVELOPEMENT endif -SRC_INCLUDE_DIRS = $(SOURCE_DIR)/headers $(SOURCE_DIR)/ecs/headers $(SOURCE_DIR)/ecs/components/headers $(CORE_DIR)/headers +SRC_INCLUDE_DIRS = $(SOURCE_DIR)/components/headers $(CORE_DIR)/headers SRC_INCLUDE_DIRS := $(addprefix -I, $(SRC_INCLUDE_DIRS)) SRC_LDFLAGS = diff --git a/src/ecs/components/animation_system.c b/src/components/animation_system.c similarity index 95% rename from src/ecs/components/animation_system.c rename to src/components/animation_system.c index d16329f..3f7bcfe 100644 --- a/src/ecs/components/animation_system.c +++ b/src/components/animation_system.c @@ -1,6 +1,8 @@ -#include "memory_alloc.h" #include "animation_system.h" + #include "game.h" +#include "memory_alloc.h" +#include "errors.h" // Args : size_t nb_frames, size_t actual_frame, float frame_delay_ms, bool play, bool loop, bool reverse void animation_system_init(component_t *component, va_list args) @@ -8,6 +10,7 @@ void animation_system_init(component_t *component, va_list args) animation_system_data_t *system_data = component->component_data; system_data->sprite_component_data = get_component(component->entity, SPRITE_COMPONENT)->component_data; + if(!system_data->sprite_component_data) return; system_data->nb_frames = va_arg(args, size_t); system_data->actual_frame_nb= va_arg(args, size_t); @@ -106,9 +109,10 @@ void animation_system_create_frames_clips(animation_system_data_t *system_data) inline void animation_system_change_animation(animation_system_data_t *system_data, const char *name, size_t nb_frames) { - sprite_component_set_texture(system_data->sprite_component_data, name); - system_data->sprite_component_data->src_rect = *(rect_t *)system_data->actual_frame->data; + system_data->sprite_component_data->texture = asset_manager_get_texture(&game.asset_manager, name); system_data->nb_frames = nb_frames; animation_system_create_frames_clips(system_data); + + system_data->sprite_component_data->src_rect = *(rect_t *)system_data->actual_frame->data; } diff --git a/src/ecs/components/headers/animation_system.h b/src/components/headers/animation_system.h similarity index 100% rename from src/ecs/components/headers/animation_system.h rename to src/components/headers/animation_system.h index 49a321a..2ac687c 100644 --- a/src/ecs/components/headers/animation_system.h +++ b/src/components/headers/animation_system.h @@ -7,12 +7,12 @@ typedef struct animation_system_data_t { sprite_component_data_t *sprite_component_data; - elem_t *actual_frame; - size_t actual_frame_nb; - size_t nb_frames; linked_list_t frames; + elem_t *actual_frame; + size_t actual_frame_nb; + float frame_delay_ms; float frame_timer_ms; diff --git a/src/ecs/components/headers/components.def b/src/components/headers/components.def similarity index 100% rename from src/ecs/components/headers/components.def rename to src/components/headers/components.def diff --git a/src/ecs/components/headers/components.h b/src/components/headers/components.h similarity index 100% rename from src/ecs/components/headers/components.h rename to src/components/headers/components.h diff --git a/src/ecs/components/headers/player_system.h b/src/components/headers/player_system.h similarity index 100% rename from src/ecs/components/headers/player_system.h rename to src/components/headers/player_system.h diff --git a/src/ecs/components/headers/sprite_component.h b/src/components/headers/sprite_component.h similarity index 81% rename from src/ecs/components/headers/sprite_component.h rename to src/components/headers/sprite_component.h index cee6ed4..719b362 100644 --- a/src/ecs/components/headers/sprite_component.h +++ b/src/components/headers/sprite_component.h @@ -20,10 +20,8 @@ void sprite_component_init(component_t *, va_list); void sprite_component_update(component_t *); -void sprite_component_draw(component_t *); +int sprite_component_draw(component_t *); void sprite_component_destroy(component_t *); -void sprite_component_set_texture(sprite_component_data_t *, const char *); - #endif // SPRITE_COMPONENT_H \ No newline at end of file diff --git a/src/ecs/components/headers/transform_component.h b/src/components/headers/transform_component.h similarity index 100% rename from src/ecs/components/headers/transform_component.h rename to src/components/headers/transform_component.h diff --git a/src/ecs/components/player_system.c b/src/components/player_system.c similarity index 92% rename from src/ecs/components/player_system.c rename to src/components/player_system.c index 10f73c3..f87bd02 100644 --- a/src/ecs/components/player_system.c +++ b/src/components/player_system.c @@ -1,9 +1,10 @@ -#include "memory_alloc.h" #include "player_system.h" + +#include "game.h" +#include "memory_alloc.h" #include "animation_system.h" #include "sprite_component.h" #include "transform_component.h" -#include "game.h" // No args void player_system_init(component_t *component, va_list args __attribute__((unused))) @@ -15,9 +16,6 @@ void player_system_init(component_t *component, va_list args __attribute__((unus system_data->transform_component_data = system_data->sprite_component_data->transform_component_data; system_data->state = PLAYER_IDLE; - - asset_manager_load_asset(&game.asset_manager, "player_idle_sheet", ASSET_TEXTURE); - asset_manager_load_asset(&game.asset_manager, "player_walk_sheet", ASSET_TEXTURE); } // Only for this file @@ -87,7 +85,5 @@ void player_system_update(component_t *component) void player_system_destroy(component_t *component) { - asset_manager_let_go_asset(&game.asset_manager, "player_idle_sheet"); - asset_manager_let_go_asset(&game.asset_manager, "player_walk_sheet"); free(component->component_data); } diff --git a/src/ecs/components/sprite_component.c b/src/components/sprite_component.c similarity index 72% rename from src/ecs/components/sprite_component.c rename to src/components/sprite_component.c index a58057d..2c4f3a1 100644 --- a/src/ecs/components/sprite_component.c +++ b/src/components/sprite_component.c @@ -15,7 +15,7 @@ void sprite_component_init(component_t *component, va_list args) component_data->flip = false; - sprite_component_set_texture(component_data, va_arg(args, const char *)); + component_data->texture = asset_manager_get_texture(&game.asset_manager, va_arg(args, const char *)); } inline void sprite_component_update(component_t *component) @@ -24,18 +24,15 @@ inline void sprite_component_update(component_t *component) frect_to_rect(&component_data->transform_component_data->bounds, &component_data->dst_rect); } -inline void sprite_component_draw(component_t *component) +inline int sprite_component_draw(component_t *component) { sprite_component_data_t *component_data = component->component_data; - asset_manager_draw_texture(component_data->texture, &component_data->src_rect, &component_data->dst_rect, component_data->flip); + if(asset_manager_draw_texture(component_data->texture, &component_data->src_rect, &component_data->dst_rect, component_data->flip)) return EXIT_FAILURE; + + return EXIT_SUCCESS; } inline void sprite_component_destroy(component_t *component) { free(component->component_data); } - -inline void sprite_component_set_texture(sprite_component_data_t *component_data, const char *name) -{ - component_data->texture = asset_manager_get_texture(&game.asset_manager, name); -} diff --git a/src/ecs/components/transform_component.c b/src/components/transform_component.c similarity index 100% rename from src/ecs/components/transform_component.c rename to src/components/transform_component.c diff --git a/src/ecs/ecs.c b/src/ecs/ecs.c deleted file mode 100644 index e0e60c8..0000000 --- a/src/ecs/ecs.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include "memory_alloc.h" -#include "ecs.h" -#include "components.h" - -component_t *create_component(component_type_t component_type) -{ - component_t *component = malloc(sizeof(component_t)); - component->component_type = component_type; - - switch(component_type) - { -#define COMPONENT(NAME, PREFIX, DRAW) \ - case NAME: \ - component->component_init = PREFIX##_init; \ - component->component_update = PREFIX##_update; \ - component->component_draw = DRAW(PREFIX); \ - component->component_data = malloc(sizeof(PREFIX##_data_t)); \ - if(!component->component_data){ free(component); return NULL; } \ - component->component_deleter = PREFIX##_destroy; \ - break; -#include "components.def" - - default: - free(component); - return NULL; - } - - return component; -} - -inline void destroy_component(component_t *component) -{ - component->component_deleter(component); - free(component); -} - -entity_t *create_entity(const unsigned int id) -{ - entity_t *entity = malloc(sizeof(entity_t)); - if(!entity) return NULL; - - entity->id = id; - entity->draw_priority = 0; - - linked_list_init(&entity->components, sizeof(component_t), (deleter_t)destroy_component); - - return entity; -} - -void add_component(entity_t *entity, component_t *component, ...) -{ - if(!component) return; - - component->entity = entity; - - va_list args, args_copy; - - va_start(args, component); - va_copy(args_copy, args); - - component->component_init(component, args_copy); - - va_end(args_copy); - va_end(args); - - linked_list_push_back(&entity->components, component); -} - -// Only for this file -// Arg : component_type_t component_type -static inline bool condition_is_component_type(elem_t *elem, va_list args) -{ - return ((component_t *)elem->data)->component_type == va_arg(args, component_type_t); -} - -inline component_t *get_component(entity_t *entity, component_type_t component_type) -{ - return linked_list_get_if(&entity->components, condition_is_component_type, component_type); -} - -// Only for this file -// No args -static inline void action_update_component(elem_t *elem, va_list args __attribute__((unused))) -{ - component_t *component = elem->data; - component->component_update(component); -} - -inline void update_entity(entity_t *entity) -{ - linked_list_for_each(&entity->components, action_update_component); -} - -// Only for this file -// No args -static inline void action_draw_component(elem_t *elem, va_list args __attribute__((unused))) -{ - component_t *component = elem->data; - if(component->component_draw) component->component_draw(component); -} - -inline void draw_entity(entity_t *entity) -{ - linked_list_for_each(&entity->components, action_draw_component); -} - -inline void destroy_entity(entity_t *entity) -{ - linked_list_clear(&entity->components); - free(entity); -} - -inline void entity_manager_init(entity_manager_t *entity_manager) -{ - linked_list_init(&entity_manager->entities, sizeof(entity_t), (deleter_t)destroy_entity); -} - -inline void entity_manager_add_entity(entity_manager_t *entity_manager, entity_t *entity) -{ - linked_list_push_back(&entity_manager->entities, entity); -} - -// Only for this file -// No args -static inline void action_update_entity(elem_t *elem, va_list args __attribute__((unused))) -{ - update_entity((entity_t *)elem->data); -} - -inline void entity_manager_update(entity_manager_t *entity_manager) -{ - linked_list_for_each(&entity_manager->entities, action_update_entity); -} - -// Only for this file -// No args -static inline void action_draw_entity(elem_t *elem, va_list args __attribute__((unused))) -{ - draw_entity((entity_t *)elem->data); -} - -inline void entity_manager_draw(entity_manager_t *entity_manager) -{ - linked_list_for_each(&entity_manager->entities, action_draw_entity); -} - -// Only for this file -// Arg : unsigned int id -static inline bool condition_is_entity_name(elem_t *elem, va_list args) -{ - return ((entity_t *)elem->data)->id == va_arg(args, unsigned int); -} - -inline void entity_manager_remove_entity(entity_manager_t *entity_manager, unsigned int id) -{ - linked_list_remove_if(&entity_manager->entities, condition_is_entity_name, id); -} - -inline void entity_manager_exit(entity_manager_t *entity_manager) -{ - linked_list_clear(&entity_manager->entities); -} diff --git a/src/ecs/headers/ecs.h b/src/ecs/headers/ecs.h deleted file mode 100644 index af4bd9d..0000000 --- a/src/ecs/headers/ecs.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef ECS_H -#define ECS_H - -#include -#include -#include "linked_list.h" - -typedef enum component_type_t { -#define COMPONENT(NAME, PREFIX, DRAW) NAME, -#include "components.def" -} component_type_t; - -// Component forwarding -typedef struct component_t component_t; - -// Component init function. It is called when component added to entity. This function is necessary. -typedef void (*component_init_t)(component_t *component, va_list args); -// Component update function. It is called in the main loop to update the component. This function is necessary. -typedef void (*component_update_t)(component_t *component); -// Component draw function. It is called in the main loop to draw the component on screen. This function is not necessary. -typedef void (*component_draw_t)(component_t *component); -// Component deleter function. It is called when the component is removed. It should free the data in the component data but not the component itself. -typedef void (*component_deleter_t)(component_t *component); - -typedef struct component_t { - component_init_t component_init; - component_update_t component_update; - component_draw_t component_draw; - - void *component_data; - - component_deleter_t component_deleter; - - struct entity_t *entity; - - component_type_t component_type; - -} component_t; - -component_t *create_component(component_type_t component_type); - -void destroy_component(component_t *component); - -typedef struct entity_t { - unsigned int id; - size_t draw_priority; - linked_list_t components; -} entity_t; - -entity_t *create_entity(const unsigned int id); - -void add_component(entity_t *entity, component_t *component, ...); - -component_t *get_component(entity_t *entity, component_type_t component_type); - -void update_entity(entity_t *entity); - -void draw_entity(entity_t *entity); - -void destroy_entity(entity_t *entity); - -typedef struct entity_manager_t { - linked_list_t entities; -} entity_manager_t; - -void entity_manager_init(entity_manager_t *entity_manager); - -void entity_manager_add_entity(entity_manager_t *entity_manager, entity_t *entity); - -void entity_manager_update(entity_manager_t *entity_manager); - -void entity_manager_draw(entity_manager_t *entity_manager); - -void entity_manager_remove_entity(entity_manager_t *entity_manager, const unsigned int id); - -void entity_manager_exit(entity_manager_t *entity_manager); - -#endif // ECS_H \ No newline at end of file diff --git a/src/game.c b/src/game.c index 86b9c07..0c8fef9 100644 --- a/src/game.c +++ b/src/game.c @@ -1,15 +1,20 @@ -#include -#include -#include -#include #include "game.h" + +#include +#include "display.h" +#include "asset_manager.h" +#include "ecs.h" #include "components.h" -void game_init(void) -{ - display_init(); +#include - asset_manager_init(&game.asset_manager); +int game_init(void) +{ + game.is_running = false; + + if(display_init()) return EXIT_FAILURE; + + if(asset_manager_init(&game.asset_manager)) return EXIT_FAILURE; entity_manager_init(&game.entity_manager); entity_t *player = create_entity(0); @@ -18,12 +23,24 @@ void game_init(void) frect_t player_bounds = {10.0f, 10.0f, 32.0f, 32.0f}; - add_component(player, create_component(TRANSFORM_COMPONENT), player_bounds, PLAYER_DEFAULT_SPEED); - add_component(player, create_component(SPRITE_COMPONENT), "player_idle_sheet"); - add_component(player, create_component(ANIMATION_SYSTEM), 4, 0, PLAYER_DEFAULT_IDLE_ANIMATION_SPEED, true, true, false); - add_component(player, create_component(PLAYER_SYSTEM)); + if(asset_manager_load_asset(&game.asset_manager, "player_idle_sheet", ASSET_TEXTURE)) return EXIT_FAILURE; + if(asset_manager_load_asset(&game.asset_manager, "player_walk_sheet", ASSET_TEXTURE)) return EXIT_FAILURE; + + component_t *component = create_component(TRANSFORM_COMPONENT); if(!component) return EXIT_FAILURE; + add_component(player, component, player_bounds, PLAYER_DEFAULT_SPEED); + + component = create_component(SPRITE_COMPONENT); if(!component) return EXIT_FAILURE; + add_component(player, component, "player_idle_sheet"); + + component = create_component(ANIMATION_SYSTEM); if(!component) return EXIT_FAILURE; + add_component(player, component, 4, 0, PLAYER_DEFAULT_IDLE_ANIMATION_SPEED, true, true, false); + + component = create_component(PLAYER_SYSTEM); if(!component) return EXIT_FAILURE; + add_component(player, component); game.is_running = true; + + return EXIT_SUCCESS; } void game_handle_event(void) @@ -57,19 +74,36 @@ void game_update(void) entity_manager_update(&game.entity_manager); } -void game_render(void) +int game_render(void) { - display_clear(); + if(display_clear()) + { + game.is_running = false; + return EXIT_FAILURE; + } + + if(entity_manager_draw(&game.entity_manager)) + { + game.is_running = false; + return EXIT_FAILURE; + } - entity_manager_draw(&game.entity_manager); display_update(); + + return EXIT_SUCCESS; } -void game_exit(void) +int game_exit(void) { entity_manager_exit(&game.entity_manager); - asset_manager_exit(&game.asset_manager); + + if(asset_manager_let_go_asset(&game.asset_manager, "player_idle_sheet")) return EXIT_FAILURE; + if(asset_manager_let_go_asset(&game.asset_manager, "player_walk_sheet")) return EXIT_FAILURE; + + if(asset_manager_exit(&game.asset_manager)) return EXIT_FAILURE; display_exit(); + + return EXIT_SUCCESS; } diff --git a/src/headers/events.h b/src/headers/events.h deleted file mode 100644 index fe24616..0000000 --- a/src/headers/events.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef EVENTS_H -#define EVENTS_H - -#include -#include - -typedef struct events_t { - vector2d_t cursor_pos; - bool keys[MAX_KEYCODES]; -} events_t; - -#endif // EVENTS_H \ No newline at end of file diff --git a/src/headers/game.h b/src/headers/game.h deleted file mode 100644 index f2304a4..0000000 --- a/src/headers/game.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef GAME_H -#define GAME_H - -#include - -#include "events.h" -#include "asset_manager.h" -#include "ecs.h" - -/** - * @brief Game data. - * There should be only one instance of this struct. - * - * @param event Events data - * @param texture_manager Texture manager instance - * @param entity_manager Entity manager instance - * @param is_running Game running state - * @param delta_time_ms Frame time -*/ -typedef struct game_t { - asset_manager_t asset_manager; - entity_manager_t entity_manager; - events_t events; - - float delta_time_ms; - bool is_running; -} game_t; - -// Global game instance -extern game_t game; - -// Initialise game -void game_init(void); - -// Handle event like inputs -void game_handle_event(void); - -// Update game -void game_update(void); - -// Render game -void game_render(void); - -// Free game instance -void game_exit(void); - -#endif // GAME_H \ No newline at end of file diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 8efbc40..0000000 --- a/src/main.c +++ /dev/null @@ -1,281 +0,0 @@ -#include "game.h" - -//#define TEXTURE_TEST -//#define LINKED_LIST_TEST - -game_t game; - -int main(void) -{ - game_init(); - - while(game.is_running) - { - game_handle_event(); - game_update(); - game_render(); - } - - game_exit(); - - return 0; -} - - -// Texture Unit Tests -#ifdef TEXTURE_TEST - -#include "texture_manager.h" - -int main(void) -{ - display_clear(C_BLACK); - - texture_manager_t texture_manager; - texture_manager_init(&texture_manager); - texture_manager_load_builtin_textures(&texture_manager); - - texture_t *texture = texture_manager_get_texture(&texture_manager, "player_run_sheet"); - - rect_t srcR = {0,0,32,32}; - rect_t dstR = srcR; - - draw_texture(texture, &src, &dst); - - src.x = 33; - dst.x = 33; - - draw_texture(texture, &src, &dst); - - texture_manager_remove_texture(&texture_manager, "player_run_sheet"); - - src.w = 128; - dst.x = 0; - dst.y = 33; - - texture_manager_draw_texture(&texture_manager, "player_idle_sheet", &src, &dst); - - texture_manager_clear(&texture_manager); - - display_update(); - getkey(); - - return 1; -} - -#endif // TEXTURE_TEST - -// Linked List Unit Tests -#ifdef LINKED_LIST_TEST - -#include "linked_list.h" - -int main(void) -{ - display_clear(C_BLACK); - - linked_list_t linked_list; - linked_list_init(&linked_list, sizeof(int), NULL); - if(linked_list.first == linked_list.last && - linked_list.first == NULL) - { - dtext(1, 0, C_BLACK, "linked_list is initialised correctly"); - } - else - { - goto Exit; - } - - elem_t *elem1 = NULL; - elem_t *elem2 = NULL; - elem_t *elem3 = NULL; - elem_t *elem4 = NULL; - - elem1 = elem_create(&linked_list); - if(elem1 && elem1->data) - { - dtext(1, 10, C_BLACK, "elem1 is initalised correctly"); - } - else - { - goto Exit; - } - - linked_list_push_back_elem(&linked_list, elem1); - if(linked_list.first == linked_list.last && - linked_list.first == elem1 && - !linked_list.first->prev && - !linked_list.first->next && - !linked_list.last->prev && - !linked_list.last->next) - { - dtext(1, 20, C_BLACK, "elem1 is correctly pushed back"); - } - else - { - goto Exit; - } - - linked_list_pop_back(&linked_list); - if(linked_list.first == linked_list.last && - linked_list.first == NULL) - { - dtext(1, 30, C_BLACK, "elem1 is correctly poped back"); - } - else - { - goto Exit; - } - - elem1 = elem_create(&linked_list); - elem2 = elem_create(&linked_list); - elem3 = elem_create(&linked_list); - elem4 = elem_create(&linked_list); - - linked_list_push_back_elem(&linked_list, elem1); - linked_list_push_back_elem(&linked_list, elem2); - if(linked_list.first == elem1 && - linked_list.last == elem2 && - !linked_list.first->prev && - linked_list.first->next && - linked_list.last->prev && - !linked_list.last->next && - linked_list.first->next == elem2 && - linked_list.last->prev == elem1) - { - dtext(1, 40, C_BLACK, "elem1 and elem2 are correctly pushed back"); - } - else - { - goto Exit; - } - - linked_list_push_front_elem(&linked_list, elem3); - linked_list_push_front_elem(&linked_list, elem4); - if(!linked_list.first->prev && - !linked_list.last->next && - linked_list.first == elem4 && - linked_list.first->next == elem3 && - linked_list.first->next->next == elem1 && - linked_list.first->next->next->next == elem2 && - linked_list.last == elem2 && - linked_list.last->prev == elem1 && - linked_list.last->prev->prev == elem3 && - linked_list.last->prev->prev->prev == elem4) - { - dtext(1, 50, C_BLACK, "elem3 and elem4 are correctly pushed front"); - } - else - { - goto Exit; - } - - if(linked_list_get_elem(&linked_list, 2) == elem1) - { - dtext(1, 60, C_BLACK, "elem4 is got correctly"); - } - else - { - goto Exit; - } - - linked_list_pop_back(&linked_list); - if(!linked_list.first->prev && - !linked_list.last->next && - linked_list.first == elem4 && - linked_list.first->next == elem3 && - linked_list.first->next->next == elem1 && - linked_list.last == elem1 && - linked_list.last->prev == elem3 && - linked_list.last->prev->prev == elem4) - { - dtext(1, 70, C_BLACK, "elem2 is correctly poped back"); - } - else - { - goto Exit; - } - - linked_list_remove(&linked_list, 1); - if(!linked_list.first->prev && - !linked_list.last->next && - linked_list.first == elem4 && - linked_list.first->next == elem1 && - linked_list.last == elem1 && - linked_list.last->prev == elem4) - { - dtext(1, 80, C_BLACK, "elem3 is correctly removed"); - } - else - { - goto Exit; - } - - linked_list_clear(&linked_list); - if(linked_list.first == linked_list.last && - linked_list.first == NULL) - { - dtext(1, 90, C_BLACK, "linked list is correctly cleared"); - } - else - { - goto Exit; - } - - elem1 = elem_create(&linked_list); - elem2 = elem_create(&linked_list); - elem3 = elem_create(&linked_list); - elem4 = elem_create(&linked_list); - - linked_list_push_back_elem(&linked_list, elem1); - linked_list_push_back_elem(&linked_list, elem2); - linked_list_push_front_elem(&linked_list, elem3); - if(linked_list.first == elem3 && - linked_list.last == elem2 && - !linked_list.first->prev && - linked_list.first->next && - linked_list.last->prev && - !linked_list.last->next && - linked_list.first->next == elem1 && - linked_list.first->next->next == elem2 && - linked_list.last->prev == elem1 && - linked_list.last->prev->prev == elem3) - { - dtext(1, 100, C_BLACK, "elem1, elem2 and elem3 are correctly pushed"); - } - else - { - goto Exit; - } - - linked_list_insert_elem(&linked_list, elem4, 1); - if(linked_list.first == elem3 && - linked_list.last == elem2 && - !linked_list.first->prev && - linked_list.first->next && - linked_list.last->prev && - !linked_list.last->next && - linked_list.first->next == elem4 && - linked_list.first->next->next == elem1 && - linked_list.first->next->next->next == elem2 && - linked_list.last->prev == elem1 && - linked_list.last->prev->prev == elem4 && - linked_list.last->prev->prev->prev == elem3) - { - dtext(1, 110, C_BLACK, "elem3 is correctly inserted"); - } - else - { - goto Exit; - } - - linked_list_clear(&linked_list); - - Exit: - display_update(); - getkey(); - - return 1; -} - -#endif // LINKED_LIST_TEST