diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2019-05-09 21:03:41 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2019-05-10 14:18:28 -0700 |
commit | 7c359879af46c63d93ad9190a18da04bbeb492bb (patch) | |
tree | 0e81f40e5cf284ef7e11ddfd96cc95da7376e039 /src/stage.c | |
parent | f42c1887f3212c56e5c69a5f1ac26b80aabda1d9 (diff) |
libstage: add stage_lookup_key()
This is identical to stage_lookup_name() except instead of comparing
the name, it calls the per-stage stage_match_func_t with the supplied
key and returns the first match according to the match func.
By supplying a spatial key like a &(vec2){x,y}, and match funcs that
can test the vec2 against their respective stage object for overlap,
simple spatial searches can be performed against the stage heirarchy.
This isn't optimized or anything, but for simple scenes it can be
convenient. Things like simple game menus might have a stage node
per menu entry and event handlers can just search the stage with
the X,Y coordinates of the events to map events to visual elements.
Diffstat (limited to 'src/stage.c')
-rw-r--r-- | src/stage.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/stage.c b/src/stage.c index 10a7f0a..a2c6e2d 100644 --- a/src/stage.c +++ b/src/stage.c @@ -310,3 +310,30 @@ stage_t * stage_lookup_name(stage_t *stage, const char *name) return NULL; } + + +/* lookup a stage by an opaque key using the per-stage match_func when present, + * returns first match, does not support multiple matches. + * Intended for rudimentary non-overlapping spatial searches like picking of + * basic 2D UI elements. + */ +stage_t * stage_lookup_key(stage_t *stage, void *key) +{ + assert(stage); + + if (stage->match && stage->match(stage, stage->object, key)) + return stage; + + for (int i = 0; i < STAGE_LAYERS_MAX; i++) { + stage_t *s; + + DLL_FOR_EACH_ENTRY(&stage->layers[i], s, stage_t, layer) { + stage_t *match = stage_lookup_key(s, key); + + if (match) + return match; + } + } + + return NULL; +} |