| Index: base/timer.h
|
| diff --git a/base/timer.h b/base/timer.h
|
| index 698d59ddcfbcd85297357a11da462134763d8e4b..eb004861335c8b3cac140ba70377ba625366409a 100644
|
| --- a/base/timer.h
|
| +++ b/base/timer.h
|
| @@ -89,7 +89,7 @@ class BaseTimer_Helper {
|
|
|
| // Used to orphan delayed_task_ so that when it runs it does nothing.
|
| void OrphanDelayedTask();
|
| -
|
| +
|
| // Used to initiated a new delayed task. This has the side-effect of
|
| // orphaning delayed_task_ if it is non-null.
|
| void InitiateDelayedTask(TimerTask* timer_task);
|
| @@ -128,7 +128,7 @@ class BaseTimer : public BaseTimer_Helper {
|
|
|
| private:
|
| typedef BaseTimer<Receiver, kIsRepeating> SelfType;
|
| -
|
| +
|
| class TimerTask : public BaseTimer_Helper::TimerTask {
|
| public:
|
| TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method)
|
| @@ -198,6 +198,65 @@ class OneShotTimer : public BaseTimer<Receiver, false> {};
|
| template <class Receiver>
|
| class RepeatingTimer : public BaseTimer<Receiver, true> {};
|
|
|
| +//-----------------------------------------------------------------------------
|
| +// A Delay timer is like The Button from Lost. Once started, you have to keep
|
| +// calling Reset otherwise it will call the given method in the MessageLoop
|
| +// thread.
|
| +//
|
| +// Once created, it is inactive until Reset is called. Once |delay| seconds have
|
| +// passed since the last call to Reset, the callback is made. Once the callback
|
| +// has been made, it's inactive until Reset is called again.
|
| +template <class Receiver>
|
| +class DelayTimer {
|
| + public:
|
| + typedef void (Receiver::*ReceiverMethod)();
|
| +
|
| + DelayTimer(TimeDelta delay, Receiver* receiver, ReceiverMethod method)
|
| + : receiver_(receiver),
|
| + method_(method),
|
| + delay_(delay) {
|
| + }
|
| +
|
| + void Reset() {
|
| + DelayFor(delay_);
|
| + }
|
| +
|
| + private:
|
| + void DelayFor(TimeDelta delay) {
|
| + trigger_time_ = Time::Now() + delay;
|
| +
|
| + // If we already have a timer that will expire at or before the given delay,
|
| + // then we have nothing more to do now.
|
| + if (timer_.IsRunning() && timer_.GetCurrentDelay() <= delay)
|
| + return;
|
| +
|
| + // The timer isn't running, or will expire too late, so restart it.
|
| + timer_.Stop();
|
| + timer_.Start(delay, this, &DelayTimer<Receiver>::Check);
|
| + }
|
| +
|
| + void Check() {
|
| + if (trigger_time_.is_null())
|
| + return;
|
| +
|
| + // If we have not waited long enough, then wait some more.
|
| + const Time now = Time::Now();
|
| + if (now < trigger_time_) {
|
| + DelayFor(trigger_time_ - now);
|
| + return;
|
| + }
|
| +
|
| + (receiver_->*method_)();
|
| + }
|
| +
|
| + Receiver *const receiver_;
|
| + const ReceiverMethod method_;
|
| + const TimeDelta delay_;
|
| +
|
| + OneShotTimer<DelayTimer<Receiver> > timer_;
|
| + Time trigger_time_;
|
| +};
|
| +
|
| } // namespace base
|
|
|
| #endif // BASE_TIMER_H_
|
|
|