From 71c5db7476d8deadfa785570ae63732445b10e85 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Tue, 27 Aug 2019 11:34:27 -0700 Subject: libstage: encapsulate stage funs in an ops struct Introduces stage_ops_t, tidying up stage_new() users. For now the stage_t simply references the passed in ops struct, so the caller must ensure its lifetime survives the referencing stages. That may be annoying if callers tend to construct them as compound literals at the call site, but I don't expect that to be too onerous to avoid. --- src/stage.c | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) (limited to 'src/stage.c') diff --git a/src/stage.c b/src/stage.c index 7a088b3..69976ae 100644 --- a/src/stage.c +++ b/src/stage.c @@ -33,31 +33,30 @@ struct stage_t { unsigned locked:1; /* stage is locked */ unsigned dirty:1; /* stage is dirty (since last render) */ - stage_prepare_func_t *prepare; /* pre-render object */ - stage_render_func_t *render; /* render object */ - stage_free_func_t *free; /* free object */ - stage_lookup_func_t *lookup; /* lookup object against key */ - void *object; /* object */ + const stage_ops_t *ops; /* ops for operating on this stage's object */ + void *object; /* this stage's object */ }; /* minimally initialize a stage to carry an object */ -static void _stage_set_object(stage_t *stage, const char *name, void *object, stage_prepare_func_t *prepare_func, stage_render_func_t *render_func, stage_free_func_t *free_func, stage_lookup_func_t *lookup_func) +static void _stage_set_object(stage_t *stage, const char *name, const stage_ops_t *ops, void *object) { + static stage_ops_t null_ops = {}; + assert(stage); assert(name); + if (!ops) + ops = &null_ops; + strncpy(stage->name, name, sizeof(stage->name)); - stage->prepare = prepare_func; - stage->render = render_func; - stage->free = free_func; - stage->lookup = lookup_func; + stage->ops = ops; stage->object = object; } /* allocate a stage, this purely creates a stage in isolation and assigns its associated name, object and functions */ -static stage_t * _stage_new(const char *name, void *object, stage_prepare_func_t *prepare_func, stage_render_func_t *render_func, stage_free_func_t *free_func, stage_lookup_func_t *lookup_func) +static stage_t * _stage_new(const char *name, const stage_ops_t *ops, void *object) { stage_t *stage; @@ -69,7 +68,7 @@ static stage_t * _stage_new(const char *name, void *object, stage_prepare_func_t for (int i = 0; i < STAGE_LAYERS_MAX; i++) dll_init(&stage->layers[i]); - _stage_set_object(stage, name, object, prepare_func, render_func, free_func, lookup_func); + _stage_set_object(stage, name, ops, object); return stage; } @@ -80,8 +79,8 @@ static void _stage_free(stage_t *stage) { assert(stage); - if (stage->free) - stage->free(stage, stage->object); + if (stage->ops->free_func) + stage->ops->free_func(stage, stage->object); free(stage); } @@ -89,7 +88,7 @@ static void _stage_free(stage_t *stage) /* returns a new stage, attached at the specified layer under parent if supplied */ /* layer has no effect when parent == NULL */ -stage_t * stage_new(const stage_conf_t *conf) +stage_t * stage_new(const stage_conf_t *conf, const stage_ops_t *ops, void *object) { stage_t *stage; @@ -97,7 +96,7 @@ stage_t * stage_new(const stage_conf_t *conf) assert(conf->parent || !conf->layer); assert(conf->layer < STAGE_LAYERS_MAX); - stage = _stage_new(conf->name, conf->object, conf->prepare_func, conf->render_func, conf->free_func, conf->lookup_func); + stage = _stage_new(conf->name, ops, object); if (!stage) return NULL; @@ -115,14 +114,14 @@ stage_t * stage_new(const stage_conf_t *conf) /* replaces a given stage's object-related properties but otherwise keeping the existing state */ -void stage_replace(stage_t *stage, const char *name, void *object, stage_prepare_func_t *prepare_func, stage_render_func_t *render_func, stage_free_func_t *free_func, stage_lookup_func_t *lookup_func) +void stage_replace(stage_t *stage, const char *name, const stage_ops_t *ops, void *object) { assert(stage); - if (stage->free) - stage->free(stage, stage->object); + if (stage->ops->free_func) + stage->ops->free_func(stage, stage->object); - _stage_set_object(stage, name, object, prepare_func, render_func, free_func, lookup_func); + _stage_set_object(stage, name, ops, object); } @@ -268,8 +267,8 @@ static void _prepare_stage(stage_t *stage, float alpha, void *render_ctxt) assert(stage); - if (stage->prepare) - stage->prepare(stage, stage->object, a, render_ctxt); + if (stage->ops->prepare_func) + stage->ops->prepare_func(stage, stage->object, a, render_ctxt); for (int i = 0; i < STAGE_LAYERS_MAX; i++) { stage_t *s; @@ -290,8 +289,8 @@ static void _render_stage(const stage_t *stage, float alpha, void *render_ctxt) assert(stage); - if (stage->render) - stage->render(stage, stage->object, a, render_ctxt); + if (stage->ops->render_func) + stage->ops->render_func(stage, stage->object, a, render_ctxt); for (int i = 0; i < STAGE_LAYERS_MAX; i++) { stage_t *s; @@ -385,8 +384,8 @@ stage_t * stage_lookup_key(stage_t *stage, void *key) { assert(stage); - if (stage->lookup) { - stage_t *hit = (stage_t *)stage->lookup(stage, stage->object, key); + if (stage->ops->lookup_func) { + stage_t *hit = (stage_t *)stage->ops->lookup_func(stage, stage->object, key); if (hit) return hit; -- cgit v1.2.3