From 19a5965400f9a252adf540050046d2dc3a026d13 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 15 Jan 2019 21:10:27 -0500 Subject: add sok_solve_cbs_t and refactor code to use it --- src/core/sok-solve.c | 30 ++++++++++++++++++++---------- src/core/sok.h | 8 +++++++- src/sdl/main.c | 11 +++++++++-- src/solve/main.c | 11 +++++++++-- src/text/main.c | 11 +++++++++-- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/core/sok-solve.c b/src/core/sok-solve.c index 34a8320..45d227c 100644 --- a/src/core/sok-solve.c +++ b/src/core/sok-solve.c @@ -7,7 +7,8 @@ static bool sok_solve_step( sok_ctx_t * const ctx, sok_cache_t * const cache, - void (*on_error)(const char * const) + const sok_solve_cbs_t * const cbs, + void * const user_data ) { // check for success if (sok_ctx_is_done(ctx)) { @@ -22,15 +23,19 @@ sok_solve_step( // add to cache if (!sok_cache_add(cache, ctx)) { - if (on_error) { + if (cbs && cbs->on_error) { // log error - on_error("sok_cache_add() failed"); + cbs->on_error("sok_cache_add() failed", user_data); } // return failure return false; } + if (cbs && cbs->on_step && !cbs->on_step(ctx, user_data)) { + // return failure + return false; + } /* * // make sure level is solvable * if (sok_ctx_is_lost(ctx)) { @@ -45,16 +50,16 @@ sok_solve_step( } // recurse, check for success - if (sok_solve_step(ctx, cache, on_error)) { + if (sok_solve_step(ctx, cache, cbs, user_data)) { // return success return true; } // undo move if (!sok_ctx_undo(ctx)) { - if (on_error) { + if (cbs && cbs->on_error) { // log error - on_error("sok_ctx_undo() failed"); + cbs->on_error("sok_ctx_undo() failed", user_data); } // return failure @@ -66,20 +71,25 @@ sok_solve_step( return false; } -bool +bool sok_solve( sok_ctx_t * const ctx, - void (*on_error)(const char * const) + const sok_solve_cbs_t * const cbs, + void *user_data ) { // init cache sok_cache_t cache; if (!sok_cache_init(&cache, SOK_CACHE_DEFAULT_CAPACITY)) { - on_error("sok_cache_init() failed"); + if (cbs && cbs->on_error) { + cbs->on_error("sok_cache_init() failed", user_data); + } + + // return failure return false; } // solve - const bool r = sok_solve_step(ctx, &cache, on_error); + const bool r = sok_solve_step(ctx, &cache, cbs, user_data); // finalize cache sok_cache_fini(&cache); diff --git a/src/core/sok.h b/src/core/sok.h index 1503b5f..92fb4e7 100644 --- a/src/core/sok.h +++ b/src/core/sok.h @@ -245,9 +245,15 @@ _Bool sok_cache_add(sok_cache_t * const, const sok_ctx_t * const); /* solve */ /*********/ +typedef struct { + _Bool (*on_step)(const sok_ctx_t *, void *); + void (*on_error)(const char * const, void *); +} sok_solve_cbs_t; + _Bool sok_solve( sok_ctx_t * const, - void (*on_error)(const char * const) + const sok_solve_cbs_t * const, + void * const ); #ifdef __cplusplus diff --git a/src/sdl/main.c b/src/sdl/main.c index 46f30c3..c3a9abe 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -60,11 +60,18 @@ load_font( static void solve_on_error( - const char * const err + 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, @@ -233,7 +240,7 @@ int main(int argc, char *argv[]) { // get current number of moves const size_t old_num_moves = ctx.num_moves; - if (sok_solve(&ctx, solve_on_error)) { + if (sok_solve(&ctx, &SOLVE_CBS, NULL)) { // found solution, print it log_moves(&ctx, old_num_moves); } else { diff --git a/src/solve/main.c b/src/solve/main.c index 140cfc5..b8b966f 100644 --- a/src/solve/main.c +++ b/src/solve/main.c @@ -7,11 +7,18 @@ static void solve_on_error( - const char * const err + 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, +}; + int main(int argc, char *argv[]) { // init context sok_ctx_t ctx; @@ -30,7 +37,7 @@ int main(int argc, char *argv[]) { } // solve level - if (!sok_solve(&ctx, solve_on_error)) { + if (!sok_solve(&ctx, &SOLVE_CBS, NULL)) { die("Couldn't solve level: %d", (int) level_num); } } diff --git a/src/text/main.c b/src/text/main.c index 204da0f..6b7513c 100644 --- a/src/text/main.c +++ b/src/text/main.c @@ -10,11 +10,18 @@ static void solve_on_error( - const char * const err + const char * const err, + void *data ) { + UNUSED(data); die("Error solving level: %s", err); } +static const sok_solve_cbs_t +SOLVE_CBS = { + .on_error = solve_on_error, +}; + static void draw_moves( const sok_ctx_t * const ctx, @@ -104,7 +111,7 @@ int main(int argc, char *argv[]) { // get current number of moves const size_t old_num_moves = ctx.num_moves; - if (sok_solve(&ctx, solve_on_error)) { + if (sok_solve(&ctx, &SOLVE_CBS, NULL)) { // found solution, print it draw_moves(&ctx, old_num_moves); } else { -- cgit v1.2.3