source: nrEngine/src/Clock.cpp @ 30

Revision 30, 11.9 KB checked in by art, 12 years ago (diff)

::std wurde durch std ueberall ersetzt!

Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13//----------------------------------------------------------------------------------
14// Includes
15//----------------------------------------------------------------------------------
16#include "Clock.h"
17#include "Log.h"
18
19//----------------------------------------------------------------------------------
20// Defines
21//----------------------------------------------------------------------------------
22#define DEFAULT_OBSERVER_NAME "__no_name__"
23
24
25namespace nrEngine{
26       
27        //----------------------------------------------------------------------------------
28        ScriptFunctionDec(scriptResetClock, Clock)
29        {
30                // check parameter count
31                if (args.size() < 1)
32                {
33                        return ScriptResult(std::string("resetClock([timeToReset = 0, [reset_all_timers = 1]]) - Not valid parameter count!"));
34                }
35
36                if (param.size() == 0)
37                {
38                        return ScriptResult(std::string("resetClock() was not properly registered before. Clock was not passed!"));
39                }
40               
41                // get clock
42                Clock* clock = nrEngine::ScriptEngine::parameter_cast<Clock* >(param[0]);
43                if (clock == NULL)
44                {
45                        return ScriptResult(std::string("resetClock() was not properly registered before. Clock was not passed!"));             
46                }
47               
48                // get parameters
49                bool shouldResetTimers = true;
50                float64 timeToReset = 0;
51                if (args.size() > 1) timeToReset = boost::lexical_cast<float64>(args[1]);
52                if (args.size() > 2) shouldResetTimers = boost::lexical_cast<bool>(args[2]);
53               
54                // reset the clock
55                clock->reset(timeToReset, shouldResetTimers);
56
57                return ScriptResult();
58        }
59
60        //------------------------------------------------------------------------
61        Clock::Clock() : ITask(){
62               
63                setTaskName("SystemClock");
64                currentTime = 0;
65                frameTime = 0;
66                frameNumber = 0;
67               
68                sourceStartValue = 0;
69                sourceLastValue = 0;
70                sourceLastRealValue = 0;
71               
72                useFixRate = false;
73                fixFrameRate = 0;
74                useMaxRate = false;
75                maxFrameRate = 0;
76                lastCurrentTime = 0;
77
78                // add default frame time       
79                setFrameWindow (7);
80                frameTime = _getFilteredFrameDuration();
81               
82                timeSource.reset();
83                realTimeSource.reset(new TimeSource());
84               
85                // setup some other values
86                nextSyncTime = 0;
87                syncInterval = 0;
88               
89        }
90               
91        //------------------------------------------------------------------------
92        Clock::~Clock(){
93                stopTask();
94        }
95       
96        //------------------------------------------------------------------------     
97        void Clock::reset(float64 resetToTime, bool resetAllObservers)
98        {
99                // check if we have to reset observers
100                if (resetAllObservers)
101                {
102                        NR_Log(Log::LOG_ENGINE, "Clock: Reset time observers");
103                        ObserverList::iterator it = observers.begin();
104                        for (; it != observers.end(); it++) (*it)->resetObserver(resetToTime);
105                }
106               
107                // reset the clock
108                lastCurrentTime = resetToTime;
109                currentTime = resetToTime;
110                frameTime = frameDefaultTime;
111                //frameNumber = 0;
112                realFrameTime = frameDefaultTime;
113                nextSyncTime = lastCurrentTime + static_cast<float64>(syncInterval) / 1000.0;
114               
115                // reset time source
116                setTimeSource(timeSource);
117                if (timeSource != NULL) timeSource->reset(resetToTime);
118               
119                // reset the frame history
120                setFrameWindow(frameFilteringWindow, frameDefaultTime);
121               
122                NR_Log(Log::LOG_ENGINE, "Clock: Reset clock to %f", resetToTime);               
123        }
124
125        //------------------------------------------------------------------------     
126        void Clock::setTimeSource(SharedPtr<TimeSource> timeSource)
127        {
128                this->timeSource = timeSource;
129       
130                if (timeSource != NULL){
131                        sourceStartValue = timeSource->getTime();
132                        sourceLastValue = sourceStartValue;
133                }
134        }
135       
136        //------------------------------------------------------------------------     
137        void Clock::setSyncInterval(uint32 milliseconds)
138        {
139                this->syncInterval = milliseconds;
140        }
141       
142        //------------------------------------------------------------------------
143        bool Clock::isAnySourceBounded(){
144                return (timeSource != NULL);
145        }
146       
147        //------------------------------------------------------------------------
148        SharedPtr<Timer> Clock::createTimer(){
149       
150                // create timer as observer
151                SharedPtr<ITimeObserver> timer(new Timer(*this));
152               
153                // add him to the list
154                int32 id = addObserver(timer);
155               
156                if (id == 0){
157                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "Clock::createTimer(): Can not add timer to the observer list");
158                }
159               
160                // set the id of the timer
161                timer->_observerID = id;
162                NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Clock::createTimer(): New timer created (id=%d)", id);
163               
164                // return created timer
165                return ::boost::dynamic_pointer_cast<Timer, ITimeObserver>(timer);
166               
167        }
168       
169        //------------------------------------------------------------------------
170        Result Clock::onStartTask()
171        {
172                // register function by the manager
173                std::vector<nrEngine::ScriptParam> param;
174                param.push_back(this);
175                Engine::sScriptEngine()->add("resetClock", scriptResetClock, param);
176               
177                return OK;
178        }
179
180        //------------------------------------------------------------------------
181        Result Clock::stopTask()
182        {
183       
184                timeSource.reset();
185               
186                for (uint32 i=0; i < observers.size(); i++){
187                        observers[i].reset();
188                }
189                observers.clear();
190               
191                Engine::sScriptEngine()->del("resetClock");
192               
193                return OK;
194        }
195       
196        //------------------------------------------------------------------------
197        Result Clock::updateTask(){
198
199                // check whenever a time source is bound
200                if (timeSource == NULL) return CLOCK_NO_TIME_SOURCE;
201
202                timeSource->notifyNextFrame();
203               
204                // calculate exact frame duration time
205                float64 exactFrameDuration = _getExactFrameDuration();
206                _addToFrameHistory(exactFrameDuration);
207               
208                // get filtered frame time
209                frameTime = _getFilteredFrameDuration();
210                frameNumber ++;
211
212                // check if we use frame bounder
213                do {
214                        currentTime = timeSource->getTime();
215
216                        // get through the list of connected observers and notify them
217                        ObserverList::iterator it;
218                        for (it = observers.begin(); it != observers.end(); ++it){
219                                (*it)->notifyTimeObserver();
220                        }
221
222                        // check if we need to sync the clock
223                        if (syncInterval > 0 && nextSyncTime < currentTime)
224                        {
225                                timeSource->sync();
226                                nextSyncTime = currentTime + static_cast<float64>(syncInterval) / 1000.0;
227                        }
228
229                } while (useMaxRate && (currentTime - lastCurrentTime) < invMaxFrameRate);
230
231                // set the last current time we used to the current time
232                lastCurrentTime = currentTime;
233               
234                // OK
235                return OK;
236        }
237
238        //------------------------------------------------------------------------
239        float64 Clock::getTime() const{
240                return currentTime;
241        }
242       
243        //------------------------------------------------------------------------
244        float32 Clock::getFrameInterval() const{
245                return (float32)frameTime;
246        }
247       
248        //------------------------------------------------------------------------
249        float32 Clock::getRealFrameInterval() const
250        {
251                return (float32)realFrameTime;
252        }
253
254        //------------------------------------------------------------------------
255        float32 Clock::getRealFrameRate() const
256        {
257                return 1.0f / getRealFrameInterval();
258        }
259
260        //------------------------------------------------------------------------
261        int32 Clock::getFrameNumber() const{
262                return frameNumber;
263        }
264       
265        //------------------------------------------------------------------------
266        float32 Clock::getFrameRate() const{
267                return 1.0f / getFrameInterval();
268        }
269               
270        //------------------------------------------------------------------------
271        int32 Clock::addObserver(SharedPtr<ITimeObserver> timeObserver){
272               
273                int32 id = 0;
274               
275                if (timeObserver != NULL){
276                        observers.push_back (timeObserver);
277                        id = observers.size();
278                        observerIDList[std::string(DEFAULT_OBSERVER_NAME) + ::boost::lexical_cast< std::string >(id)] = id;
279                        observers[observers.size()-1]->_observerID = id;
280                }
281               
282                return id;
283        }
284       
285        //------------------------------------------------------------------------
286        Result Clock::removeObserver(int32 observerID){
287               
288                int32 id = observerID - 1;
289                if (id <= 0 || id+1 >= static_cast<int32>(observers.size())
290                                || observerIDList.find(std::string(DEFAULT_OBSERVER_NAME) + 
291                                ::boost::lexical_cast< std::string >(observerID)) == observerIDList.end()){
292                        return CLOCK_OBSERVER_NOT_FOUND;
293                }
294               
295                // remove it from the list
296                observers.erase(observers.begin() + id);
297               
298                // also clean the map enty for this id
299                observerIDList.erase(observerIDList.find( std::string(DEFAULT_OBSERVER_NAME) + 
300                                ::boost::lexical_cast< std::string >(observerID) ));
301                               
302                // OK
303                return OK;
304        }
305               
306        //------------------------------------------------------------------------
307        Result Clock::addObserver(const std::string& obsName,SharedPtr<ITimeObserver> timeObserver)
308        {
309       
310                // check whenever such an observer already exists
311                if (observerIDList[obsName]){
312                        return CLOCK_OBSERVER_ALREADY_ADDED;
313                }
314               
315                // add observer
316                if (timeObserver != NULL && obsName.length() > 0){
317                        observers.push_back (timeObserver);
318                        observerIDList[obsName] = observers.size(); 
319                        observers[observers.size()-1]->_observerID = observers.size();
320                }
321               
322                return OK;
323                                       
324        }
325       
326        //------------------------------------------------------------------------
327        Result Clock::removeObserver(const std::string& obsName){
328       
329                if (observerIDList[obsName]){
330                        int32 id = observerIDList[obsName] - 1;
331                        observers.erase(observers.begin() + id);
332                }else{
333                        return CLOCK_OBSERVER_NOT_FOUND;
334                }
335               
336                return OK;
337        }
338       
339        //------------------------------------------------------------------------
340        void Clock::setFrameWindow(int32 frameCount, float32 defaultFrameTime){
341               
342                frameFilteringWindow = frameCount > 1 ? frameCount : 1;
343                frameDefaultTime = defaultFrameTime;
344                frameDurationHistory.clear ();
345                frameDurationHistory.push_back(frameDefaultTime);
346        }
347       
348        //------------------------------------------------------------------------
349        void Clock::setFixFrameRate(bool setFixRate, float32 fixFrameRate){
350                useFixRate = setFixRate;
351                this->fixFrameRate = fixFrameRate;
352        }
353               
354        //------------------------------------------------------------------------
355        void Clock::setMaxFrameRate(bool set, float32 maxFPS)
356        {
357                useMaxRate = set;
358                this->maxFrameRate = maxFPS;
359                invMaxFrameRate = 1.0 / (float64)(maxFPS);
360        }
361
362        //------------------------------------------------------------------------
363        float64 Clock::_getExactFrameDuration (){
364               
365               
366                float64 sourceTime = timeSource->getTime();
367                float64 sourceRealTime = realTimeSource->getTime();
368               
369                realFrameTime = sourceRealTime - sourceLastRealValue;
370               
371                sourceLastValue = sourceTime;
372                sourceLastRealValue = sourceRealTime;
373               
374                /*if (frameDuration > 0.200){
375                        frameDuration = frameDurationHistory.back();
376                }else if (frameDuration < 0){
377                        frameDuration = 0;
378                }*/
379
380                if (useFixRate || timeSource == NULL){
381                        return 1.0f / (fixFrameRate);
382                }
383
384                return realFrameTime;
385        }
386       
387        //------------------------------------------------------------------------
388        void Clock::_addToFrameHistory (float64 exactFrameDuration){
389                frameDurationHistory.push_back (exactFrameDuration);
390                if (frameDurationHistory.size () > (uint32) frameFilteringWindow)
391                        frameDurationHistory.pop_front ();
392        }
393       
394        //------------------------------------------------------------------------
395        float64 Clock::_getFilteredFrameDuration () const{
396               
397                if (useFixRate){
398                        return 1.0f/(fixFrameRate);
399                }
400               
401                float64 totalFrameTime = 0;
402       
403                std::deque<float64>::const_iterator it;
404                for (it=frameDurationHistory.begin();it != frameDurationHistory.end(); ++it){
405                        totalFrameTime += *it;
406                }
407               
408                return totalFrameTime/static_cast<float64>(frameDurationHistory.size());
409        }
410       
411}; // end namespace
412
413#undef DEFAULT_OBSERVER_NAME
Note: See TracBrowser for help on using the repository browser.