From 9c85fb496e9bdffd438df720045d5a12e6c03cc7 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Tue, 27 Nov 2018 17:30:07 -0800 Subject: libix2: disambiguate ix2_search_status_t Previously one could say stop/ignore/continue. There was no way to say stop and ignore, or stop but don't ignore. Now there are basically two classes of returns, stop and continue, and each of those have ignore/don't ignore sub-statuses. The naming is changed to STOP vs. MORE and HIT vs. MISS for brevity: typedef enum ix2_search_status_t { IX2_SEARCH_STOP_MISS, IX2_SEARCH_STOP_HIT, IX2_SEARCH_MORE_MISS, IX2_SEARCH_MORE_HIT } ix2_search_status_t; --- src/ix2.c | 45 +++++++++++++++++++++++++++++++-------------- src/ix2.h | 7 ++++--- src/test.c | 2 +- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/ix2.c b/src/ix2.c index 2876d32..47bb592 100644 --- a/src/ix2.c +++ b/src/ix2.c @@ -612,17 +612,26 @@ unsigned ix2_search_by_point(ix2_t *ix2, v2f_t *point, ix2_search_cb cb, void *c continue; if (cb) { - ix2_search_status_t r; ix2_object_t *o = ref->object; + ix2_search_status_t r; r = cb(cb_context, o, &o->position, &o->aabb, o->object); - if (r == IX2_SEARCH_STOP) { + switch (r) { + case IX2_SEARCH_STOP_HIT: n_hits++; - break; - } - if (r == IX2_SEARCH_IGNORE) + case IX2_SEARCH_STOP_MISS: + return n_hits; + + case IX2_SEARCH_MORE_HIT: + n_hits++; + + case IX2_SEARCH_MORE_MISS: continue; + + default: + assert(0); + } } n_hits++; @@ -712,22 +721,30 @@ unsigned ix2_search_by_aabb(ix2_t *ix2, v2f_t *search_position, v2f_t *search_or ix2_search_status_t r; r = cb(cb_context, o, &o->position, &o->aabb, o->object); - if (r == IX2_SEARCH_STOP) { + switch (r) { + case IX2_SEARCH_STOP_HIT: + n_hits++; + + case IX2_SEARCH_STOP_MISS: + /* XXX: this is necessary, the hits nodes must be kept movable */ + list_for_each_entry_safe(o, _o, &hits, hits) + list_del_init(&o->hits); + + return n_hits; + + case IX2_SEARCH_MORE_HIT: n_hits++; - break; - } - if (r == IX2_SEARCH_IGNORE) + case IX2_SEARCH_MORE_MISS: continue; + + default: + assert(0); + } } n_hits++; } - /* just in case the search was aborted, finish deleting these nodes */ - /* FIXME: this whole hit list thing is pretty janky */ - list_for_each_entry_safe(o, _o, &hits, hits) - list_del_init(&o->hits); - return n_hits; } diff --git a/src/ix2.h b/src/ix2.h index b76e174..46f9727 100644 --- a/src/ix2.h +++ b/src/ix2.h @@ -23,9 +23,10 @@ typedef struct bb2f_t bb2f_t; typedef struct v2f_t v2f_t; typedef enum ix2_search_status_t { - IX2_SEARCH_STOP, - IX2_SEARCH_IGNORE, - IX2_SEARCH_CONTINUE + IX2_SEARCH_STOP_MISS, /* stop && current object is a miss */ + IX2_SEARCH_STOP_HIT, /* stop && current object is a hit */ + IX2_SEARCH_MORE_MISS, /* continue && current object is a miss */ + IX2_SEARCH_MORE_HIT, /* continue && current object is a miss */ } ix2_search_status_t; typedef ix2_search_status_t (*ix2_search_cb)(void *cb_context, ix2_object_t *ix2_object, v2f_t *ix2_object_position, bb2f_t *ix2_object_aabb, void *object); diff --git a/src/test.c b/src/test.c index d00f63a..1d14a98 100644 --- a/src/test.c +++ b/src/test.c @@ -34,7 +34,7 @@ ix2_search_status_t cb(void *cb_context, ix2_object_t *ix2_object, v2f_t *ix2_ob fprintf(stderr, "found %p ix2_object=%p ix2_object_aabb=%f,%f ... %f,%f\n", cb_context, ix2_object, ix2_object_aabb->min.x, ix2_object_aabb->min.y, ix2_object_aabb->max.x, ix2_object_aabb->max.y); - return IX2_SEARCH_CONTINUE; + return IX2_SEARCH_MORE_HIT; } typedef struct object_t { -- cgit v1.2.3