From 7c359879af46c63d93ad9190a18da04bbeb492bb Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Thu, 9 May 2019 21:03:41 -0700 Subject: 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. --- src/stage.c | 27 +++++++++++++++++++++++++++ src/stage.h | 1 + 2 files changed, 28 insertions(+) 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; +} diff --git a/src/stage.h b/src/stage.h index b273b7b..31f134a 100644 --- a/src/stage.h +++ b/src/stage.h @@ -41,5 +41,6 @@ void stage_set_locked(stage_t *stage, int locked); int stage_get_locked(const stage_t *stage); void stage_set_layer(stage_t *stage, int layer); stage_t * stage_lookup_name(stage_t *stage, const char *name); +stage_t * stage_lookup_key(stage_t *stage, void *key); #endif -- cgit v1.2.3