Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/tools/Timer.h @ 995

Last change on this file since 995 was 995, checked in by landauf, 16 years ago

added 'delay time command' console command that executes 'command' after 'time' seconds. it uses a automatically destroying timer for every execution, so you can start several delayed commands at the same time without overwriting older entries.

and this is great:

append disco.txt delay 0.0 Ambient setAmbientLightTest 1,0,0,1
append disco.txt delay 0.2 Ambient setAmbientLightTest 0,1,0,1
append disco.txt delay 0.4 Ambient setAmbientLightTest 0,0,1,1
append disco.txt delay 0.6 exec disco.txt

exec disco.txt

and you'll have disco in space… forever! :D

File size: 9.2 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28/*!
29    @file Timer.h
30    @brief Definition and Implementation of the Timer class.
31
32    The Timer is a callback-object, calling a given function after a given time-interval.
33
34    Usage:
35    header.h:
36        class ClassName
37        {
38            public:
39                ClassName();
40                void functionName();
41                Timer<ClassName> myTimer;
42        };
43
44    source.cc:
45        include "core/Executor.h"
46
47        ClassName::ClassName()
48        {
49            myTimer.setTimer(interval_in_seconds, bLoop, this, createExecutor(createFunctor(&ClassName::functionName)));
50        }
51
52        void ClassName::functionName()
53        {
54            whateveryouwant();
55            something(else);
56        }
57*/
58
59#ifndef _Timer_H__
60#define _Timer_H__
61
62#include <OgreFrameListener.h>
63#include "OrxonoxPrereqs.h"
64#include "core/CorePrereqs.h"
65
66namespace orxonox
67{
68    class StaticTimer;
69    void delay(float delay, const std::string& command);
70    void executeDelayedCommand(StaticTimer* timer, const std::string& command);
71
72    //! TimerBase is the parent of the Timer class.
73    class _OrxonoxExport TimerBase : public OrxonoxClass
74    {
75        friend class TimerFrameListener;
76
77        public:
78            ~TimerBase();
79
80            void run() const;
81
82            /** @brief Starts the Timer: Function-call after 'interval' seconds. */
83            inline void startTimer()
84                { this->bActive_ = true; this->time_ = this->interval_; }
85            /** @brief Stops the Timer. */
86            inline void stopTimer()
87                { this->bActive_ = false; this->time_ = this->interval_; }
88            /** @brief Pauses the Timer - it will continue with the actual state if you unpause it. */
89            inline void pauseTimer()
90                { this->bActive_ = false; }
91            /** @brief Unpauses the Timer - continues with the given state. */
92            inline void unpauseTimer()
93                { this->bActive_ = true; }
94            /** @brief Returns true if the Timer is active (= not stoped, not paused). @return True = Time is active */
95            inline bool isActive() const
96                { return this->bActive_; }
97            /** @brief Gives the Timer some extra time. @param time The amount of extra time in seconds */
98            inline void addTime(float time)
99                { this->time_ += time; }
100            /** @brief Decreases the remaining time of the Timer. @param time The amount of time to remove */
101            inline void removeTime(float time)
102                { this->time_ -= time; }
103            /** @brief Sets the interval of the Timer. @param interval The interval */
104            inline void setInterval(float interval)
105                { this->interval_ = interval; }
106            /** @brief Sets bLoop to a given value. @param bLoop True = loop */
107            inline void setLoop(bool bLoop)
108                { this->bLoop_ = bLoop; }
109
110        protected:
111            TimerBase();
112
113            Executor* executor_; //!< The executor of the function that should be called when the time expires
114
115            float interval_;     //!< The time-interval in seconds
116            bool bLoop_;         //!< If true, the function gets called every 'interval' seconds
117            bool bActive_;       //!< If true, the Timer ticks and calls the function if the time's up
118
119            float time_;         //!< Internal variable, counting the time till the next function-call
120    };
121
122    //! The Timer is a callback-object, calling a given function after a given time-interval.
123    template <class T = BaseObject>
124    class Timer : public TimerBase
125    {
126        public:
127            Timer() {}
128
129            /**
130                @brief Constructor: Initializes the Timer with given values.
131                @param interval The timer-interval in seconds
132                @param bLoop If true, the function gets called every 'interval' seconds
133                @param object The object owning the timer and the function
134                @param exeuctor A executor of the function to call
135            */
136            Timer(float interval, bool bLoop, T* object, ExecutorMember<T>* exeuctor)
137            {
138                this->setTimer(interval, bLoop, object, exeuctor);
139            }
140
141            /**
142                @brief Initializes the Timer with given values.
143                @param interval The timer-interval in seconds
144                @param bLoop If true, the function gets called every 'interval' seconds
145                @param object The object owning the timer and the function
146                @param exeuctor A executor of the function to call
147            */
148            void setTimer(float interval, bool bLoop, T* object, ExecutorMember<T>* executor)
149            {
150                this->interval_ = interval;
151                this->bLoop_ = bLoop;
152                executor->setObject(object);
153                this->executor_ = (Executor*)executor;
154                this->bActive_ = true;
155
156                this->time_ = interval;
157            }
158    };
159
160    //! The StaticTimer is a callback-object, calling a static function after a given time-interval.
161    class StaticTimer : public TimerBase
162    {
163        public:
164            StaticTimer() {}
165
166            /**
167                @brief Constructor: Initializes the Timer with given values.
168                @param interval The timer-interval in seconds
169                @param bLoop If true, the function gets called every 'interval' seconds
170                @param exeuctor A executor of the function to call
171            */
172            StaticTimer(float interval, bool bLoop, ExecutorStatic* executor)
173            {
174                this->setTimer(interval, bLoop, executor);
175            }
176
177            /**
178                @brief Initializes the Timer with given values.
179                @param interval The timer-interval in seconds
180                @param bLoop If true, the function gets called every 'interval' seconds
181                @param object The object owning the timer and the function
182                @param executor A executor of the function to call
183            */
184            void setTimer(float interval, bool bLoop, ExecutorStatic* executor)
185            {
186                this->interval_ = interval;
187                this->bLoop_ = bLoop;
188                this->executor_ = (Executor*)executor;
189                this->bActive_ = true;
190
191                this->time_ = interval;
192            }
193    };
194
195    //! The TimerFrameListener manages all Timers in the game.
196    class TimerFrameListener : public Ogre::FrameListener
197    {
198        private:
199            /** @brief Gets called before a frame gets rendered. */
200            bool frameStarted(const Ogre::FrameEvent &evt)
201            {
202                // Iterate through all Timers
203                for (Iterator<TimerBase> it = ObjectList<TimerBase>::start(); it; )
204                {
205                    if (it->isActive())
206                    {
207                        // If active: Decrease the timer by the duration of the last frame
208                        it->time_ -= evt.timeSinceLastFrame;
209
210                        if (it->time_ <= 0)
211                        {
212                            // It's time to call the function
213                            if (it->bLoop_)
214                            {
215                                it->time_ += it->interval_; // Q: Why '+=' and not '='? A: Think about it. It's more accurate like that. Seriously.
216                                while (it->time_ <= 0)
217                                {
218                                    // The interval was shorter than one tick, so execute the function more than once
219                                    it->run();
220                                    it->time_ += it->interval_;
221                                }
222                            }
223                            else
224                                it->stopTimer(); // Stop the timer if we don't want to loop
225
226                            (it++)->run();
227                        }
228                        else
229                            ++it;
230                    }
231                    else
232                        ++it;
233                }
234
235                return FrameListener::frameStarted(evt);
236            }
237    };
238}
239
240#endif /* _Timer_H__ */
Note: See TracBrowser for help on using the repository browser.