OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // OneShotTimer and RepeatingTimer provide a simple timer API. As the names | 5 // OneShotTimer and RepeatingTimer provide a simple timer API. As the names |
6 // suggest, OneShotTimer calls you back once after a time delay expires. | 6 // suggest, OneShotTimer calls you back once after a time delay expires. |
7 // RepeatingTimer on the other hand calls you back periodically with the | 7 // RepeatingTimer on the other hand calls you back periodically with the |
8 // prescribed time interval. | 8 // prescribed time interval. |
9 // | 9 // |
10 // OneShotTimer and RepeatingTimer both cancel the timer when they go out of | 10 // OneShotTimer and RepeatingTimer both cancel the timer when they go out of |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 TimerTask(TimeDelta delay) : delay_(delay) { | 82 TimerTask(TimeDelta delay) : delay_(delay) { |
83 // timer_ is set in InitiateDelayedTask. | 83 // timer_ is set in InitiateDelayedTask. |
84 } | 84 } |
85 virtual ~TimerTask() {} | 85 virtual ~TimerTask() {} |
86 BaseTimer_Helper* timer_; | 86 BaseTimer_Helper* timer_; |
87 TimeDelta delay_; | 87 TimeDelta delay_; |
88 }; | 88 }; |
89 | 89 |
90 // Used to orphan delayed_task_ so that when it runs it does nothing. | 90 // Used to orphan delayed_task_ so that when it runs it does nothing. |
91 void OrphanDelayedTask(); | 91 void OrphanDelayedTask(); |
92 | 92 |
93 // Used to initiated a new delayed task. This has the side-effect of | 93 // Used to initiated a new delayed task. This has the side-effect of |
94 // orphaning delayed_task_ if it is non-null. | 94 // orphaning delayed_task_ if it is non-null. |
95 void InitiateDelayedTask(TimerTask* timer_task); | 95 void InitiateDelayedTask(TimerTask* timer_task); |
96 | 96 |
97 TimerTask* delayed_task_; | 97 TimerTask* delayed_task_; |
98 | 98 |
99 DISALLOW_COPY_AND_ASSIGN(BaseTimer_Helper); | 99 DISALLOW_COPY_AND_ASSIGN(BaseTimer_Helper); |
100 }; | 100 }; |
101 | 101 |
102 //----------------------------------------------------------------------------- | 102 //----------------------------------------------------------------------------- |
(...skipping 18 matching lines...) Expand all Loading... |
121 } | 121 } |
122 | 122 |
123 // Call this method to reset the timer delay of an already running timer. | 123 // Call this method to reset the timer delay of an already running timer. |
124 void Reset() { | 124 void Reset() { |
125 DCHECK(IsRunning()); | 125 DCHECK(IsRunning()); |
126 InitiateDelayedTask(static_cast<TimerTask*>(delayed_task_)->Clone()); | 126 InitiateDelayedTask(static_cast<TimerTask*>(delayed_task_)->Clone()); |
127 } | 127 } |
128 | 128 |
129 private: | 129 private: |
130 typedef BaseTimer<Receiver, kIsRepeating> SelfType; | 130 typedef BaseTimer<Receiver, kIsRepeating> SelfType; |
131 | 131 |
132 class TimerTask : public BaseTimer_Helper::TimerTask { | 132 class TimerTask : public BaseTimer_Helper::TimerTask { |
133 public: | 133 public: |
134 TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method) | 134 TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method) |
135 : BaseTimer_Helper::TimerTask(delay), | 135 : BaseTimer_Helper::TimerTask(delay), |
136 receiver_(receiver), | 136 receiver_(receiver), |
137 method_(method) { | 137 method_(method) { |
138 } | 138 } |
139 | 139 |
140 virtual ~TimerTask() { | 140 virtual ~TimerTask() { |
141 // This task may be getting cleared because the MessageLoop has been | 141 // This task may be getting cleared because the MessageLoop has been |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 //----------------------------------------------------------------------------- | 191 //----------------------------------------------------------------------------- |
192 // A simple, one-shot timer. See usage notes at the top of the file. | 192 // A simple, one-shot timer. See usage notes at the top of the file. |
193 template <class Receiver> | 193 template <class Receiver> |
194 class OneShotTimer : public BaseTimer<Receiver, false> {}; | 194 class OneShotTimer : public BaseTimer<Receiver, false> {}; |
195 | 195 |
196 //----------------------------------------------------------------------------- | 196 //----------------------------------------------------------------------------- |
197 // A simple, repeating timer. See usage notes at the top of the file. | 197 // A simple, repeating timer. See usage notes at the top of the file. |
198 template <class Receiver> | 198 template <class Receiver> |
199 class RepeatingTimer : public BaseTimer<Receiver, true> {}; | 199 class RepeatingTimer : public BaseTimer<Receiver, true> {}; |
200 | 200 |
| 201 //----------------------------------------------------------------------------- |
| 202 // A Delay timer is like The Button from Lost. Once started, you have to keep |
| 203 // calling Reset otherwise it will call the given method in the MessageLoop |
| 204 // thread. |
| 205 // |
| 206 // Once created, it is inactive until Reset is called. Once |delay| seconds have |
| 207 // passed since the last call to Reset, the callback is made. Once the callback |
| 208 // has been made, it's inactive until Reset is called again. |
| 209 template <class Receiver> |
| 210 class DelayTimer { |
| 211 public: |
| 212 typedef void (Receiver::*ReceiverMethod)(); |
| 213 |
| 214 DelayTimer(TimeDelta delay, Receiver* receiver, ReceiverMethod method) |
| 215 : receiver_(receiver), |
| 216 method_(method), |
| 217 delay_(delay) { |
| 218 } |
| 219 |
| 220 void Reset() { |
| 221 DelayFor(delay_); |
| 222 } |
| 223 |
| 224 private: |
| 225 void DelayFor(TimeDelta delay) { |
| 226 trigger_time_ = Time::Now() + delay; |
| 227 |
| 228 // If we already have a timer that will expire at or before the given delay, |
| 229 // then we have nothing more to do now. |
| 230 if (timer_.IsRunning() && timer_.GetCurrentDelay() <= delay) |
| 231 return; |
| 232 |
| 233 // The timer isn't running, or will expire too late, so restart it. |
| 234 timer_.Stop(); |
| 235 timer_.Start(delay, this, &DelayTimer<Receiver>::Check); |
| 236 } |
| 237 |
| 238 void Check() { |
| 239 if (trigger_time_.is_null()) |
| 240 return; |
| 241 |
| 242 // If we have not waited long enough, then wait some more. |
| 243 const Time now = Time::Now(); |
| 244 if (now < trigger_time_) { |
| 245 DelayFor(trigger_time_ - now); |
| 246 return; |
| 247 } |
| 248 |
| 249 (receiver_->*method_)(); |
| 250 } |
| 251 |
| 252 Receiver *const receiver_; |
| 253 const ReceiverMethod method_; |
| 254 const TimeDelta delay_; |
| 255 |
| 256 OneShotTimer<DelayTimer<Receiver> > timer_; |
| 257 Time trigger_time_; |
| 258 }; |
| 259 |
201 } // namespace base | 260 } // namespace base |
202 | 261 |
203 #endif // BASE_TIMER_H_ | 262 #endif // BASE_TIMER_H_ |
OLD | NEW |