source: trunk/src/ticker.cpp @ 129

Last change on this file since 129 was 129, checked in by sam, 12 years ago

Minor optimisation in the garbage collection order.

  • Property svn:keywords set to Id
File size: 3.3 KB
RevLine 
[100]1//
2// Deus Hax (working title)
3// Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
4//
[94]5
[100]6#if defined HAVE_CONFIG_H
7#   include "config.h"
8#endif
[94]9
[98]10#include <cstdlib>
11#include <cstdio>
[94]12#include <stdint.h>
13
[122]14#include "profiler.h"
[94]15#include "ticker.h"
16#include "asset.h"
[116]17#include "timer.h"
[94]18
19/*
20 * Ticker implementation class
21 */
22
23static class TickerData
24{
25    friend class Ticker;
26
27public:
28    TickerData() :
[111]29        todo(0),
[94]30        nassets(0)
31    {
[101]32        for (int i = 0; i < Asset::GROUP_COUNT; i++)
33            list[i] = NULL;
[116]34        bias = 0.0f;
[94]35    }
36
37    ~TickerData()
38    {
[111]39#if !FINAL_RELEASE
[98]40        if (nassets)
41            fprintf(stderr, "ERROR: still %i assets in ticker\n", nassets);
[111]42#endif
[94]43    }
44
45private:
[116]46    /* Asset management */
[111]47    Asset *todo;
[101]48    Asset *list[Asset::GROUP_COUNT];
[94]49    int nassets;
[116]50
[122]51    /* Fixed framerate management */
52    Timer timer;
53    float delta_time, bias;
[94]54}
55tickerdata;
56
57static TickerData * const data = &tickerdata;
58
59/*
60 * Ticker public class
61 */
62
63void Ticker::Register(Asset *asset)
64{
[111]65    /* If we are called from its constructor, the object's vtable is not
66     * ready yet, so we do not know which group this asset belongs to. Wait
67     * until the first tick. */
68    asset->next = data->todo;
69    data->todo = asset;
[94]70}
71
[116]72void Ticker::TickGame()
[94]73{
[122]74    Profiler::Stop(Profiler::STAT_TICK_FRAME);
75    Profiler::Start(Profiler::STAT_TICK_FRAME);
[124]76
[122]77    Profiler::Start(Profiler::STAT_TICK_GAME);
78
79    data->delta_time = data->timer.GetSeconds();
[116]80    data->bias += data->delta_time;
81
[129]82    /* Garbage collect objects that can be destroyed. We can do this
83     * before inserting awaiting objects, because there is no way these
84     * are already marked for destruction. */
[101]85    for (int i = 0; i < Asset::GROUP_COUNT; i++)
86        for (Asset *a = data->list[i], *prev = NULL; a; prev = a, a = a->next)
87            if (a->destroy)
88            {
89                if (prev)
90                    prev->next = a->next;
91                else
92                    data->list[i] = a->next;
[98]93
[101]94                data->nassets--;
95                delete a;
96            }
[98]97
[129]98    /* Insert waiting objects into the appropriate lists */
99    while (data->todo)
100    {
101        Asset *a = data->todo;
102        data->todo = a->next;
103
104        int i = a->GetGroup();
105        a->next = data->list[i];
106        data->list[i] = a;
107        data->nassets++;
108    }
109
[98]110    /* Tick objects for the game loop */
[101]111    for (int i = 0; i < Asset::GROUP_COUNT; i++)
112        for (Asset *a = data->list[i]; a; a = a->next)
[104]113            if (!a->destroy)
[116]114                a->TickGame(data->delta_time);
[122]115
116    Profiler::Stop(Profiler::STAT_TICK_GAME);
[94]117}
118
[116]119void Ticker::TickRender()
[94]120{
[122]121    Profiler::Start(Profiler::STAT_TICK_RENDER);
122
[98]123    /* Tick objects for the render loop */
[101]124    for (int i = 0; i < Asset::GROUP_COUNT; i++)
125        for (Asset *a = data->list[i]; a; a = a->next)
[104]126            if (!a->destroy)
[116]127                a->TickRender(data->delta_time);
[122]128
129    Profiler::Stop(Profiler::STAT_TICK_RENDER);
130    Profiler::Start(Profiler::STAT_TICK_BLIT);
[94]131}
132
[126]133void Ticker::ClampFps(float delta_time)
[116]134{
[122]135    Profiler::Stop(Profiler::STAT_TICK_BLIT);
136
[126]137    if (delta_time > data->bias + 0.2f)
138        delta_time = data->bias + 0.2f; // Don't go below 5 fps
139    if (delta_time > data->bias)
140        data->timer.WaitSeconds(delta_time - data->bias);
141    data->bias -= delta_time;
[116]142}
143
Note: See TracBrowser for help on using the repository browser.