chiark / gitweb /
Introduce a mechanism by which calls to midend_supersede_game_desc()
authorSimon Tatham <anakin@pobox.com>
Sun, 31 Mar 2013 09:58:52 +0000 (09:58 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 31 Mar 2013 09:58:52 +0000 (09:58 +0000)
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]

devel.but
emcc.c
midend.c
puzzles.h

index 457e169ff32aa2ab938cbd88bcf6092acdfcf073..5fb200d9eb23837a08e5e4c963602062d80efb11 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -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
 
diff --git a/emcc.c b/emcc.c
index 4116fd1172348842aae6a3a6d21fb646aade4cb6..2a5f788e403486d883ae2a96a1ce4b4b733db931 100644 (file)
--- a/emcc.c
+++ b/emcc.c
@@ -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.
index fddf01d8e6bc65226df6d7c32fddfb559afb3fbc..d55be55edf4cc5bc616b1ae86437b026bb2025fc 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -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)
index fbd1828e2fc54147f9d7e12ba12ade30c9db5698..3da1008ca29e5f6448345cacb2ebd5d234c7ea7f 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -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);