Mercurial > molko
changeset 311:f10fd1293a7e
core: fix states + tests
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 09 Sep 2021 13:57:54 +0200 |
parents | b271a0e8ce52 |
children | 4ea0f035f712 |
files | GNUmakefile libmlk-core/core/game.c libmlk-core/core/game.h tests/test-state.c |
diffstat | 4 files changed, 161 insertions(+), 140 deletions(-) [+] |
line wrap: on
line diff
--- a/GNUmakefile Mon Sep 06 09:56:59 2021 +0200 +++ b/GNUmakefile Thu Sep 09 13:57:54 2021 +0200 @@ -385,7 +385,7 @@ ${LIBMLK_CORE_OBJS}: config.h ${LIBMLK_CORE}: INCS += ${SDL2_INCS} -${LIBMLK_CORE}: ${LIBMLK_CORE_OBJS} ${LIBMLK_CORE_MO} +${LIBMLK_CORE}: ${LIBMLK_SQLITE} ${LIBMLK_CORE_OBJS} ${LIBMLK_CORE_MO} ${CMD.ar} libmlk-core-pot: @@ -398,7 +398,7 @@ ${LIBMLK_UI_ASTS}: ${MLK_BCC} ${LIBMLK_UI_OBJS}: ${LIBMLK_UI_ASTS} config.h -${LIBMLK_UI}: ${LIBMLK_UI_OBJS} ${LIBMLK_UI_MO} +${LIBMLK_UI}: ${LIBMLK_CORE} ${LIBMLK_UI_OBJS} ${LIBMLK_UI_MO} ${CMD.ar} libmlk-ui-pot: @@ -411,7 +411,7 @@ ${LIBMLK_RPG_ASTS}: ${MLK_BCC} ${LIBMLK_RPG_OBJS}: ${LIBMLK_RPG_ASTS} config.h -${LIBMLK_RPG}: ${LIBMLK_RPG_OBJS} ${LIBMLK_RPG_MO} +${LIBMLK_RPG}: ${LIBMLK_UI} ${LIBMLK_RPG_OBJS} ${LIBMLK_RPG_MO} ${CMD.ar} libmlk-rpg-pot: @@ -424,7 +424,7 @@ ${LIBMLK_ADVENTURE_ASTS}: ${MLK_BCC} ${LIBMLK_ADVENTURE_OBJS}: ${LIBMLK_ADVENTURE_ASTS} config.h -${LIBMLK_ADVENTURE}: ${LIBMLK_ADVENTURE_OBJS} ${LIBMLK_ADVENTURE_MO} +${LIBMLK_ADVENTURE}: ${LIBMLK_RPG} ${LIBMLK_ADVENTURE_OBJS} ${LIBMLK_ADVENTURE_MO} ${CMD.ar} libmlk-adventure-pot:
--- a/libmlk-core/core/game.c Mon Sep 06 09:56:59 2021 +0200 +++ b/libmlk-core/core/game.c Thu Sep 09 13:57:54 2021 +0200 @@ -33,6 +33,14 @@ }; void +game_init(void) +{ + memset(&game, 0, sizeof (game)); + + game.state = &game.states[0]; +} + +void game_push(struct state *state) { assert(state); @@ -54,6 +62,8 @@ state_end(*game.state); state_finish(*game.state); + *game.state = NULL; + if (game.state != &game.states[0]) state_resume(*--game.state); } @@ -117,9 +127,10 @@ void game_quit(void) { - for (size_t i = 0; i < UTIL_SIZE(game.states); ++i) + for (size_t i = 0; i < UTIL_SIZE(game.states); ++i) { if (game.states[i]) state_finish(game.states[i]); - *game.state = NULL; + game.states[i] = NULL; + } }
--- a/libmlk-core/core/game.h Mon Sep 06 09:56:59 2021 +0200 +++ b/libmlk-core/core/game.h Thu Sep 09 13:57:54 2021 +0200 @@ -39,6 +39,9 @@ CORE_BEGIN_DECLS void +game_init(void); + +void game_push(struct state *); void
--- a/tests/test-state.c Mon Sep 06 09:56:59 2021 +0200 +++ b/tests/test-state.c Thu Sep 09 13:57:54 2021 +0200 @@ -30,6 +30,8 @@ unsigned int handle; unsigned int update; unsigned int draw; + unsigned int suspend; + unsigned int resume; unsigned int end; unsigned int finish; }; @@ -41,6 +43,18 @@ } static void +setup(void *data) +{ + game_init(); +} + +static void +cleanup(void *data) +{ + game_quit(); +} + +static void my_start(struct state *state) { ((struct invokes *)state->data)->start++; @@ -69,6 +83,18 @@ } static void +my_suspend(struct state *state) +{ + ((struct invokes *)state->data)->suspend++; +} + +static void +my_resume(struct state *state) +{ + ((struct invokes *)state->data)->resume++; +} + +static void my_end(struct state *state) { ((struct invokes *)state->data)->end++; @@ -86,6 +112,8 @@ .handle = my_handle, \ .update = my_update, \ .draw = my_draw, \ + .suspend = my_suspend, \ + .resume = my_resume, \ .end = my_end, \ .finish = my_finish \ } @@ -202,158 +230,137 @@ GREATEST_RUN_TEST(basics_finish); } -static void -switch_startup(void *data) +GREATEST_TEST +test_game_push(void) { - memset(data, 0, sizeof (game)); -} - -GREATEST_TEST -switch_quick_1(void) -{ - struct { + static struct { struct invokes inv; struct state state; - } table[2] = { - { .state = INIT(&table[0]) }, - { .state = INIT(&table[1]) } - }; - - /* - * When set to 1, switching quickly state will immediately set the - * current state to the specified one and call start on it. However, - * if there was already a planned state, it is finished immediately. - */ - game_push(&table[0].state); - - GREATEST_ASSERT_EQ(table[0].inv.start, 1); - GREATEST_ASSERT_EQ(table[0].inv.handle, 0); - GREATEST_ASSERT_EQ(table[0].inv.update, 0); - GREATEST_ASSERT_EQ(table[0].inv.draw, 0); - GREATEST_ASSERT_EQ(table[0].inv.end, 0); - GREATEST_ASSERT_EQ(table[0].inv.finish, 0); - - GREATEST_ASSERT_EQ(table[1].inv.start, 0); - GREATEST_ASSERT_EQ(table[1].inv.handle, 0); - GREATEST_ASSERT_EQ(table[1].inv.update, 0); - GREATEST_ASSERT_EQ(table[1].inv.draw, 0); - GREATEST_ASSERT_EQ(table[1].inv.end, 0); - GREATEST_ASSERT_EQ(table[1].inv.finish, 0); - - /* Switch from [0] to [1] quickly, [0] should be closed immediately. */ - zero(&table[0].inv); - game_push(&table[1].state); - - GREATEST_ASSERT_EQ(table[0].inv.start, 0); - GREATEST_ASSERT_EQ(table[0].inv.handle, 0); - GREATEST_ASSERT_EQ(table[0].inv.update, 0); - GREATEST_ASSERT_EQ(table[0].inv.draw, 0); - GREATEST_ASSERT_EQ(table[0].inv.end, 1); - GREATEST_ASSERT_EQ(table[0].inv.finish, 1); - - GREATEST_ASSERT_EQ(table[1].inv.start, 1); - GREATEST_ASSERT_EQ(table[1].inv.handle, 0); - GREATEST_ASSERT_EQ(table[1].inv.update, 0); - GREATEST_ASSERT_EQ(table[1].inv.draw, 0); - GREATEST_ASSERT_EQ(table[1].inv.end, 0); - GREATEST_ASSERT_EQ(table[1].inv.finish, 0); - - GREATEST_PASS(); -} - -GREATEST_TEST -switch_quick_0(void) -{ - struct { - struct invokes inv; - struct state state; - } table[2] = { - { .state = INIT(&table[0]) }, - { .state = INIT(&table[1]) } + } states[] = { + { .state = INIT(&states[0].inv) }, + { .state = INIT(&states[1].inv) } }; - game_push(&table[0].state); - - GREATEST_ASSERT_EQ(table[0].inv.start, 1); - GREATEST_ASSERT_EQ(table[0].inv.handle, 0); - GREATEST_ASSERT_EQ(table[0].inv.update, 0); - GREATEST_ASSERT_EQ(table[0].inv.draw, 0); - GREATEST_ASSERT_EQ(table[0].inv.end, 0); - GREATEST_ASSERT_EQ(table[0].inv.finish, 0); + /* 0 becomes active and should start. */ + game_push(&states[0].state); + GREATEST_ASSERT_EQ(states[0].inv.start, 1U); + GREATEST_ASSERT_EQ(states[0].inv.handle, 0U); + GREATEST_ASSERT_EQ(states[0].inv.update, 0U); + GREATEST_ASSERT_EQ(states[0].inv.draw, 0U); + GREATEST_ASSERT_EQ(states[0].inv.suspend, 0U); + GREATEST_ASSERT_EQ(states[0].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[0].inv.end, 0U); + GREATEST_ASSERT_EQ(states[0].inv.finish, 0U); - GREATEST_ASSERT_EQ(table[1].inv.start, 0); - GREATEST_ASSERT_EQ(table[1].inv.handle, 0); - GREATEST_ASSERT_EQ(table[1].inv.update, 0); - GREATEST_ASSERT_EQ(table[1].inv.draw, 0); - GREATEST_ASSERT_EQ(table[1].inv.end, 0); - GREATEST_ASSERT_EQ(table[1].inv.finish, 0); + /* Put some event, update and drawing. */ + game_handle(&(union event) { .type = EVENT_QUIT }); + game_update(100); + game_update(100); + game_draw(); + game_draw(); + game_draw(); + GREATEST_ASSERT_EQ(states[0].inv.start, 1U); + GREATEST_ASSERT_EQ(states[0].inv.handle, 1U); + GREATEST_ASSERT_EQ(states[0].inv.update, 2U); + GREATEST_ASSERT_EQ(states[0].inv.draw, 3U); + GREATEST_ASSERT_EQ(states[0].inv.suspend, 0U); + GREATEST_ASSERT_EQ(states[0].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[0].inv.end, 0U); + GREATEST_ASSERT_EQ(states[0].inv.finish, 0U); - /* - * Switch from [0] to [1] quickly, this should do nothing as it should - * be done on the next game_update call instead. - */ - zero(&table[0].inv); - game_push(&table[1].state); + /* Switch to state 1, 0 must be suspended. */ + game_push(&states[1].state); + GREATEST_ASSERT_EQ(states[0].inv.start, 1U); + GREATEST_ASSERT_EQ(states[0].inv.handle, 1U); + GREATEST_ASSERT_EQ(states[0].inv.update, 2U); + GREATEST_ASSERT_EQ(states[0].inv.draw, 3U); + GREATEST_ASSERT_EQ(states[0].inv.suspend, 1U); + GREATEST_ASSERT_EQ(states[0].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[0].inv.end, 0U); + GREATEST_ASSERT_EQ(states[0].inv.finish, 0U); - GREATEST_ASSERT_EQ(table[0].inv.start, 0); - GREATEST_ASSERT_EQ(table[0].inv.handle, 0); - GREATEST_ASSERT_EQ(table[0].inv.update, 0); - GREATEST_ASSERT_EQ(table[0].inv.draw, 0); - GREATEST_ASSERT_EQ(table[0].inv.end, 0); - GREATEST_ASSERT_EQ(table[0].inv.finish, 0); + GREATEST_ASSERT_EQ(states[1].inv.start, 1U); + GREATEST_ASSERT_EQ(states[1].inv.handle, 0U); + GREATEST_ASSERT_EQ(states[1].inv.update, 0U); + GREATEST_ASSERT_EQ(states[1].inv.draw, 0U); + GREATEST_ASSERT_EQ(states[1].inv.suspend, 0U); + GREATEST_ASSERT_EQ(states[1].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[1].inv.end, 0U); + GREATEST_ASSERT_EQ(states[1].inv.finish, 0U); - GREATEST_ASSERT_EQ(table[1].inv.start, 0); - GREATEST_ASSERT_EQ(table[1].inv.handle, 0); - GREATEST_ASSERT_EQ(table[1].inv.update, 0); - GREATEST_ASSERT_EQ(table[1].inv.draw, 0); - GREATEST_ASSERT_EQ(table[1].inv.end, 0); - GREATEST_ASSERT_EQ(table[1].inv.finish, 0); - - GREATEST_PASS(); -} + /* Update a little this state. */ + game_update(10); + game_update(10); + game_update(10); + game_update(10); + GREATEST_ASSERT_EQ(states[0].inv.start, 1U); + GREATEST_ASSERT_EQ(states[0].inv.handle, 1U); + GREATEST_ASSERT_EQ(states[0].inv.update, 2U); + GREATEST_ASSERT_EQ(states[0].inv.draw, 3U); + GREATEST_ASSERT_EQ(states[0].inv.suspend, 1U); + GREATEST_ASSERT_EQ(states[0].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[0].inv.end, 0U); + GREATEST_ASSERT_EQ(states[0].inv.finish, 0U); -GREATEST_TEST -switch_invoke(void) -{ - struct { - struct invokes inv; - struct state state; - } table[2] = { - { .state = INIT(&table[0]) }, - { .state = INIT(&table[1]) } - }; + GREATEST_ASSERT_EQ(states[1].inv.start, 1U); + GREATEST_ASSERT_EQ(states[1].inv.handle, 0U); + GREATEST_ASSERT_EQ(states[1].inv.update, 4U); + GREATEST_ASSERT_EQ(states[1].inv.draw, 0U); + GREATEST_ASSERT_EQ(states[1].inv.suspend, 0U); + GREATEST_ASSERT_EQ(states[1].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[1].inv.end, 0U); + GREATEST_ASSERT_EQ(states[1].inv.finish, 0U); + + /* Pop it, it should be finalized through end and finish. */ + game_pop(); - /* Start with 0. */ - game_push(&table[0].state); + GREATEST_ASSERT_EQ(states[0].inv.start, 1U); + GREATEST_ASSERT_EQ(states[0].inv.handle, 1U); + GREATEST_ASSERT_EQ(states[0].inv.update, 2U); + GREATEST_ASSERT_EQ(states[0].inv.draw, 3U); + GREATEST_ASSERT_EQ(states[0].inv.suspend, 1U); + GREATEST_ASSERT_EQ(states[0].inv.resume, 1U); + GREATEST_ASSERT_EQ(states[0].inv.end, 0U); + GREATEST_ASSERT_EQ(states[0].inv.finish, 0U); - /* Ask to switch to 1. */ - zero(&table[0].inv); - game_push(&table[1].state); - game_update(0); + GREATEST_ASSERT_EQ(states[1].inv.start, 1U); + GREATEST_ASSERT_EQ(states[1].inv.handle, 0U); + GREATEST_ASSERT_EQ(states[1].inv.update, 4U); + GREATEST_ASSERT_EQ(states[1].inv.draw, 0U); + GREATEST_ASSERT_EQ(states[1].inv.suspend, 0U); + GREATEST_ASSERT_EQ(states[1].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[1].inv.end, 1U); + GREATEST_ASSERT_EQ(states[1].inv.finish, 1U); - GREATEST_ASSERT_EQ(table[0].inv.start, 0); - GREATEST_ASSERT_EQ(table[0].inv.handle, 0); - GREATEST_ASSERT_EQ(table[0].inv.update, 0); - GREATEST_ASSERT_EQ(table[0].inv.draw, 0); - GREATEST_ASSERT_EQ(table[0].inv.end, 1); - GREATEST_ASSERT_EQ(table[0].inv.finish, 1); + /* Pop this state as well. */ + game_pop(); - GREATEST_ASSERT_EQ(table[1].inv.start, 1); - GREATEST_ASSERT_EQ(table[1].inv.handle, 0); - GREATEST_ASSERT_EQ(table[1].inv.update, 1); - GREATEST_ASSERT_EQ(table[1].inv.draw, 0); - GREATEST_ASSERT_EQ(table[1].inv.end, 0); - GREATEST_ASSERT_EQ(table[1].inv.finish, 0); + GREATEST_ASSERT_EQ(states[0].inv.start, 1U); + GREATEST_ASSERT_EQ(states[0].inv.handle, 1U); + GREATEST_ASSERT_EQ(states[0].inv.update, 2U); + GREATEST_ASSERT_EQ(states[0].inv.draw, 3U); + GREATEST_ASSERT_EQ(states[0].inv.suspend, 1U); + GREATEST_ASSERT_EQ(states[0].inv.resume, 1U); + GREATEST_ASSERT_EQ(states[0].inv.end, 1U); + GREATEST_ASSERT_EQ(states[0].inv.finish, 1U); + + GREATEST_ASSERT_EQ(states[1].inv.start, 1U); + GREATEST_ASSERT_EQ(states[1].inv.handle, 0U); + GREATEST_ASSERT_EQ(states[1].inv.update, 4U); + GREATEST_ASSERT_EQ(states[1].inv.draw, 0U); + GREATEST_ASSERT_EQ(states[1].inv.suspend, 0U); + GREATEST_ASSERT_EQ(states[1].inv.resume, 0U); + GREATEST_ASSERT_EQ(states[1].inv.end, 1U); + GREATEST_ASSERT_EQ(states[1].inv.finish, 1U); GREATEST_PASS(); } -GREATEST_SUITE(suite_switch) +GREATEST_SUITE(suite_game) { - GREATEST_SET_SETUP_CB(switch_startup, &game); - GREATEST_RUN_TEST(switch_quick_1); - GREATEST_RUN_TEST(switch_quick_0); - GREATEST_RUN_TEST(switch_invoke); + GREATEST_SET_SETUP_CB(setup, NULL); + GREATEST_SET_TEARDOWN_CB(cleanup, NULL); + GREATEST_RUN_TEST(test_game_push); } GREATEST_MAIN_DEFS(); @@ -363,6 +370,6 @@ { GREATEST_MAIN_BEGIN(); GREATEST_RUN_SUITE(suite_basics); - GREATEST_RUN_SUITE(suite_switch); + GREATEST_RUN_SUITE(suite_game); GREATEST_MAIN_END(); }