From c17f5a5377f959a7e67526e0ae89b329bf99a101 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Wed, 16 Jan 2019 07:15:26 -0500 Subject: solve in background thread --- src/sdl/main.c | 117 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 45 deletions(-) (limited to 'src/sdl/main.c') diff --git a/src/sdl/main.c b/src/sdl/main.c index c3a9abe..8e96fa5 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -12,25 +12,7 @@ #include "draw.h" #include "log-renderer-info.h" #include "assets.h" - -static void -log_moves( - const sok_ctx_t * const ctx, - const size_t skip_moves -) { - char buf[1024] = { 0 }; - size_t ofs = 0; - - for (size_t i = skip_moves; i < ctx->num_moves; i++) { - if (ctx->moves[i].dir >= SOK_DIR_LAST) { - die("invalid move: %u", ctx->moves[i].dir); - } - - buf[ofs++] = SOK_DIR_TO_CHAR(ctx->moves[i].dir); - } - - SDL_Log("Solution (%d moves): %s", (int) (ctx->num_moves - skip_moves), buf); -} +#include "solve.h" static TTF_Font * load_font( @@ -58,20 +40,6 @@ load_font( return font; } -static void -solve_on_error( - const char * const err, - void *user_data -) { - UNUSED(user_data); - die("Error solving level: %s", err); -} - -static const sok_solve_cbs_t -SOLVE_CBS = { - .on_error = solve_on_error, -}; - static void set_level( draw_ctx_t * const draw_ctx, @@ -95,6 +63,41 @@ set_level( ); } +static void +log_moves( + const sok_ctx_t * const ctx +) { + char buf[1024] = { 0 }; + size_t ofs = 0; + + for (size_t i = 0; i < ctx->num_moves; i++) { + if (ctx->moves[i].dir >= SOK_DIR_LAST) { + die("invalid move: %u", ctx->moves[i].dir); + } + + buf[ofs++] = SOK_DIR_TO_CHAR(ctx->moves[i].dir); + } + + SDL_Log("Solution (%d moves): %s", (int) ctx->num_moves, buf); +} + +static void +solve_on_done( + const bool result, + const sok_ctx_t * const solved_ctx, + const size_t num_steps, + void *user_data +) { + if (result) { + // copy context + sok_ctx_t *ctx = user_data; + *ctx = *solved_ctx; + + // log moves + log_moves(ctx); + } +} + int main(int argc, char *argv[]) { size_t level_num = (argc > 1) ? atoi(argv[1]) : 0, zoom = 0; @@ -154,6 +157,7 @@ int main(int argc, char *argv[]) { // init draw context draw_ctx_t draw_ctx = { + .state = GAME_STATE_PLAY, .level_num = &level_num, .ctx = &ctx, .renderer = renderer, @@ -168,6 +172,12 @@ int main(int argc, char *argv[]) { sprites_init(renderer, draw_ctx.sprites); draw_ctx.font = load_font(ASSET_ROBOTO_TTF); + // register solve event + const Uint32 solve_event_type = SDL_RegisterEvents(1); + if (solve_event_type == ((Uint32)-1)) { + die("SDL_RegisterEvents(): %s", SDL_GetError()); + } + bool is_fullscreen = false; bool done = false; while (!done) { @@ -176,7 +186,7 @@ int main(int argc, char *argv[]) { // read events while (SDL_PollEvent(&ev)) { // get action - const action_t action = get_action(&ev); + const action_t action = get_action(draw_ctx.state, &ev, solve_event_type); // handle action switch (action.type) { @@ -236,17 +246,9 @@ int main(int argc, char *argv[]) { break; case ACTION_SOLVE: - { - // get current number of moves - const size_t old_num_moves = ctx.num_moves; - - if (sok_solve(&ctx, &SOLVE_CBS, NULL)) { - // found solution, print it - log_moves(&ctx, old_num_moves); - } else { - warn("Couldn't solve level"); - } - } + draw_ctx.state = GAME_STATE_SOLVE; + draw_ctx.solve_num_steps = 0; + draw_ctx.solve = solve(&ctx, solve_event_type); break; case ACTION_ZOOM_IN: @@ -269,6 +271,31 @@ int main(int argc, char *argv[]) { // toggle flag is_fullscreen = !is_fullscreen; + break; + case ACTION_SOLVE_CANCEL: + SDL_Log("solve cancelled by user"); + draw_ctx.state = GAME_STATE_PLAY; + solve_cancel(draw_ctx.solve); + + break; + case ACTION_SOLVE_EVENT_STEP: + draw_ctx.solve_num_steps = action.data; + + break; + case ACTION_SOLVE_EVENT_DONE: + SDL_Log("solve done"); + draw_ctx.state = GAME_STATE_PLAY; + // TODO: handle success + solve_fini(draw_ctx.solve, solve_on_done, &ctx); + draw_ctx.solve = NULL; + + break; + case ACTION_SOLVE_EVENT_FAIL: + SDL_Log("solve fail"); + draw_ctx.state = GAME_STATE_PLAY; + solve_fini(draw_ctx.solve, NULL, NULL); + draw_ctx.solve = NULL; + break; default: // ignore -- cgit v1.2.3