diff --git a/doomsday/client/include/world/thinkers.h b/doomsday/client/include/world/thinkers.h index fe413f1688..fb79beae21 100644 --- a/doomsday/client/include/world/thinkers.h +++ b/doomsday/client/include/world/thinkers.h @@ -95,6 +95,15 @@ class Thinkers */ void setMobjId(thid_t id, bool inUse = true); + /** + * Returns the total number of thinkers (of any type) in the collection. + * + * @param numInStasis If not @c NULL, the number of thinkers in stasis will + * be added to the current value (caller must ensure to + * initialize this). + */ + int count(int *numInStasis = 0) const; + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/client/src/world/thinkers.cpp b/doomsday/client/src/world/thinkers.cpp index b1abd9882c..17a409cf40 100644 --- a/doomsday/client/src/world/thinkers.cpp +++ b/doomsday/client/src/world/thinkers.cpp @@ -86,6 +86,26 @@ struct ThinkerList sentinel.prev = &th; } + int count(int *numInStasis) const + { + int num = 0; + thinker_t *th = sentinel.next; + while(th != &sentinel && th) + { +#ifdef LIBDENG_FAKE_MEMORY_ZONE + DENG_ASSERT(th->next != 0); + DENG_ASSERT(th->prev != 0); +#endif + num += 1; + if(numInStasis && th->inStasis) + { + (*numInStasis) += 1; + } + th = th->next; + } + return num; + } + int iterate(int (*callback) (thinker_t *, void *), void *parameters = 0) { int result = false; @@ -337,6 +357,20 @@ int Thinkers::iterate(thinkfunc_t func, byte flags, return result; } +int Thinkers::count(int *numInStasis) const +{ + int total = 0; + if(isInited()) + { + for(int i = 0; i < d->lists.count(); ++i) + { + ThinkerList *list = d->lists[i]; + total += list->count(numInStasis); + } + } + return total; +} + void unlinkThinkerFromList(thinker_t *th) { th->next->prev = th->prev;