mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Generalise the midend serialisation callbacks.
These are currently only used for internal serialisation of midend state in order to undo/redo across New Game, and are named accordingly. But I'm about to reuse them for another set of serialisation functions, so they'll want more general names, and also need to be moved higher up in the source file so as to have been defined where I'll want to use them.
This commit is contained in:
56
midend.c
56
midend.c
@ -30,6 +30,11 @@ struct midend_serialise_buf {
|
|||||||
int len, size;
|
int len, size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct midend_serialise_buf_read_ctx {
|
||||||
|
struct midend_serialise_buf *ser;
|
||||||
|
int len, pos;
|
||||||
|
};
|
||||||
|
|
||||||
struct midend {
|
struct midend {
|
||||||
frontend *frontend;
|
frontend *frontend;
|
||||||
random_state *random;
|
random_state *random;
|
||||||
@ -477,7 +482,7 @@ void midend_force_redraw(midend *me)
|
|||||||
midend_redraw(me);
|
midend_redraw(me);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void newgame_serialise_write(void *ctx, const void *buf, int len)
|
static void midend_serialise_buf_write(void *ctx, const void *buf, int len)
|
||||||
{
|
{
|
||||||
struct midend_serialise_buf *ser = (struct midend_serialise_buf *)ctx;
|
struct midend_serialise_buf *ser = (struct midend_serialise_buf *)ctx;
|
||||||
int new_len;
|
int new_len;
|
||||||
@ -492,6 +497,18 @@ static void newgame_serialise_write(void *ctx, const void *buf, int len)
|
|||||||
ser->len = new_len;
|
ser->len = new_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool midend_serialise_buf_read(void *ctx, void *buf, int len)
|
||||||
|
{
|
||||||
|
struct midend_serialise_buf_read_ctx *const rctx = ctx;
|
||||||
|
|
||||||
|
if (len > rctx->len - rctx->pos)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
memcpy(buf, rctx->ser->buf + rctx->pos, len);
|
||||||
|
rctx->pos += len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void midend_new_game(midend *me)
|
void midend_new_game(midend *me)
|
||||||
{
|
{
|
||||||
me->newgame_undo.len = 0;
|
me->newgame_undo.len = 0;
|
||||||
@ -511,7 +528,7 @@ void midend_new_game(midend *me)
|
|||||||
* worse, valid but wrong.
|
* worse, valid but wrong.
|
||||||
*/
|
*/
|
||||||
midend_purge_states(me);
|
midend_purge_states(me);
|
||||||
midend_serialise(me, newgame_serialise_write, &me->newgame_undo);
|
midend_serialise(me, midend_serialise_buf_write, &me->newgame_undo);
|
||||||
}
|
}
|
||||||
|
|
||||||
midend_stop_anim(me);
|
midend_stop_anim(me);
|
||||||
@ -640,23 +657,6 @@ bool midend_can_redo(midend *me)
|
|||||||
return (me->statepos < me->nstates || me->newgame_redo.len);
|
return (me->statepos < me->nstates || me->newgame_redo.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct newgame_undo_deserialise_read_ctx {
|
|
||||||
struct midend_serialise_buf *ser;
|
|
||||||
int len, pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool newgame_undo_deserialise_read(void *ctx, void *buf, int len)
|
|
||||||
{
|
|
||||||
struct newgame_undo_deserialise_read_ctx *const rctx = ctx;
|
|
||||||
|
|
||||||
if (len > rctx->len - rctx->pos)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
memcpy(buf, rctx->ser->buf + rctx->pos, len);
|
|
||||||
rctx->pos += len;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct newgame_undo_deserialise_check_ctx {
|
struct newgame_undo_deserialise_check_ctx {
|
||||||
bool refused;
|
bool refused;
|
||||||
};
|
};
|
||||||
@ -726,7 +726,7 @@ static bool midend_undo(midend *me)
|
|||||||
me->dir = -1;
|
me->dir = -1;
|
||||||
return true;
|
return true;
|
||||||
} else if (me->newgame_undo.len) {
|
} else if (me->newgame_undo.len) {
|
||||||
struct newgame_undo_deserialise_read_ctx rctx;
|
struct midend_serialise_buf_read_ctx rctx;
|
||||||
struct newgame_undo_deserialise_check_ctx cctx;
|
struct newgame_undo_deserialise_check_ctx cctx;
|
||||||
struct midend_serialise_buf serbuf;
|
struct midend_serialise_buf serbuf;
|
||||||
|
|
||||||
@ -737,14 +737,14 @@ static bool midend_undo(midend *me)
|
|||||||
*/
|
*/
|
||||||
serbuf.buf = NULL;
|
serbuf.buf = NULL;
|
||||||
serbuf.len = serbuf.size = 0;
|
serbuf.len = serbuf.size = 0;
|
||||||
midend_serialise(me, newgame_serialise_write, &serbuf);
|
midend_serialise(me, midend_serialise_buf_write, &serbuf);
|
||||||
|
|
||||||
rctx.ser = &me->newgame_undo;
|
rctx.ser = &me->newgame_undo;
|
||||||
rctx.len = me->newgame_undo.len; /* copy for reentrancy safety */
|
rctx.len = me->newgame_undo.len; /* copy for reentrancy safety */
|
||||||
rctx.pos = 0;
|
rctx.pos = 0;
|
||||||
cctx.refused = false;
|
cctx.refused = false;
|
||||||
deserialise_error = midend_deserialise_internal(
|
deserialise_error = midend_deserialise_internal(
|
||||||
me, newgame_undo_deserialise_read, &rctx,
|
me, midend_serialise_buf_read, &rctx,
|
||||||
newgame_undo_deserialise_check, &cctx);
|
newgame_undo_deserialise_check, &cctx);
|
||||||
if (cctx.refused) {
|
if (cctx.refused) {
|
||||||
/*
|
/*
|
||||||
@ -777,7 +777,8 @@ static bool midend_undo(midend *me)
|
|||||||
* the midend so that we can redo back into it later.
|
* the midend so that we can redo back into it later.
|
||||||
*/
|
*/
|
||||||
me->newgame_redo.len = 0;
|
me->newgame_redo.len = 0;
|
||||||
newgame_serialise_write(&me->newgame_redo, serbuf.buf, serbuf.len);
|
midend_serialise_buf_write(&me->newgame_redo,
|
||||||
|
serbuf.buf, serbuf.len);
|
||||||
|
|
||||||
sfree(serbuf.buf);
|
sfree(serbuf.buf);
|
||||||
return true;
|
return true;
|
||||||
@ -799,7 +800,7 @@ static bool midend_redo(midend *me)
|
|||||||
me->dir = +1;
|
me->dir = +1;
|
||||||
return true;
|
return true;
|
||||||
} else if (me->newgame_redo.len) {
|
} else if (me->newgame_redo.len) {
|
||||||
struct newgame_undo_deserialise_read_ctx rctx;
|
struct midend_serialise_buf_read_ctx rctx;
|
||||||
struct newgame_undo_deserialise_check_ctx cctx;
|
struct newgame_undo_deserialise_check_ctx cctx;
|
||||||
struct midend_serialise_buf serbuf;
|
struct midend_serialise_buf serbuf;
|
||||||
|
|
||||||
@ -810,14 +811,14 @@ static bool midend_redo(midend *me)
|
|||||||
*/
|
*/
|
||||||
serbuf.buf = NULL;
|
serbuf.buf = NULL;
|
||||||
serbuf.len = serbuf.size = 0;
|
serbuf.len = serbuf.size = 0;
|
||||||
midend_serialise(me, newgame_serialise_write, &serbuf);
|
midend_serialise(me, midend_serialise_buf_write, &serbuf);
|
||||||
|
|
||||||
rctx.ser = &me->newgame_redo;
|
rctx.ser = &me->newgame_redo;
|
||||||
rctx.len = me->newgame_redo.len; /* copy for reentrancy safety */
|
rctx.len = me->newgame_redo.len; /* copy for reentrancy safety */
|
||||||
rctx.pos = 0;
|
rctx.pos = 0;
|
||||||
cctx.refused = false;
|
cctx.refused = false;
|
||||||
deserialise_error = midend_deserialise_internal(
|
deserialise_error = midend_deserialise_internal(
|
||||||
me, newgame_undo_deserialise_read, &rctx,
|
me, midend_serialise_buf_read, &rctx,
|
||||||
newgame_undo_deserialise_check, &cctx);
|
newgame_undo_deserialise_check, &cctx);
|
||||||
if (cctx.refused) {
|
if (cctx.refused) {
|
||||||
/*
|
/*
|
||||||
@ -850,7 +851,8 @@ static bool midend_redo(midend *me)
|
|||||||
* the midend so that we can undo back into it later.
|
* the midend so that we can undo back into it later.
|
||||||
*/
|
*/
|
||||||
me->newgame_undo.len = 0;
|
me->newgame_undo.len = 0;
|
||||||
newgame_serialise_write(&me->newgame_undo, serbuf.buf, serbuf.len);
|
midend_serialise_buf_write(&me->newgame_undo,
|
||||||
|
serbuf.buf, serbuf.len);
|
||||||
|
|
||||||
sfree(serbuf.buf);
|
sfree(serbuf.buf);
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user