1 #include <msp/core/algorithm.h>
2 #include <msp/core/raii.h>
15 Timer::Slot &Timer::add(const TimeDelta &td)
17 unique_ptr<Slot> s = make_unique<Slot>(td);
20 slots.push_back({ move(s) });
21 push_heap(slots.begin(), slots.end());
27 Timer::Slot &Timer::add(const TimeStamp &ts)
29 unique_ptr<Slot> s = make_unique<Slot>(ts);
32 slots.push_back({ move(s) });
33 push_heap(slots.begin(), slots.end());
39 void Timer::cancel(Slot &slot)
42 auto i = find_if(slots, [&slot](const SlotProxy &p){ return p.slot.get()==&slot; });
46 make_heap(slots.begin(), slots.end());
55 void Timer::tick(const TimeDelta &timeout)
58 throw invalid_argument("Timer::tick");
63 void Timer::do_tick(const TimeDelta &timeout)
67 deadline = now()+timeout;
69 unique_ptr<Slot> next;
78 stamp = slots.front().slot->get_timeout();
83 if(timeout && (!deadline || t<deadline))
85 SetFlag setf(blocking);
87 if(stamp && (!deadline || stamp<deadline))
94 // The slots may have changed while waiting so check again
101 next = move(slots.front().slot);
102 pop_heap(slots.begin(), slots.end());
106 if(next->signal_timeout.emit() && next->increment())
109 slots.push_back({ move(next) });
110 push_heap(slots.begin(), slots.end());
114 TimeStamp Timer::get_next_timeout() const
118 return slots.begin()->slot->get_timeout();
122 Timer::Slot::Slot(const TimeDelta &td):
124 timeout(now()+interval)
127 Timer::Slot::Slot(const TimeStamp &ts):
131 bool Timer::Slot::increment()
140 bool Timer::SlotProxy::operator<(const SlotProxy &sp) const
142 return slot->get_timeout()>sp.slot->get_timeout();