I've just realised that the JS puzzles' permalinks were not updating

when the user pressed 'n' for a new game, because all the front end
knows is that it passed a keystroke to the puzzle, and it has no way
of hearing back that a particular keypress resulted in a game id
change.

To fix this, I've renamed midend_request_desc_changes to
midend_request_id_changes and expanded its remit to cover _any_ change
to the game ids. So now that callback in the Emscripten front end is
the only place from which update_permalinks is called (apart from
initialising them at setup time), and that should handle everything.

[originally from svn r9805]
This commit is contained in:
Simon Tatham
2013-04-05 15:49:20 +00:00
parent 841c9318f3
commit 8f87f2ce89
4 changed files with 27 additions and 30 deletions

View File

@ -1609,10 +1609,6 @@ should use it if they're not Mines; if you think you need to use it,
think again repeatedly in the hope of finding a better way to do
whatever it was you needed to do.
If a front end wants to be notified when this happens, it can ask the
midend to do so by calling \cw{midend_request_desc_changes()}; see
\k{midend-request-desc-changes}.
\C{drawing} The drawing API
The back end function \cw{redraw()} (\k{backend-redraw}) is required
@ -3274,17 +3270,18 @@ message (which does not need freeing at all).
accept or return a pointer to a midend. You'd probably call it just
\e{before} deciding what kind of midend you wanted to instantiate.)
\H{midend-request-desc-changes} \cw{midend_request_desc_changes()}
\H{midend-request-id-changes} \cw{midend_request_id_changes()}
\c void midend_request_desc_changes(midend *me,
\c void (*notify)(void *), void *ctx);
\c void midend_request_id_changes(midend *me,
\c void (*notify)(void *), void *ctx);
This function is called by the front end to request notification by
the mid-end when a puzzle supersedes its game description (see
\k{backend-supersede}). After this function is called, any call to
\cw{midend_supersede_game_desc()} by the back end will cause the
mid-end to call \cw{notify(ctx)} after the game description is
changed.
the mid-end when the current game IDs (either descriptive or
random-seed) change. This can occur as a result of keypresses ('n' for
New Game, for example) or when a puzzle supersedes its game
description (see \k{backend-supersede}). After this function is
called, any change of the game ids will cause the mid-end to call
\cw{notify(ctx)} after the change.
This is for use by puzzles which want to present the game description
to the user constantly (e.g. as an HTML hyperlink) instead of only

16
emcc.c
View File

@ -313,10 +313,10 @@ static void update_permalinks(void)
}
/*
* Callback from the midend if Mines supersedes its game description,
* so we can update the permalinks.
* Callback from the midend when the game ids change, so we can update
* the permalinks.
*/
static void desc_changed(void *ignored)
static void ids_changed(void *ignored)
{
update_permalinks();
}
@ -598,7 +598,6 @@ static void cfg_end(int use_results)
midend_new_game(me);
resize();
midend_redraw(me);
update_permalinks();
free_cfg(cfg);
js_dialog_cleanup();
}
@ -653,7 +652,6 @@ void command(int n)
*/
midend_set_params(me, presets[i]);
midend_new_game(me);
update_permalinks();
resize();
midend_redraw(me);
update_undo_redo();
@ -802,11 +800,11 @@ int main(int argc, char **argv)
}
/*
* Request notification if a puzzle (hopefully only ever Mines)
* supersedes its game description, so that we can proactively
* update the permalink.
* Request notification when the game ids change (e.g. if the user
* presses 'n', and also when Mines supersedes its game
* description), so that we can proactively update the permalink.
*/
midend_request_desc_changes(me, desc_changed, NULL);
midend_request_id_changes(me, ids_changed, NULL);
/*
* Draw the puzzle's initial state, and set up the permalinks and

View File

@ -82,8 +82,8 @@ struct midend {
int preferred_tilesize, tilesize, winwidth, winheight;
void (*game_desc_change_notify_function)(void *);
void *game_desc_change_notify_ctx;
void (*game_id_change_notify_function)(void *);
void *game_id_change_notify_ctx;
};
#define ensure(me) do { \
@ -499,6 +499,9 @@ void midend_new_game(midend *me)
me->ui = me->ourgame->new_ui(me->states[0].state);
midend_set_timer(me);
me->pressed_mouse_button = 0;
if (me->game_id_change_notify_function)
me->game_id_change_notify_function(me->game_id_change_notify_ctx);
}
int midend_can_undo(midend *me)
@ -1082,10 +1085,10 @@ int midend_wants_statusbar(midend *me)
return me->ourgame->wants_statusbar;
}
void midend_request_desc_changes(midend *me, void (*notify)(void *), void *ctx)
void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx)
{
me->game_desc_change_notify_function = notify;
me->game_desc_change_notify_ctx = ctx;
me->game_id_change_notify_function = notify;
me->game_id_change_notify_ctx = ctx;
}
void midend_supersede_game_desc(midend *me, char *desc, char *privdesc)
@ -1094,8 +1097,8 @@ void midend_supersede_game_desc(midend *me, char *desc, char *privdesc)
sfree(me->privdesc);
me->desc = dupstr(desc);
me->privdesc = privdesc ? dupstr(privdesc) : NULL;
if (me->game_desc_change_notify_function)
me->game_desc_change_notify_function(me->game_desc_change_notify_ctx);
if (me->game_id_change_notify_function)
me->game_id_change_notify_function(me->game_id_change_notify_ctx);
}
config_item *midend_get_config(midend *me, int which, char **wintitle)

View File

@ -268,8 +268,7 @@ char *midend_deserialise(midend *me,
void *rctx);
char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len),
void *rctx);
void midend_request_desc_changes(midend *me, void (*notify)(void *),
void *ctx);
void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx);
/* Printing functions supplied by the mid-end */
char *midend_print_puzzle(midend *me, document *doc, int with_soln);
int midend_tilesize(midend *me);