From 55ce5773333b41229798c2a9b238812660707b7d Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 12 Jun 2020 22:39:15 -0700 Subject: libstage: add return value to stage_render_func_t This introduces some stage_render() flow control and render-time freeing of nodes via the nodes render_func(). It's particularly useful for one-shot ephemeral nodes which are thrown on-screen and require nothing more than their render and free funcs for a full lifecycle. An example would be something running an effect briefly which runs autonomously from just a timer alone, returning the free request from the final render once the ending time arrives. --- src/stage.c | 28 +++++++++++++++++++++------- src/stage.h | 8 +++++++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/stage.c b/src/stage.c index a714f1f..63afbcb 100644 --- a/src/stage.c +++ b/src/stage.c @@ -302,19 +302,33 @@ static void _prepare_stage(stage_t *stage, float alpha, void *render_ctxt) } -static void _render_stage(const stage_t *stage, float alpha, void *render_ctxt) +static void _render_stage(stage_t *stage, float alpha, void *render_ctxt) { - float a = alpha * stage->alpha; + stage_render_func_ret_t r = STAGE_RENDER_FUNC_RET_CONTINUE; + float a; assert(stage); + a = alpha * stage->alpha; + if (stage->ops->render_func) - stage->ops->render_func(stage, stage->object, a, render_ctxt); + r = stage->ops->render_func(stage, stage->object, a, render_ctxt); + + switch (r) { + case STAGE_RENDER_FUNC_RET_FREE: + stage_free(stage); + case STAGE_RENDER_FUNC_RET_SKIP: + return; + case STAGE_RENDER_FUNC_RET_CONTINUE: + break; + default: + assert(0); + } for (int i = 0; i < STAGE_LAYERS_MAX; i++) { - stage_t *s; + stage_t *s, *_s; - DLL_FOR_EACH_ENTRY(&stage->layers[i], s, stage_t, layer) { + DLL_FOR_EACH_ENTRY_SAFE(&stage->layers[i], s, _s, stage_t, layer) { if (!s->active) continue; @@ -342,11 +356,11 @@ int stage_render(stage_t *stage, void *render_ctxt) _prepare_stage(stage, 1.f, render_ctxt); if (stage->dirty) { + stage->dirty = 0; + if (stage->active) _render_stage(stage, 1.f, render_ctxt); - stage->dirty = 0; - return 1; } diff --git a/src/stage.h b/src/stage.h index 40f2057..b64e095 100644 --- a/src/stage.h +++ b/src/stage.h @@ -22,8 +22,14 @@ typedef struct stage_t stage_t; +typedef enum stage_render_func_ret_t { + STAGE_RENDER_FUNC_RET_CONTINUE, + STAGE_RENDER_FUNC_RET_SKIP, + STAGE_RENDER_FUNC_RET_FREE +} stage_render_func_ret_t; + typedef void (stage_prepare_func_t)(stage_t *stage, void *object, float alpha, void *render_ctxt); -typedef void (stage_render_func_t)(const stage_t *stage, void *object, float alpha, void *render_ctxt); +typedef stage_render_func_ret_t (stage_render_func_t)(const stage_t *stage, void *object, float alpha, void *render_ctxt); typedef void (stage_free_func_t)(const stage_t *stage, void *object); typedef struct stage_ops_t { -- cgit v1.2.3