Mercurial > molko
changeset 466:39dd7c66ebfd
core: script -> mlk_action_script
While here, don't create a static array and let the user specify the storage
area where actions will be put (similar to mlk_action_stack).
Remove example-action for now which requires a major rewrite.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 27 Feb 2023 11:03:13 +0100 |
parents | 01f5580e43d1 |
children | 7420c78018dc |
files | examples/CMakeLists.txt examples/example-action/CMakeLists.txt examples/example-action/example-action.c libmlk-core/CMakeLists.txt libmlk-core/mlk/core/action-script.c libmlk-core/mlk/core/action-script.h libmlk-core/mlk/core/script.c libmlk-core/mlk/core/script.h tests/test-action-script.c |
diffstat | 9 files changed, 266 insertions(+), 863 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/CMakeLists.txt Mon Feb 27 10:03:52 2023 +0100 +++ b/examples/CMakeLists.txt Mon Feb 27 11:03:13 2023 +0100 @@ -20,7 +20,6 @@ set( DIRS - example-action example-animation example-audio example-battle
--- a/examples/example-action/CMakeLists.txt Mon Feb 27 10:03:52 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for Molko's Engine -# -# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -project(example-action) - -set( - SOURCES - ${example-action_SOURCE_DIR}/example-action.c -) - -mlk_executable( - NAME example-action - FOLDER examples - LIBRARIES libmlk-example - SOURCES ${SOURCES} -) - -source_group(TREE ${example-action_SOURCE_DIR} FILES ${SOURCES})
--- a/examples/example-action/example-action.c Mon Feb 27 10:03:52 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,424 +0,0 @@ -/* - * example-action.c -- example on how to use automatic actions - * - * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <mlk/core/action.h> -#include <mlk/core/action-stack.h> -#include <mlk/core/core.h> -#include <mlk/core/event.h> -#include <mlk/core/game.h> -#include <mlk/core/image.h> -#include <mlk/core/maths.h> -#include <mlk/core/painter.h> -#include <mlk/core/panic.h> -#include <mlk/core/script.h> -#include <mlk/core/sprite.h> -#include <mlk/core/state.h> -#include <mlk/core/sys.h> -#include <mlk/core/texture.h> -#include <mlk/core/util.h> -#include <mlk/core/window.h> - -#include <mlk/ui/theme.h> -#include <mlk/ui/ui.h> - -#include <mlk/rpg/message.h> -#include <mlk/rpg/rpg.h> - -#include <assets/sprites/chest.h> -#include <assets/sprites/people.h> - -#define W 1280 -#define H 720 - -#define MW (W * 0.75) -#define MX ((W / 2) - (MW / 2)) -#define MY (100) - -/* This is a stack of "parallel" events. */ -static struct mlk_action *events_actions[32]; -static struct mlk_action_stack events; - -/* This is a stack of modal events. */ -static struct mlk_action *modal_actions[32]; -static struct mlk_action_stack modal; - -/* Maximum number of states. */ -static struct state *states[1]; - -/* - * Event object for the chest to click on. - */ -static struct { - const char *text[2]; - struct message msg; - struct mlk_action msg_act; - int x; - int y; - int opened; - struct texture image; - struct sprite sprite; - struct mlk_action event; -} chest = { - .text = { - "100000 pièces.", - "Te voilà riche sale file de crevette." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = chest.text, - .linesz = 2 - } -}; - -/* - * Event object for the guide who ask dialog with you. - * - * It is a script spawned upon click like this. - * - * [guide.event] - * | spawn - * (on click)------------------->[message 1] - * v - * [message 2] - * v - * [question 3] - * spawn v - * [response]<---------------------[check result] - * v - * [message 4/5] - */ -static struct { - struct { - const char *text[6]; - struct message msg; - struct mlk_action act; - } msgs[5]; - - /* This is the sprite and action to click on. */ - int x; - int y; - struct texture image; - struct sprite sprite; - struct mlk_action event; - - /* This is the event for the response. */ - struct mlk_action response; - - struct script script; - struct mlk_action script_act; -} guide = { - .msgs = { - { - .text = { - "Bienvenue dans ce monde Molko." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, - .flags = MESSAGE_FLAGS_FADEIN, - .lines = guide.msgs[0].text, - .linesz = 1 - }, - }, - { - .text = { - "Penses tu vraiment pouvoir me battre ?" - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = guide.msgs[1].text, - .linesz = 1 - } - }, - { - .text = { - "Non j'ai la trouille.", - "Bien sûr, je suis la légende." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .flags = MESSAGE_FLAGS_QUESTION, - .lines = guide.msgs[2].text, - .linesz = 2 - } - }, - - /* In case of NO. */ - { - .text = { - "Poule mouillée." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = guide.msgs[3].text, - .linesz = 1 - } - }, - - /* In case of YES. */ - { - .text = { - "Prépare toi à souffrir." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = guide.msgs[4].text, - .linesz = 1 - } - } - } -}; - -static int -guide_response_update(struct mlk_action *act, unsigned int ticks) -{ - /* Immediately return to get access to end. */ - (void)act; - (void)ticks; - - return 1; -} - -static void -guide_response_end(struct mlk_action *act) -{ - (void)act; - - /* We add a final response depending on the result. */ - const int index = guide.msgs[2].msg.index + 3; - - message_action(&guide.msgs[index].msg, &guide.msgs[index].act); - message_query(&guide.msgs[index].msg, NULL, &guide.msgs[index].msg.h); - mlk_action_stack_add(&modal, &guide.msgs[index].act); -} - -static void -guide_popup(void) -{ - /* Prepare the script with first 3 messages. */ - for (size_t i = 0; i < 3; ++i) { - message_action(&guide.msgs[i].msg, &guide.msgs[i].act); - message_query(&guide.msgs[i].msg, NULL, &guide.msgs[i].msg.h); - script_append(&guide.script, &guide.msgs[i].act); - } - - /* Reset the message index. */ - guide.msgs[2].msg.index = 0; - - /* This is final action that analyze user input. */ - guide.response.update = guide_response_update; - guide.response.end = guide_response_end; - script_append(&guide.script, &guide.response); - - script_action(&guide.script, &guide.script_act); - mlk_action_stack_add(&modal, &guide.script_act); -} - -static void -guide_handle(struct mlk_action *act, const union mlk_event *ev) -{ - (void)act; - - if (!mlk_action_stack_completed(&modal)) - return; - - switch (ev->type) { - case MLK_EVENT_CLICKDOWN: - if (mlk_maths_is_boxed(guide.x, guide.y, - guide.sprite.cellw, guide.sprite.cellh, - ev->click.x, ev->click.y)) - guide_popup(); - break; - default: - break; - } -} - -static void -guide_draw(struct mlk_action *act) -{ - (void)act; - - sprite_draw(&guide.sprite, 0, 0, guide.x, guide.y); -} - -static void -guide_init(void) -{ - if (mlk_image_openmem(&guide.image, assets_sprites_people, sizeof (assets_sprites_people)) < 0) - mlk_panic(); - - sprite_init(&guide.sprite, &guide.image, 48, 48); - - /* This is the global guide action. */ - guide.event.handle = guide_handle; - guide.event.draw = guide_draw; - guide.x = 200; - guide.y = 200; -} - -static void -chest_handle(struct mlk_action *act, const union mlk_event *ev) -{ - (void)act; - - if (chest.opened || !mlk_action_stack_completed(&modal)) - return; - - switch (ev->type) { - case MLK_EVENT_CLICKDOWN: - if (mlk_maths_is_boxed(chest.x, chest.y, chest.sprite.cellw, chest.sprite.cellh, - ev->click.x, ev->click.y)) { - chest.opened = 1; - message_action(&chest.msg, &chest.msg_act); - message_query(&chest.msg, NULL, &chest.msg.h); - mlk_action_stack_add(&modal, &chest.msg_act); - } - default: - break; - } -} - -static void -chest_draw(struct mlk_action *act) -{ - (void)act; - - const int row = chest.opened ? chest.sprite.nrows - 1 : 0; - const int col = chest.opened ? chest.sprite.ncols - 1 : 0; - - sprite_draw(&chest.sprite, row, col, chest.x, chest.y); -} - -static void -chest_init(void) -{ - if (mlk_image_openmem(&chest.image, assets_sprites_chest, sizeof (assets_sprites_chest)) < 0) - mlk_panic(); - - sprite_init(&chest.sprite, &chest.image, 32, 32); - - chest.x = 100; - chest.y = 100; - chest.event.handle = chest_handle; - chest.event.draw = chest_draw; -} - -static void -init(void) -{ - if (mlk_core_init("fr.malikania", "example-action") < 0 || ui_init() < 0 || rpg_init() < 0) - mlk_panic(); - if (window_open("Example - Action", W, H) < 0) - mlk_panic(); - - guide_init(); - chest_init(); -} - -static void -handle(struct state *st, const union mlk_event *ev) -{ - (void)st; - - switch (ev->type) { - case MLK_EVENT_QUIT: - mlk_game_quit(); - break; - default: - mlk_action_stack_handle(&events, ev); - mlk_action_stack_handle(&modal, ev); - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - (void)st; - - mlk_action_stack_update(&events, ticks); - mlk_action_stack_update(&modal, ticks); -} - -static void -draw(struct state *st) -{ - (void)st; - - mlk_painter_set_color(0xffffffff); - mlk_painter_clear(); - mlk_action_stack_draw(&events); - mlk_action_stack_draw(&modal); - mlk_painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .update = update, - .draw = draw - }; - - mlk_action_stack_init(&modal, modal_actions, UTIL_SIZE(modal_actions)); - mlk_action_stack_init(&events, events_actions, UTIL_SIZE(events_actions)); - mlk_action_stack_add(&events, &chest.event); - mlk_action_stack_add(&events, &guide.event); - - mlk_game_init(states, UTIL_SIZE(states)); - mlk_game_push(&state); - mlk_game_loop(); -} - -static void -quit(void) -{ - window_finish(); - rpg_finish(); - ui_finish(); - mlk_core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); - - return 0; -}
--- a/libmlk-core/CMakeLists.txt Mon Feb 27 10:03:52 2023 +0100 +++ b/libmlk-core/CMakeLists.txt Mon Feb 27 11:03:13 2023 +0100 @@ -20,6 +20,8 @@ set( SOURCES + ${libmlk-core_SOURCE_DIR}/mlk/core/action-script.c + ${libmlk-core_SOURCE_DIR}/mlk/core/action-script.h ${libmlk-core_SOURCE_DIR}/mlk/core/action-stack.c ${libmlk-core_SOURCE_DIR}/mlk/core/action-stack.h ${libmlk-core_SOURCE_DIR}/mlk/core/action.c @@ -60,8 +62,6 @@ ${libmlk-core_SOURCE_DIR}/mlk/core/painter.h ${libmlk-core_SOURCE_DIR}/mlk/core/panic.c ${libmlk-core_SOURCE_DIR}/mlk/core/panic.h - ${libmlk-core_SOURCE_DIR}/mlk/core/script.c - ${libmlk-core_SOURCE_DIR}/mlk/core/script.h ${libmlk-core_SOURCE_DIR}/mlk/core/sound.c ${libmlk-core_SOURCE_DIR}/mlk/core/sound.h ${libmlk-core_SOURCE_DIR}/mlk/core/sprite.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-core/mlk/core/action-script.c Mon Feb 27 11:03:13 2023 +0100 @@ -0,0 +1,117 @@ +/* + * script.c -- convenient sequence of actions + * + * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "action-script.h" +#include "action.h" +#include "err.h" + +static inline struct mlk_action * +current(struct mlk_action_script *s) +{ + if (s->cur >= s->size) + return NULL; + + return s->actions[s->cur]; +} + +void +mlk_action_script_init(struct mlk_action_script *s, struct mlk_action **actions, size_t max) +{ + assert(s); + + s->actions = actions; + s->max = max; + s->size = s->cur = 0; +} + +int +mlk_action_script_append(struct mlk_action_script *s, struct mlk_action *a) +{ + assert(s); + assert(a); + + if (s->size >= s->max) + return MLK_ERR_NO_MEM; + + s->actions[s->size++] = a; + + return 0; +} + +void +mlk_action_script_handle(struct mlk_action_script *s, const union mlk_event *ev) +{ + assert(s); + assert(ev); + + struct mlk_action *a = current(s); + + if (a) + mlk_action_handle(a, ev); +} + +int +mlk_action_script_update(struct mlk_action_script *s, unsigned int ticks) +{ + assert(s); + + struct mlk_action *a; + + /* No action left means completed. */ + if (!(a = current(s))) + return 1; + + if (mlk_action_update(a, ticks)) { + mlk_action_end(a); + s->cur++; + } + + return s->cur >= s->size; +} + +void +mlk_action_script_draw(struct mlk_action_script *s) +{ + assert(s); + + struct mlk_action *a; + + if ((a = current(s))) + mlk_action_draw(a); +} + +int +mlk_action_script_completed(const struct mlk_action_script *s) +{ + assert(s); + + return s->cur >= s->size; +} + +void +mlk_action_script_finish(struct mlk_action_script *s) +{ + assert(s); + + for (size_t i = 0; i < s->size; ++i) + mlk_action_finish(s->actions[i]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-core/mlk/core/action-script.h Mon Feb 27 11:03:13 2023 +0100 @@ -0,0 +1,62 @@ +/* + * script.h -- convenient sequence of actions + * + * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MLK_CORE_ACTION_SCRIPT_H +#define MLK_CORE_ACTION_SCRIPT_H + +#include <stddef.h> + +#include "core.h" + +struct mlk_action; + +union mlk_event; + +struct mlk_action_script { + struct mlk_action **actions; + size_t size; + size_t max; + size_t cur; +}; + +MLK_CORE_BEGIN_DECLS + +void +mlk_action_script_init(struct mlk_action_script *, struct mlk_action **, size_t); + +int +mlk_action_script_append(struct mlk_action_script *, struct mlk_action *); + +void +mlk_action_script_handle(struct mlk_action_script *, const union mlk_event *); + +int +mlk_action_script_update(struct mlk_action_script *, unsigned int); + +void +mlk_action_script_draw(struct mlk_action_script *); + +int +mlk_action_script_completed(const struct mlk_action_script *); + +void +mlk_action_script_finish(struct mlk_action_script *); + +MLK_CORE_END_DECLS + +#endif /* !MLK_CORE_ACTION_SCRIPT_H */
--- a/libmlk-core/mlk/core/script.c Mon Feb 27 10:03:52 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -/* - * script.c -- convenient sequence of actions - * - * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include "action.h" -#include "err.h" -#include "script.h" - -static struct mlk_action * -current(struct script *s) -{ - if (s->cur >= s->actionsz) - return NULL; - - return s->actions[s->cur]; -} - -static void -handle(struct mlk_action *a, const union mlk_event *ev) -{ - script_handle(a->data, ev); -} - -static int -update(struct mlk_action *a, unsigned int ticks) -{ - return script_update(a->data, ticks); -} - -static void -draw(struct mlk_action *a) -{ - script_draw(a->data); -} - -static void -finish(struct mlk_action *a) -{ - script_finish(a->data); -} - -void -script_init(struct script *s) -{ - assert(s); - - memset(s, 0, sizeof (*s)); -} - -int -script_append(struct script *s, struct mlk_action *a) -{ - assert(s); - assert(a); - - if (s->actionsz >= SCRIPT_ACTION_MAX) - return MLK_ERR_NO_MEM; - - s->actions[s->actionsz++] = a; - - return 0; -} - -void -script_handle(struct script *s, const union mlk_event *ev) -{ - assert(s); - assert(ev); - - struct mlk_action *a = current(s); - - if (a) - mlk_action_handle(a, ev); -} - -int -script_update(struct script *s, unsigned int ticks) -{ - assert(s); - - struct mlk_action *a = current(s); - - if (!a) - return 1; - - if (mlk_action_update(a, ticks)) { - mlk_action_end(a); - s->cur++; - } - - return s->cur >= s->actionsz; -} - -void -script_draw(struct script *s) -{ - assert(s); - - struct mlk_action *a = current(s); - - if (a) - mlk_action_draw(a); -} - -int -script_completed(const struct script *s) -{ - assert(s); - - return s->cur >= s->actionsz; -} - -void -script_finish(struct script *s) -{ - assert(s); - - for (size_t i = 0; i < s->actionsz; ++i) - mlk_action_finish(s->actions[i]); - - memset(s, 0, sizeof (*s)); -} - -void -script_action(struct script *s, struct mlk_action *action) -{ - assert(s); - assert(action); - - memset(action, 0, sizeof (*action)); - action->data = s; - action->handle = handle; - action->update = update; - action->draw = draw; - action->finish = finish; -}
--- a/libmlk-core/mlk/core/script.h Mon Feb 27 10:03:52 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * script.h -- convenient sequence of actions - * - * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_SCRIPT_H -#define MLK_CORE_SCRIPT_H - -#include <stddef.h> - -#include "core.h" - -#define SCRIPT_ACTION_MAX (128) - -struct mlk_action; - -union mlk_event; - -struct script { - struct mlk_action *actions[SCRIPT_ACTION_MAX]; - size_t actionsz; - size_t cur; -}; - -MLK_CORE_BEGIN_DECLS - -void -script_init(struct script *); - -int -script_append(struct script *, struct mlk_action *); - -void -script_handle(struct script *, const union mlk_event *); - -int -script_update(struct script *, unsigned int); - -void -script_draw(struct script *); - -int -script_completed(const struct script *); - -void -script_finish(struct script *); - -void -script_action(struct script *s, struct mlk_action *); - -MLK_CORE_END_DECLS - -#endif /* !MLK_CORE_SCRIPT_H */
--- a/tests/test-action-script.c Mon Feb 27 10:03:52 2023 +0100 +++ b/tests/test-action-script.c Mon Feb 27 11:03:13 2023 +0100 @@ -17,8 +17,9 @@ */ #include <mlk/core/action.h> +#include <mlk/core/err.h> #include <mlk/core/event.h> -#include <mlk/core/script.h> +#include <mlk/core/action-script.h> #include <dt.h> @@ -88,39 +89,50 @@ static void test_basics_init(void) { - struct script sc; + struct mlk_action_script sc; + struct mlk_action *actions[10]; - script_init(&sc); + mlk_action_script_init(&sc, actions, 10); - DT_EQ_UINT(sc.actionsz, 0U); - DT_EQ_UINT(sc.cur, 0U); + DT_EQ_SIZE(sc.size, 0U); + DT_EQ_SIZE(sc.max, 10U); + DT_EQ_SIZE(sc.cur, 0U); } static void test_basics_append(void) { - struct mlk_action act[3] = {0}; - struct script sc = {0}; + struct mlk_action actions[4] = {0}; + struct mlk_action *array[3] = {0}; + struct mlk_action_script sc = {0}; + + mlk_action_script_init(&sc, array, 3); - DT_ASSERT(script_append(&sc, &act[0]) == 0); - DT_EQ_UINT(sc.cur, 0U); - DT_EQ_UINT(sc.actionsz, 1U); - DT_EQ_PTR(sc.actions[0], &act[0]); + DT_ASSERT(mlk_action_script_append(&sc, &actions[0]) == 0); + DT_EQ_SIZE(sc.size, 1U); + DT_EQ_SIZE(sc.max, 3U); + DT_EQ_SIZE(sc.cur, 0U); + DT_EQ_PTR(sc.actions[0], &actions[0]); - DT_ASSERT(script_append(&sc, &act[1]) == 0); - DT_EQ_UINT(sc.cur, 0U); - DT_EQ_UINT(sc.actionsz, 2U); - DT_EQ_PTR(sc.actions[0], &act[0]); - DT_EQ_PTR(sc.actions[1], &act[1]); + DT_ASSERT(mlk_action_script_append(&sc, &actions[1]) == 0); + DT_EQ_SIZE(sc.size, 2U); + DT_EQ_SIZE(sc.max, 3U); + DT_EQ_SIZE(sc.cur, 0U); + DT_EQ_PTR(sc.actions[0], &actions[0]); + DT_EQ_PTR(sc.actions[1], &actions[1]); - DT_ASSERT(script_append(&sc, &act[2]) == 0); - DT_EQ_UINT(sc.cur, 0U); - DT_EQ_UINT(sc.actionsz, 3U); - DT_EQ_PTR(sc.actions[0], &act[0]); - DT_EQ_PTR(sc.actions[1], &act[1]); - DT_EQ_PTR(sc.actions[2], &act[2]); + DT_ASSERT(mlk_action_script_append(&sc, &actions[2]) == 0); + DT_EQ_SIZE(sc.size, 3U); + DT_EQ_SIZE(sc.max, 3U); + DT_EQ_SIZE(sc.cur, 0U); + DT_EQ_PTR(sc.actions[0], &actions[0]); + DT_EQ_PTR(sc.actions[1], &actions[1]); + DT_EQ_PTR(sc.actions[2], &actions[2]); - script_finish(&sc); + /* This can not fit. */ + DT_ASSERT(mlk_action_script_append(&sc, &actions[3]) == MLK_ERR_NO_MEM); + + mlk_action_script_finish(&sc); } static void @@ -135,14 +147,17 @@ { .act = INIT(&table[2].inv, my_update_false) } }; - struct script sc = {0}; + struct mlk_action array[3] = {0}; + struct mlk_action_script sc = {0}; - DT_ASSERT(script_append(&sc, &table[0].act) == 0); - DT_ASSERT(script_append(&sc, &table[1].act) == 0); - DT_ASSERT(script_append(&sc, &table[2].act) == 0); + mlk_action_script_init(&sc, array, 3); + + DT_ASSERT(mlk_action_script_append(&sc, &table[0].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[1].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[2].act) == 0); /* [0] */ - script_handle(&sc, &(union mlk_event){0}); + mlk_action_script_handle(&sc, &(union mlk_event){0}); DT_EQ_INT(table[0].inv.handle, 1); DT_EQ_INT(table[0].inv.update, 0); DT_EQ_INT(table[0].inv.draw, 0); @@ -160,8 +175,8 @@ DT_EQ_INT(table[2].inv.finish, 0); /* [0] -> [1] */ - DT_ASSERT(!script_update(&sc, 0)); - script_handle(&sc, &(union mlk_event){0}); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); + mlk_action_script_handle(&sc, &(union mlk_event){0}); DT_EQ_INT(table[0].inv.handle, 1); DT_EQ_INT(table[0].inv.update, 1); @@ -180,8 +195,8 @@ DT_EQ_INT(table[2].inv.finish, 0); /* [2] */ - DT_ASSERT(!script_update(&sc, 0)); - script_handle(&sc, &(union mlk_event){0}); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); + mlk_action_script_handle(&sc, &(union mlk_event){0}); DT_EQ_INT(table[0].inv.handle, 1); DT_EQ_INT(table[0].inv.update, 1); @@ -198,6 +213,8 @@ DT_EQ_INT(table[2].inv.draw, 0); DT_EQ_INT(table[2].inv.end, 0); DT_EQ_INT(table[2].inv.finish, 0); + + mlk_action_script_finish(&sc); } static void @@ -212,14 +229,17 @@ { .act = INIT(&table[2].inv, my_update_false) } }; - struct script sc = {0}; + struct mlk_action array[3]; + struct mlk_action_script sc = {0}; - DT_ASSERT(script_append(&sc, &table[0].act) == 0); - DT_ASSERT(script_append(&sc, &table[1].act) == 0); - DT_ASSERT(script_append(&sc, &table[2].act) == 0); + mlk_action_script_init(&sc, array, 3); + + DT_ASSERT(mlk_action_script_append(&sc, &table[0].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[1].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[2].act) == 0); /* 0 -> 1 */ - DT_ASSERT(!script_update(&sc, 0)); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); DT_EQ_INT(table[0].inv.draw, 0); @@ -237,7 +257,7 @@ DT_EQ_INT(table[2].inv.finish, 0); /* 1 -> 2 */ - DT_ASSERT(!script_update(&sc, 0)); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); DT_EQ_INT(table[0].inv.draw, 0); @@ -255,9 +275,9 @@ DT_EQ_INT(table[2].inv.finish, 0); /* 2 stays, it never ends. */ - DT_ASSERT(!script_update(&sc, 0)); - DT_ASSERT(!script_update(&sc, 0)); - DT_ASSERT(!script_update(&sc, 0)); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); DT_EQ_INT(table[0].inv.draw, 0); @@ -276,7 +296,7 @@ /* Now, change its update function to complete the script. */ table[2].act.update = my_update_true; - DT_ASSERT(script_update(&sc, 0)); + DT_ASSERT(mlk_action_script_update(&sc, 0)); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); DT_EQ_INT(table[0].inv.draw, 0); @@ -292,6 +312,8 @@ DT_EQ_INT(table[2].inv.draw, 0); DT_EQ_INT(table[2].inv.end, 1); DT_EQ_INT(table[2].inv.finish, 0); + + mlk_action_script_finish(&sc); } static void @@ -306,14 +328,17 @@ { .act = INIT(&table[2].inv, my_update_false) } }; - struct script sc = {0}; + struct mlk_action array[3]; + struct mlk_action_script sc = {0}; - DT_ASSERT(script_append(&sc, &table[0].act) == 0); - DT_ASSERT(script_append(&sc, &table[1].act) == 0); - DT_ASSERT(script_append(&sc, &table[2].act) == 0); + mlk_action_script_init(&sc, array, 3); + + DT_ASSERT(mlk_action_script_append(&sc, &table[0].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[1].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[2].act) == 0); /* [0] */ - script_draw(&sc); + mlk_action_script_draw(&sc); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 0); DT_EQ_INT(table[0].inv.draw, 1); @@ -331,8 +356,8 @@ DT_EQ_INT(table[2].inv.finish, 0); /* [0] -> [1] */ - DT_ASSERT(!script_update(&sc, 0)); - script_draw(&sc); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); + mlk_action_script_draw(&sc); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); @@ -351,8 +376,8 @@ DT_EQ_INT(table[2].inv.finish, 0); /* [2] */ - DT_ASSERT(!script_update(&sc, 0)); - script_draw(&sc); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); + mlk_action_script_draw(&sc); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); @@ -383,16 +408,19 @@ { .act = INIT(&table[2].inv, my_update_false) } }; - struct script sc = {0}; + struct mlk_action array[3]; + struct mlk_action_script sc = {0}; - DT_ASSERT(script_append(&sc, &table[0].act) == 0); - DT_ASSERT(script_append(&sc, &table[1].act) == 0); - DT_ASSERT(script_append(&sc, &table[2].act) == 0); + mlk_action_script_init(&sc, array, 3); + + DT_ASSERT(mlk_action_script_append(&sc, &table[0].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[1].act) == 0); + DT_ASSERT(mlk_action_script_append(&sc, &table[2].act) == 0); /* Update once so that the current action goes to 1. */ - DT_ASSERT(!script_update(&sc, 0)); + DT_ASSERT(!mlk_action_script_update(&sc, 0)); - script_finish(&sc); + mlk_action_script_finish(&sc); DT_EQ_INT(table[0].inv.handle, 0); DT_EQ_INT(table[0].inv.update, 1); @@ -411,131 +439,6 @@ DT_EQ_INT(table[2].inv.finish, 1); } -static void -test_action_simple(void) -{ - struct { - struct invokes inv; - struct mlk_action act; - } table[] = { - { .act = INIT(&table[0].inv, my_update_true) }, - { .act = INIT(&table[1].inv, my_update_true) }, - { .act = INIT(&table[2].inv, my_update_false) } - }; - - struct script sc = {0}; - struct mlk_action act; - - DT_ASSERT(script_append(&sc, &table[0].act) == 0); - DT_ASSERT(script_append(&sc, &table[1].act) == 0); - DT_ASSERT(script_append(&sc, &table[2].act) == 0); - - /* Now convert this script into an action itself. */ - script_action(&sc, &act); - - /* Draw and input before updating. */ - mlk_action_handle(&act, &(union mlk_event){0}); - mlk_action_draw(&act); - - /* [0] -> [1] */ - DT_ASSERT(!mlk_action_update(&act, 0)); - DT_EQ_INT(table[0].inv.handle, 1); - DT_EQ_INT(table[0].inv.update, 1); - DT_EQ_INT(table[0].inv.draw, 1); - DT_EQ_INT(table[0].inv.end, 1); - DT_EQ_INT(table[0].inv.finish, 0); - DT_EQ_INT(table[1].inv.handle, 0); - DT_EQ_INT(table[1].inv.update, 0); - DT_EQ_INT(table[1].inv.draw, 0); - DT_EQ_INT(table[1].inv.end, 0); - DT_EQ_INT(table[1].inv.finish, 0); - DT_EQ_INT(table[2].inv.handle, 0); - DT_EQ_INT(table[2].inv.update, 0); - DT_EQ_INT(table[2].inv.draw, 0); - DT_EQ_INT(table[2].inv.end, 0); - DT_EQ_INT(table[2].inv.finish, 0); - - mlk_action_handle(&act, &(union mlk_event){0}); - mlk_action_draw(&act); - - /* [1] -> [2] */ - DT_ASSERT(!mlk_action_update(&act, 0)); - DT_EQ_INT(table[0].inv.handle, 1); - DT_EQ_INT(table[0].inv.update, 1); - DT_EQ_INT(table[0].inv.draw, 1); - DT_EQ_INT(table[0].inv.end, 1); - DT_EQ_INT(table[0].inv.finish, 0); - DT_EQ_INT(table[1].inv.handle, 1); - DT_EQ_INT(table[1].inv.update, 1); - DT_EQ_INT(table[1].inv.draw, 1); - DT_EQ_INT(table[1].inv.end, 1); - DT_EQ_INT(table[1].inv.finish, 0); - DT_EQ_INT(table[2].inv.handle, 0); - DT_EQ_INT(table[2].inv.update, 0); - DT_EQ_INT(table[2].inv.draw, 0); - DT_EQ_INT(table[2].inv.end, 0); - DT_EQ_INT(table[2].inv.finish, 0); - - mlk_action_handle(&act, &(union mlk_event){0}); - mlk_action_draw(&act); - - /* 2 stays, it never ends. */ - DT_ASSERT(!mlk_action_update(&act, 0)); - DT_ASSERT(!mlk_action_update(&act, 0)); - DT_ASSERT(!mlk_action_update(&act, 0)); - DT_EQ_INT(table[0].inv.handle, 1); - DT_EQ_INT(table[0].inv.update, 1); - DT_EQ_INT(table[0].inv.draw, 1); - DT_EQ_INT(table[0].inv.end, 1); - DT_EQ_INT(table[0].inv.finish, 0); - DT_EQ_INT(table[1].inv.handle, 1); - DT_EQ_INT(table[1].inv.update, 1); - DT_EQ_INT(table[1].inv.draw, 1); - DT_EQ_INT(table[1].inv.end, 1); - DT_EQ_INT(table[1].inv.finish, 0); - DT_EQ_INT(table[2].inv.handle, 1); - DT_EQ_INT(table[2].inv.update, 3); - DT_EQ_INT(table[2].inv.draw, 1); - DT_EQ_INT(table[2].inv.end, 0); - DT_EQ_INT(table[2].inv.finish, 0); - - table[2].act.update = my_update_true; - DT_ASSERT(mlk_action_update(&act, 0)); - DT_EQ_INT(table[0].inv.handle, 1); - DT_EQ_INT(table[0].inv.update, 1); - DT_EQ_INT(table[0].inv.draw, 1); - DT_EQ_INT(table[0].inv.end, 1); - DT_EQ_INT(table[0].inv.finish, 0); - DT_EQ_INT(table[1].inv.handle, 1); - DT_EQ_INT(table[1].inv.update, 1); - DT_EQ_INT(table[1].inv.draw, 1); - DT_EQ_INT(table[1].inv.end, 1); - DT_EQ_INT(table[1].inv.finish, 0); - DT_EQ_INT(table[2].inv.handle, 1); - DT_EQ_INT(table[2].inv.update, 4); - DT_EQ_INT(table[2].inv.draw, 1); - DT_EQ_INT(table[2].inv.end, 1); - DT_EQ_INT(table[2].inv.finish, 0); - - /* Also dispose resources. */ - mlk_action_finish(&act); - DT_EQ_INT(table[0].inv.handle, 1); - DT_EQ_INT(table[0].inv.update, 1); - DT_EQ_INT(table[0].inv.draw, 1); - DT_EQ_INT(table[0].inv.end, 1); - DT_EQ_INT(table[0].inv.finish, 1); - DT_EQ_INT(table[1].inv.handle, 1); - DT_EQ_INT(table[1].inv.update, 1); - DT_EQ_INT(table[1].inv.draw, 1); - DT_EQ_INT(table[1].inv.end, 1); - DT_EQ_INT(table[1].inv.finish, 1); - DT_EQ_INT(table[2].inv.handle, 1); - DT_EQ_INT(table[2].inv.update, 4); - DT_EQ_INT(table[2].inv.draw, 1); - DT_EQ_INT(table[2].inv.end, 1); - DT_EQ_INT(table[2].inv.finish, 1); -} - int main(void) { @@ -545,6 +448,5 @@ DT_RUN(test_basics_update); DT_RUN(test_basics_draw); DT_RUN(test_basics_finish); - DT_RUN(test_action_simple); DT_SUMMARY(); }