Mercurial > molko
view libmlk-core/mlk/core/game.h @ 645:83781cc87fca
core: rework game stack state mechanism
The current model was fundamentally broken as the state could continue its
execution when calling mlk_game_pop from itself (e.g. in update).
The current model uses a sjlj mechanism with mlk_game_push/pop being disallowed
in special state function like end, finish, suspend.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 04 Feb 2024 15:24:00 +0100 |
parents | 75944708c55c |
children |
line wrap: on
line source
/* * game.h -- main game object * * 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_GAME_H #define MLK_CORE_GAME_H /** * \file mlk/core/game.h * \brief Main game object * * For convenience, the default game structure is already initialized with an * array of 8 states usable. */ #include <stddef.h> struct mlk_state; union mlk_event; /** * \enum mlk_game_inhibit * \brief Inhibit game loop */ enum mlk_game_inhibit { /** * Inhibit user input. */ MLK_GAME_INHIBIT_INPUT = (1 << 0), /** * Inhibit game update. */ MLK_GAME_INHIBIT_UPDATE = (1 << 1), /** * Inhibit drawing. * * \note Turning off drawing can introduce weird results on some * platforms. */ MLK_GAME_INHIBIT_DRAW = (1 << 2) }; /** * \struct mlk_game * \brief Game structure */ struct mlk_game { /** * (read-write) * * Inhibit a state function from the game loop. * * Enabling any flags on this field will skip according function from * the loop. */ enum mlk_game_inhibit inhibit; /** * (read-write, borrowed) * * Array of non-owning states. */ struct mlk_state **states; /** * Number of states in array ::mlk_game::states. * * \warning Changing this value must be kept in sync with the array * dimension. */ size_t statesz; /** \cond MLK_PRIVATE_DECLS */ struct mlk_state **state; /** \endcond MLK_PRIVATE_DECLS */ }; /** * \brief Main game loop structure. */ extern struct mlk_game mlk_game; #if defined(__cplusplus) extern "C" { #endif /** * Initialize the main game loop. */ void mlk_game_init(void); /** * Append the state into the game stack and switch to it, suspending current * state. * * The function takes ownership of the state and will be finalized later. * * \pre state != NULL * \param state the state to switch */ _Noreturn void mlk_game_push(struct mlk_state *state); /** * Pop the current state if any and resume the previous one. */ _Noreturn void mlk_game_pop(void); /** * Enter a game loop until there is no more states. * * The current implementation will perform a loop capped to a 60 FPS rate and * update the states with the appropriate number of ticks. * * \pre state != NULL * \param state the first state to run */ void mlk_game_loop(struct mlk_state *state); /** * Request the game loop to stop by removing all states. */ void mlk_game_quit(void); #if defined(__cplusplus) } #endif #endif /* !MLK_CORE_GAME_H */