Skip to content

Commit

Permalink
scenes: rework scene management
Browse files Browse the repository at this point in the history
Following more of the intended paradigms of view_dispatcher and
scene_manager. Scene callbacks now all send view dispatcher custom
events rather than navigating scene transitions within them. This
means scenes are no longer in the callback when exit/enter pairs
are called which is the correct way to handle it.

Signed-off-by: Kris Bahnsen <Kris@KBEmbedded.com>
  • Loading branch information
kbembedded committed Aug 3, 2024
1 parent d353ec0 commit 7a2ddb0
Show file tree
Hide file tree
Showing 20 changed files with 331 additions and 234 deletions.
7 changes: 4 additions & 3 deletions src/include/pokemon_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ struct pokemon_fap {
typedef struct pokemon_fap PokemonFap;

typedef enum {
AppViewMainMenu,
AppViewOpts, // Generic view ID meant for module re-use
AppViewSubmenu,
AppViewTextInput,
AppViewVariableItem,
AppViewDialogEx,
AppViewSelectPokemon,
AppViewTrade,
AppViewExitConfirm,
} AppView;

#endif /* POKEMON_APP_H */
77 changes: 51 additions & 26 deletions src/pokemon_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,68 @@

#include <src/include/pokemon_app.h>
#include <src/include/pokemon_data.h>
#include <src/scenes/include/pokemon_menu.h>
#include <src/views/trade.h>
#include <src/views/select_pokemon.h>
#include <src/include/pokemon_char_encode.h>

#include <src/scenes/include/pokemon_scene.h>

bool pokemon_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
PokemonFap* pokemon_fap = context;

return scene_manager_handle_custom_event(pokemon_fap->scene_manager, event);
}

bool pokemon_back_event_callback(void* context) {
furi_assert(context);
PokemonFap* pokemon_fap = context;
return scene_manager_handle_back_event(pokemon_fap->scene_manager);
}


PokemonFap* pokemon_alloc() {
PokemonFap* pokemon_fap = (PokemonFap*)malloc(sizeof(PokemonFap));
ViewDispatcher* view_dispatcher = NULL;

// View dispatcher
pokemon_fap->view_dispatcher = view_dispatcher_alloc();
view_dispatcher = view_dispatcher_alloc();
pokemon_fap->view_dispatcher = view_dispatcher;

view_dispatcher_enable_queue(pokemon_fap->view_dispatcher);
view_dispatcher_set_event_callback_context(pokemon_fap->view_dispatcher, pokemon_fap);
view_dispatcher_enable_queue(view_dispatcher);
view_dispatcher_set_event_callback_context(view_dispatcher, pokemon_fap);
view_dispatcher_set_custom_event_callback(view_dispatcher, pokemon_custom_event_callback);
view_dispatcher_set_navigation_event_callback(view_dispatcher, pokemon_back_event_callback);
view_dispatcher_attach_to_gui(
pokemon_fap->view_dispatcher,
view_dispatcher,
(Gui*)furi_record_open(RECORD_GUI),
ViewDispatcherTypeFullscreen);

// Set up defaults
// Set up pinout defaults
memcpy(&pokemon_fap->pins, &common_pinouts[PINOUT_ORIGINAL], sizeof(struct gblink_pins));

/* Set up gui modules used. It would be nice if these could be allocated and
* freed as needed, however, the scene manager still requires pointers that
* get set up as a part of the scene. Therefore, individual scene's exit
* callbacks cannot free the buffer.
*
* In order to do this properly, I think each scene, or maybe common to all
* scenes, would end up needing to set a delayed callback of some kind. But
* I'm not sure how to guarantee this gets called in a reasonable amount of
* time.
*/
// Text input
pokemon_fap->text_input = text_input_alloc();
view_dispatcher_add_view(
view_dispatcher, AppViewTextInput, text_input_get_view(pokemon_fap->text_input));

// Submenu
pokemon_fap->submenu = submenu_alloc();
view_dispatcher_add_view(
view_dispatcher, AppViewSubmenu, submenu_get_view(pokemon_fap->submenu));

// Variable Item List
pokemon_fap->variable_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
view_dispatcher, AppViewVariableItem, variable_item_list_get_view(pokemon_fap->variable_item_list));

