Introduce a mechanism by which calls to midend_supersede_game_desc()

can trigger a call to a front end notification function. Use this to
update the game ID permalink when Mines supersedes its game ID.

[originally from svn r9793]
This commit is contained in:
Simon Tatham
2013-03-31 09:58:52 +00:00
parent bf696f83fc
commit bb14689b4a
4 changed files with 54 additions and 0 deletions

View File

@ -1609,6 +1609,10 @@ 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
@ -3270,6 +3274,27 @@ 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()}
\c void midend_request_desc_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.
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
showing it when the user explicitly requests it.
This is a function I anticipate few front ends needing to implement,
so I make it a callback rather than a static function in order to
relieve most front ends of the need to provide an empty
implementation.
\H{frontend-backend} Direct reference to the back end structure by
the front end

16
emcc.c
View File

@ -309,6 +309,15 @@ static void update_permalinks(void)
sfree(seed);
}
/*
* Callback from the midend if Mines supersedes its game description,
* so we can update the permalinks.
*/
static void desc_changed(void *ignored)
{
update_permalinks();
}
/* ----------------------------------------------------------------------
* Implementation of the drawing API by calling Javascript canvas
* drawing functions. (Well, half of it; the other half is on the JS
@ -761,6 +770,13 @@ int main(int argc, char **argv)
colour_strings[i] = dupstr(col);
}
/*
* Request notification if a puzzle (hopefully only ever Mines)
* supersedes its game description, so that we can proactively
* update the permalink.
*/
midend_request_desc_changes(me, desc_changed, NULL);
/*
* Draw the puzzle's initial state, and set up the permalinks and
* undo/redo greying out.

View File

@ -81,6 +81,9 @@ struct midend {
int pressed_mouse_button;
int preferred_tilesize, tilesize, winwidth, winheight;
void (*game_desc_change_notify_function)(void *);
void *game_desc_change_notify_ctx;
};
#define ensure(me) do { \
@ -1079,12 +1082,20 @@ int midend_wants_statusbar(midend *me)
return me->ourgame->wants_statusbar;
}
void midend_request_desc_changes(midend *me, void (*notify)(void *), void *ctx)
{
me->game_desc_change_notify_function = notify;
me->game_desc_change_notify_ctx = ctx;
}
void midend_supersede_game_desc(midend *me, char *desc, char *privdesc)
{
sfree(me->desc);
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);
}
config_item *midend_get_config(midend *me, int which, char **wintitle)

View File

@ -268,6 +268,8 @@ 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);
/* Printing functions supplied by the mid-end */
char *midend_print_puzzle(midend *me, document *doc, int with_soln);
int midend_tilesize(midend *me);