source: trunk/src/ticker.cpp @ 122

Last change on this file since 122 was 122, checked in by sam, 11 years ago

Implement the profiling system.

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