Skip to content

Commit

Permalink
pokemon: refactor
Browse files Browse the repository at this point in the history
This accomplishes a few things:
- Retype vars introduced in previous commits to match format of
    existing project code.
- Move common elements to a single struct for the whole application.
    This also removes the struct for each of the two current views
    and passes around the main struct as callback contexts.
- Remove the use of view models as copies of data and instead point
    the model for each view at the main struct. All of the draw
    callbacks for existing views end up needing this data and only
    have access to a view model at runtime.
- Partial cleanup of circular dependencies and unneeded variables.
    Some headers had circular includes which would compile but
    caused issues.
  • Loading branch information
kbembedded committed Sep 15, 2023
1 parent a75ac8f commit 4277b04
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 265 deletions.
71 changes: 42 additions & 29 deletions pokemon_app.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "pokemon_app.h"
#include "views/trade.hpp"
#include "views/select_pokemon.hpp"

struct pokemon_lut pokemon_table[] = {
const PokemonTable pokemon_table[] = {
{"Bulbasaur", &I_bulbasaur, 0x99},
{"Ivysaur", &I_ivysaur, 0x09},
{"Venusaur", &I_venusaur, 0x9A},
Expand Down Expand Up @@ -159,66 +161,77 @@ uint32_t pokemon_exit_confirm_view(void* context) {
UNUSED(context);
return AppViewExitConfirm;
}
App* pokemon_alloc() {
App* app = (App*)malloc(sizeof(App));

PokemonFap* pokemon_alloc() {
PokemonFap* pokemon_fap = (PokemonFap*)malloc(sizeof(PokemonFap));

// Gui
app->gui = (Gui*)furi_record_open(RECORD_GUI);
/* XXX: what is furi_record open for? It doesn't return a Gui handle. */
pokemon_fap->gui = (Gui*)furi_record_open(RECORD_GUI);

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

view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_enable_queue(pokemon_fap->view_dispatcher);
view_dispatcher_set_event_callback_context(pokemon_fap->view_dispatcher, pokemon_fap);
view_dispatcher_attach_to_gui(
pokemon_fap->view_dispatcher, pokemon_fap->gui, ViewDispatcherTypeFullscreen);

// Start Index first pokemon
app->current_pokemon = 0;
pokemon_fap->curr_pokemon = 0;

// Set up pointer to pokemon table
pokemon_fap->pokemon_table = pokemon_table;

// Select Pokemon View
app->select_pokemon = select_pokemon_alloc(app);
view_set_previous_callback(select_pokemon_get_view(app), pokemon_exit_confirm_view);
pokemon_fap->select_view = select_pokemon_alloc(pokemon_fap);
view_set_previous_callback(select_pokemon_get_view(pokemon_fap), pokemon_exit_confirm_view);
view_dispatcher_add_view(
app->view_dispatcher, AppViewSelectPokemon, select_pokemon_get_view(app));
pokemon_fap->view_dispatcher, AppViewSelectPokemon, select_pokemon_get_view(pokemon_fap));

// Trade View
app->trade = trade_alloc(app);
view_set_previous_callback(trade_get_view(app), pokemon_exit_confirm_view);
view_dispatcher_add_view(app->view_dispatcher, AppViewTrade, trade_get_view(app));
pokemon_fap->trade_view = trade_alloc(pokemon_fap);
view_set_previous_callback(pokemon_fap->trade_view, pokemon_exit_confirm_view);
view_dispatcher_add_view(pokemon_fap->view_dispatcher, AppViewTrade, pokemon_fap->trade_view);

view_dispatcher_switch_to_view(app->view_dispatcher, AppViewSelectPokemon);
view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewSelectPokemon);

return app;
return pokemon_fap;
}

void free_app(App* app) {
furi_assert(app);
void free_app(PokemonFap* pokemon_fap) {
furi_assert(pokemon_fap);

// Free views
view_dispatcher_remove_view(app->view_dispatcher, AppViewSelectPokemon);
select_pokemon_free(app);
view_dispatcher_remove_view(app->view_dispatcher, AppViewTrade);
trade_free(app);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewSelectPokemon);
/* XXX: Still need to deal with select_pokemon code */
select_pokemon_free(pokemon_fap);
view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewTrade);
trade_free(pokemon_fap);
// Close records
furi_record_close(RECORD_GUI);
app->gui = NULL;
/* XXX: Since furi_record doesn't appear to be a Gui function, it wouldn't clear the pointer */
pokemon_fap->gui = NULL;

// Free rest
free(app);
free(pokemon_fap);
pokemon_fap = NULL;
}

extern "C" int32_t pokemon_app(void* p) {
UNUSED(p);
//FURI_LOG_D(TAG, "init scene");
App* app = (App*)pokemon_alloc();
//App* app = (App*)pokemon_alloc();
PokemonFap* pokemon_fap = pokemon_alloc();

furi_hal_light_set(LightRed, 0x00);
furi_hal_light_set(LightGreen, 0x00);
furi_hal_light_set(LightBlue, 0x00);
//switch view and run dispatcher
view_dispatcher_run(app->view_dispatcher);
view_dispatcher_run(pokemon_fap->view_dispatcher);

// Free resources
free_app(app);
furi_record_close(RECORD_GUI);
free_app(pokemon_fap);

return 0;
}
53 changes: 35 additions & 18 deletions pokemon_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@
#include <gui/icon.h>
#include <pokemon_icons.h>

#include "views/select_pokemon.hpp"
#include "views/trade.hpp"

#define TAG "Pokemon"

struct pokemon_lut {
struct pokemon_data_table {
const char* name;
const Icon* icon;
const uint8_t hex;
};

typedef struct App App;
typedef struct pokemon_data_table PokemonTable;

typedef enum {
GAMEBOY_INITIAL,
GAMEBOY_READY,
Expand All @@ -32,6 +30,7 @@ typedef enum {
GAMEBOY_TRADING
} render_gameboy_state_t;

#if 0
struct App {
Gui* gui;
ViewDispatcher* view_dispatcher;
Expand All @@ -42,24 +41,42 @@ struct App {
int current_pokemon = 0;
char pokemon_hex_code = ' ';
};
#endif

struct pokemon_fap {
Gui* gui;
ViewDispatcher* view_dispatcher;

/* View ports for each of the application's steps */
View* select_view;
View* trade_view;

/* Table of pokemon data for Gen I */
const PokemonTable* pokemon_table;

/* The currently selected pokemon */
int curr_pokemon;

/* Some state tracking */
/* This, combined with some globals in trade.cpp, can probably be better
* consolidated at some point.
*/
bool trading;
bool connected;
render_gameboy_state_t gameboy_status;

/* TODO: Other variables will end up here, like selected level, EV/IV,
* moveset, etc. Likely will want to be another sub struct similar to
* the actual pokemon data structure.
*/
};

typedef struct pokemon_fap PokemonFap;

typedef enum {
AppViewSelectPokemon,
AppViewTrade,
AppViewExitConfirm,
} AppView;

typedef void (*SelectPokemonCallback)(void* context, uint32_t index);
typedef struct SelectPokemonModel {
int current_pokemon = 0;
char pokemon_hex_code = ' ';
bool trading = false;
bool connected = false;
render_gameboy_state_t gameboy_status = GAMEBOY_INITIAL;
SelectPokemonCallback callback;
void* callback_context;
} SelectPokemonModel;

extern struct pokemon_lut pokemon_table[];

#endif /* POKEMON_APP_H */
Loading

0 comments on commit 4277b04

Please sign in to comment.