// // Deus Hax (working title) // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> // #if defined HAVE_CONFIG_H # include "config.h" #endif #include <cstdlib> #include <cstdio> #include <stdint.h> #include "ticker.h" #include "asset.h" /* * Ticker implementation class */ static class TickerData { friend class Ticker; public: TickerData() : todo(0), nassets(0) { for (int i = 0; i < Asset::GROUP_COUNT; i++) list[i] = NULL; } ~TickerData() { #if !FINAL_RELEASE if (nassets) fprintf(stderr, "ERROR: still %i assets in ticker\n", nassets); #endif } private: Asset *todo; Asset *list[Asset::GROUP_COUNT]; int nassets; } tickerdata; static TickerData * const data = &tickerdata; /* * Ticker public class */ void Ticker::Register(Asset *asset) { /* If we are called from its constructor, the object's vtable is not * ready yet, so we do not know which group this asset belongs to. Wait * until the first tick. */ asset->next = data->todo; data->todo = asset; } void Ticker::TickGame(float delta_time) { /* Insert waiting objects in the appropriate lists */ while (data->todo) { Asset *a = data->todo; data->todo = a->next; int i = a->GetGroup(); a->next = data->list[i]; data->list[i] = a; data->nassets++; } /* Garbage collect objects that can be destroyed */ for (int i = 0; i < Asset::GROUP_COUNT; i++) for (Asset *a = data->list[i], *prev = NULL; a; prev = a, a = a->next) if (a->destroy) { if (prev) prev->next = a->next; else data->list[i] = a->next; data->nassets--; delete a; } /* Tick objects for the game loop */ for (int i = 0; i < Asset::GROUP_COUNT; i++) for (Asset *a = data->list[i]; a; a = a->next) if (!a->destroy) a->TickGame(delta_time); } void Ticker::TickRender(float delta_time) { /* Tick objects for the render loop */ for (int i = 0; i < Asset::GROUP_COUNT; i++) for (Asset *a = data->list[i]; a; a = a->next) if (!a->destroy) a->TickRender(delta_time); }