Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/src/libraries/tools/Timer.cc @ 10422

Last change on this file since 10422 was 8022, checked in by landauf, 14 years ago

added RealTimer, a subclass of Timer which is not affected by the game's time factor
added "delayreal" command which works like "delay" but uses RealTimer instead of Timer

in the graphics menu, the resolution confirmation popup now also closes itself after 10 seconds if it is used ingame while the game is paused

  • Property svn:eol-style set to native
File size: 7.6 KB
RevLine 
[1505]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
[7401]29/**
30    @file
31    @brief Implementation of the Timer class.
32*/
33
[3196]34#include "Timer.h"
35
[1505]36#include <set>
37
[8020]38#include <boost/bimap.hpp>
39
[5929]40#include "util/Clock.h"
[1505]41#include "core/CoreIncludes.h"
[7284]42#include "core/command/ConsoleCommand.h"
43#include "core/command/CommandExecutor.h"
44#include "core/command/Functor.h"
[8022]45#include "tools/interfaces/TimeFactorListener.h"
[1505]46
47namespace orxonox
48{
[7284]49    SetConsoleCommand("delay", &delay).argumentCompleter(1, autocompletion::command());
[8022]50    SetConsoleCommand("delayreal", &delayreal).argumentCompleter(1, autocompletion::command());
[8020]51    SetConsoleCommand("killdelay", &killdelay);
[7284]52    SetConsoleCommand("killdelays", &killdelays);
[1505]53
[8020]54    static boost::bimap<unsigned int, Timer*> delaytimers;
55    static unsigned int delayHandleCounter = 0;
[1505]56
57    /**
[8022]58        @brief Console-command: Calls another console command after @a delay seconds (game time).
[1505]59        @param delay The delay in seconds
60        @param command The console command
[8020]61        @return The handle of the delayed command, can be used as argument for killdelay()
[1505]62    */
[8020]63    unsigned int delay(float delay, const std::string& command)
[1505]64    {
[8022]65        return addDelayedCommand(new Timer(), delay, command);
66    }
[1505]67
[8022]68    /**
69        @brief Console-command: Calls another console command after @a delay seconds (real time)
70        @param delay The delay in seconds
71        @param command The console command
72        @return The handle of the delayed command, can be used as argument for killdelay()
73    */
74    unsigned int delayreal(float delay, const std::string& command)
75    {
76        return addDelayedCommand(new RealTimer(), delay, command);
77    }
78
79    /**
80        @brief Helper function, used by delay() and delayreal() to add a delayed command.
81        @param timer The timer which will execute the command
82        @param delay The delay in seconds
83        @param command The console command
84        @return The handle of the delayed command, can be used as argument for killdelay()
85    */
86    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command)
87    {
88        delaytimers.insert(boost::bimap<unsigned int, Timer*>::value_type(++delayHandleCounter, timer));
89
[7284]90        const ExecutorStaticPtr& delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
[8022]91        delayexecutor->setDefaultValues(timer, command);
92        timer->setTimer(delay, false, delayexecutor);
[8020]93
94        return delayHandleCounter;
[1505]95    }
96
97    /**
[7401]98        @brief Helper function for delay(), executes the command and destroys the timer.
99        @param timer The timer which called this function.
[1505]100        @param command The command to execute
101    */
[5929]102    void executeDelayedCommand(Timer* timer, const std::string& command)
[1505]103    {
104        CommandExecutor::execute(command);
[5929]105        timer->destroy();
[8020]106        delaytimers.right.erase(timer);
[1505]107    }
108
109    /**
[7401]110        @brief Console-command: Kills all scheduled commands that were delayed using delay().
[1505]111    */
112    void killdelays()
113    {
[8020]114        for (boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.begin(); it != delaytimers.left.end(); ++it)
115            it->second->destroy();
[1505]116
[8020]117        delaytimers.clear();
[1505]118    }
119
120    /**
[8020]121        @brief Console-command: Kills a delayed command with given handle.
122    */
123    void killdelay(unsigned int handle)
124    {
125        boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.find(handle);
126        if (it != delaytimers.left.end())
127        {
128            it->second->destroy();
129            delaytimers.left.erase(it);
130        }
131    }
132
133    /**
[1505]134        @brief Constructor: Sets the default-values.
135    */
[5929]136    Timer::Timer()
[1505]137    {
[5929]138        this->init();
[8022]139        RegisterRootObject(Timer);
[5929]140    }
[1505]141
[5929]142    /**
[7401]143        @brief Constructor: Initializes and starts the timer, which will call an executor after some time.
144        @param interval         The timer-interval in seconds
145        @param bLoop            If true, the executor gets called every @a interval seconds
146        @param executor         The executor that will be called
147        @param bKillAfterCall   If true, the timer will be deleted after the executor was called
[5929]148    */
[7284]149    Timer::Timer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall)
[5929]150    {
151        this->init();
[8022]152        RegisterRootObject(Timer);
[1505]153
[5929]154        this->setTimer(interval, bLoop, executor, bKillAfterCall);
[1505]155    }
156
157    /**
[5929]158        @brief Initializes the Timer
159    */
160    void Timer::init()
161    {
162        this->executor_ = 0;
163        this->interval_ = 0;
164        this->bLoop_ = false;
165        this->bActive_ = false;
166        this->bKillAfterCall_ = false;
[1505]167
[5929]168        this->time_ = 0;
169    }
170
[1505]171    /**
[8022]172        @brief Returns the current time factor of the game.
173    */
174    float Timer::getTimeFactor()
175    {
176        return TimeFactorListener::getTimeFactor();
177    }
178
179    /**
[7401]180        @brief Calls the executor and destroys the timer if requested.
[1505]181    */
[5929]182    void Timer::run()
[1505]183    {
[2087]184        bool temp = this->bKillAfterCall_; // to avoid errors with bKillAfterCall_=false and an exutors which destroy the timer
185
[1505]186        (*this->executor_)();
[2087]187
188        if (temp)
[5929]189            this->destroy();
[1505]190    }
191
192    /**
193        @brief Updates the timer before the frames are rendered.
194    */
[5929]195    void Timer::tick(const Clock& time)
[1505]196    {
197        if (this->bActive_)
198        {
199            // If active: Decrease the timer by the duration of the last frame
[3301]200            this->time_ -= static_cast<long long>(time.getDeltaTimeMicroseconds() * this->getTimeFactor());
[1505]201
202            if (this->time_ <= 0)
203            {
204                // It's time to call the function
[2087]205                if (this->bLoop_ && !this->bKillAfterCall_)
[1505]206                {
207                    this->time_ += this->interval_; // Q: Why '+=' and not '='? A: Think about it. It's more accurate like that. Seriously.
208                    while (this->time_ <= 0)
209                    {
210                        // The interval was shorter than one tick, so execute the function more than once
211                        this->run();
212                        this->time_ += this->interval_;
213                    }
214                }
215                else
216                    this->stopTimer(); // Stop the timer if we don't want to loop
217
218                this->run();
219            }
220        }
221    }
[8022]222
223    ///////////////
224    // RealTimer //
225    ///////////////
226    /// @copydoc Timer::Timer
227    RealTimer::RealTimer()
228    {
229        RegisterObject(RealTimer);
230    }
231
232    /// @copydoc Timer::Timer(float, bool, const ExecutorPtr&, bool)
233    RealTimer::RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall) : Timer(interval, bLoop, executor, bKillAfterCall)
234    {
235        RegisterObject(RealTimer);
236    }
237
238    /// Returns always 1 because RealTimer doesn't depend on the game time.
239    float RealTimer::getTimeFactor()
240    {
241        return 1;
242    }
[1505]243}
Note: See TracBrowser for help on using the repository browser.