// DialogEx
pokemon_fap->dialog_ex = dialog_ex_alloc();
view_dispatcher_add_view(
view_dispatcher, AppViewDialogEx, dialog_ex_get_view(pokemon_fap->dialog_ex));

// Set up menu scene
// Scene manager
pokemon_fap->scene_manager = scene_manager_alloc(&pokemon_scene_handlers, pokemon_fap);
view_dispatcher_add_view(
pokemon_fap->view_dispatcher, AppViewMainMenu, submenu_get_view(pokemon_fap->submenu));
scene_manager_next_scene(pokemon_fap->scene_manager, PokemonSceneMainMenu);

return pokemon_fap;
Expand All @@ -53,19 +73,24 @@ PokemonFap* pokemon_alloc() {
void free_app(PokemonFap* pokemon_fap) {
furi_assert(pokemon_fap);

view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewMainMenu);
// Submenu
submenu_free(pokemon_fap->submenu);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewSubmenu);

text_input_free(pokemon_fap->text_input);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewTextInput);

variable_item_list_free(pokemon_fap->variable_item_list);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewVariableItem);

dialog_ex_free(pokemon_fap->dialog_ex);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewDialogEx);

view_dispatcher_free(pokemon_fap->view_dispatcher);

// Free scenes
scene_manager_free(pokemon_fap->scene_manager);

// Free gui modules
submenu_free(pokemon_fap->submenu);
text_input_free(pokemon_fap->text_input);
variable_item_list_free(pokemon_fap->variable_item_list);
dialog_ex_free(pokemon_fap->dialog_ex);

// Close records
furi_record_close(RECORD_GUI);

Expand Down
10 changes: 0 additions & 10 deletions src/scenes/include/pokemon_menu.h

This file was deleted.

6 changes: 6 additions & 0 deletions src/scenes/include/pokemon_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
typedef enum {
#include "pokemon_scene_config.h"
PokemonSceneNum,
/* Magic number to send on an event to search through scene history and
* change to a previous scene.
*/
PokemonSceneSearch = (1 << 30),
/* Magic number to send on an event to trigger going back a scene */
PokemonSceneBack = (1 << 31),
} PokemonScene;
#undef ADD_SCENE

Expand Down
30 changes: 16 additions & 14 deletions src/scenes/pokemon_exit_confirm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@
#include <src/views/select_pokemon.h>
#include <src/views/trade.h>

static bool pokemon_scene_exit_confirm_back_event_callback(void* context) {
UNUSED(context);
/* XXX:
* TODO:
* I think instead of clobbering the nav handler, I can let the scene event handler
* deal with ignoring back and then dealing with inputs
*/

return true;
}
//static bool pokemon_scene_exit_confirm_back_event_callback(void* context) {
// UNUSED(context);

// return true;
//}

static void pokemon_scene_exit_confirm_dialog_callback(DialogExResult result, void* context) {
PokemonFap* pokemon_fap = context;

scene_manager_handle_custom_event(pokemon_fap->scene_manager, result);
view_dispatcher_send_custom_event(pokemon_fap->view_dispatcher, result);
}

void pokemon_scene_exit_confirm_on_enter(void* context) {
Expand Down Expand Up @@ -46,12 +52,11 @@ void pokemon_scene_exit_confirm_on_enter(void* context) {
* back events. Going back to the main menu as well as going back to the
* gen menu will re-enable the proper navigation handler.
*/
view_dispatcher_set_navigation_event_callback(
pokemon_fap->view_dispatcher, pokemon_scene_exit_confirm_back_event_callback);
/* XXX: Test this */
//view_dispatcher_set_navigation_event_callback(
// pokemon_fap->view_dispatcher, pokemon_scene_exit_confirm_back_event_callback);

view_dispatcher_add_view(
pokemon_fap->view_dispatcher, AppViewOpts, dialog_ex_get_view(pokemon_fap->dialog_ex));
view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewOpts);
view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewDialogEx);
}

bool pokemon_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) {
Expand Down Expand Up @@ -91,9 +96,6 @@ bool pokemon_scene_exit_confirm_on_event(void* context, SceneManagerEvent event)
}

void pokemon_scene_exit_confirm_on_exit(void* context) {
PokemonFap* pokemon_fap = (PokemonFap*)context;

view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewMainMenu);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewOpts);
UNUSED(context);
}

Loading

0 comments on commit 7a2ddb0

Please sign in to comment.