296 |
{ |
{ |
297 |
class Alarm { |
class Alarm { |
298 |
TimeHandler * handler; |
TimeHandler * handler; |
299 |
double interval; |
double interval; |
300 |
double timeleft; |
double timeleft; |
301 |
bool repeatp; |
bool repeatp; |
302 |
|
bool removed; |
303 |
public: |
public: |
304 |
Alarm(TimeHandler* h, double interval, bool repeatp); |
Alarm(TimeHandler* h, double interval, bool repeatp); |
305 |
void tick(double dtime); |
void tick(double dtime); |
306 |
bool expired() const { return timeleft <= 0; } |
bool expired() const { return removed || timeleft <= 0; } |
307 |
|
void remove() { removed = true; } |
308 |
|
|
309 |
bool operator==(const Alarm &a) const { |
bool operator==(const Alarm &a) const { |
310 |
return a.handler == handler; |
return a.handler == handler; |
319 |
} |
} |
320 |
|
|
321 |
Alarm::Alarm(TimeHandler* h, double i, bool r) |
Alarm::Alarm(TimeHandler* h, double i, bool r) |
322 |
: handler(h), interval(i), timeleft(i), repeatp(r) |
: handler(h), interval(i), timeleft(i), repeatp(r), removed(false) |
323 |
{} |
{} |
324 |
|
|
325 |
void |
void |
326 |
Alarm::tick(double dtime) |
Alarm::tick(double dtime) |
327 |
{ |
{ |
328 |
timeleft -= dtime; |
if (!removed) { |
329 |
if (repeatp) { |
timeleft -= dtime; |
330 |
while (timeleft <= 0) { |
if (repeatp) { |
331 |
|
while (timeleft <= 0) { |
332 |
|
handler->alarm(); |
333 |
|
timeleft += interval; |
334 |
|
} |
335 |
|
} else if (timeleft <= 0) { |
336 |
handler->alarm(); |
handler->alarm(); |
|
timeleft += interval; |
|
337 |
} |
} |
|
} else if (timeleft <= 0) { |
|
|
handler->alarm(); |
|
338 |
} |
} |
339 |
} |
} |
340 |
|
|
348 |
void |
void |
349 |
Timer::deactivate(TimeHandler* th) |
Timer::deactivate(TimeHandler* th) |
350 |
{ |
{ |
351 |
// This doesn't work: Some objects deactivate themselves from their |
// This doesn't work: Some objects deactivate themselves from their |
352 |
// `tick' method! |
// `tick' method! |
353 |
// rep.handlers.remove(th); |
// rep.handlers.remove(th); |
354 |
|
|
355 |
std::list<TimeHandler*>::iterator i; |
std::list<TimeHandler*>::iterator i; |
356 |
|
|
377 |
void |
void |
378 |
Timer::remove_alarm(TimeHandler *th) |
Timer::remove_alarm(TimeHandler *th) |
379 |
{ |
{ |
380 |
// only the ``handler'' entries are compared |
// does not work (crashes if alarm_n removed alarm_n+1) |
381 |
rep.alarms.remove(Alarm(th,0,0)); |
// rep.alarms.remove(Alarm(th,0,0)); |
382 |
|
|
383 |
|
list<Alarm>::iterator e = rep.alarms.end(); |
384 |
|
// only the ``handler'' entries are compared: |
385 |
|
list<Alarm>::iterator a = find(rep.alarms.begin(), e, Alarm(th, 0, 0)); |
386 |
|
if (a != e) |
387 |
|
a->remove(); // only mark for removal! |
388 |
} |
} |
389 |
|
|
390 |
|
|
395 |
for_each(rep.handlers.begin(), rep.handlers.end(), |
for_each(rep.handlers.begin(), rep.handlers.end(), |
396 |
bind2nd(mem_fun(&TimeHandler::tick), dtime)); |
bind2nd(mem_fun(&TimeHandler::tick), dtime)); |
397 |
|
|
398 |
// Explicit loop since `mem_fun_ref' requires a constant member function |
// explicit loop to allow remove_alarm() to be called from inside alarm() |
|
|
|
399 |
for (list<Alarm>::iterator i=rep.alarms.begin(); i != rep.alarms.end(); ) { |
for (list<Alarm>::iterator i=rep.alarms.begin(); i != rep.alarms.end(); ) { |
|
// allow remove_alarm() to be called from inside alarm() |
|
400 |
list<Alarm>::iterator n = next(i); |
list<Alarm>::iterator n = next(i); |
401 |
|
|
402 |
i->tick(dtime); |
i->tick(dtime); |