summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2019-08-27 11:34:27 -0700
committerVito Caputo <vcaputo@pengaru.com>2019-08-27 11:34:27 -0700
commit71c5db7476d8deadfa785570ae63732445b10e85 (patch)
treee39c31097505eb59daed6d675126bf619e356a0b
parent83a324a7d4a2c3e0a75148c918171b14f77dd371 (diff)
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.
-rw-r--r--src/stage.c51
-rw-r--r--src/stage.h17
2 files changed, 35 insertions, 33 deletions
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;
diff --git a/src/stage.h b/src/stage.h
index 86d2311..a73a5d9 100644
--- a/src/stage.h
+++ b/src/stage.h
@@ -27,22 +27,25 @@ typedef void (stage_render_func_t)(const stage_t *stage, void *object, float alp
typedef void (stage_free_func_t)(const stage_t *stage, void *object);
typedef stage_t * (stage_lookup_func_t)(const stage_t *stage, void *object, void *key);
+typedef struct stage_ops_t {
+ stage_prepare_func_t *prepare_func; /* pre-render object */
+ stage_render_func_t *render_func; /* render object */
+ stage_free_func_t *free_func; /* free object */
+ stage_lookup_func_t *lookup_func; /* lookup object against key */
+} stage_ops_t;
+
typedef struct stage_conf_t {
stage_t *parent;
int layer;
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;
float alpha;
unsigned active:1;
unsigned locked:1;
} stage_conf_t;
-stage_t * stage_new(const stage_conf_t *conf);
-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);
+stage_t * stage_new(const stage_conf_t *conf, const stage_ops_t *ops, void *object);
+void stage_replace(stage_t *stage, const char *name, const stage_ops_t *ops, void *object);
+
stage_t * stage_free(stage_t *stage);
int stage_render(stage_t *stage, void *render_ctxt);
void stage_dirty(stage_t *stage);
© All Rights Reserved