25 #ifndef EXE4CPP_MOCKEXECUTOR_H 26 #define EXE4CPP_MOCKEXECUTOR_H 28 #include "exe4cpp/IExecutor.h" 45 class MockTimer final :
public ITimer 50 MockTimer(
MockExecutor* source,
const steady_time_t& time,
const action_t& action) :
57 void cancel()
override 62 steady_time_t expires_at()
override 78 virtual Timer start(
const duration_t& delay,
const action_t& action)
override 80 return start(current_time + delay, action);
83 virtual Timer start(
const steady_time_t& time,
const action_t& action)
override 85 const auto timer = std::make_shared<MockTimer>(
this, time, action);
86 this->timers.push_back(timer);
90 virtual void post(
const action_t& action)
override 92 this->post_queue.push_back(action);
103 this->check_for_expired_timers();
105 if (this->post_queue.size() > 0)
107 auto runnable = post_queue.front();
108 this->post_queue.pop_front();
123 size_t run_many(
size_t maximum = std::numeric_limits<size_t>::max())
126 while (num < maximum && this->
run_one()) ++num;
133 return this->post_queue.size();
136 size_t num_pending_timers()
const 138 return this->timers.size();
141 steady_time_t next_timer_expiration_abs()
const 143 auto lt = [](
const std::shared_ptr<MockTimer>& lhs,
const std::shared_ptr<MockTimer>& rhs)
145 return lhs->expires_at() < rhs->expires_at();
147 auto min = std::min_element(this->timers.begin(), this->timers.end(), lt);
148 if (min == this->timers.end())
150 return steady_time_t();
154 return (*min)->expires_at();
158 duration_t next_timer_expiration_rel()
const 160 auto lt = [](
const std::shared_ptr<MockTimer>& lhs,
const std::shared_ptr<MockTimer>& rhs)
162 return lhs->expires_at() < rhs->expires_at();
164 auto min = std::min_element(this->timers.begin(), this->timers.end(), lt);
165 if (min == this->timers.end())
167 return duration_t::max();
171 return (*min)->expires_at() - this->current_time;
175 size_t advance_time(duration_t duration)
177 this->add_time(duration);
178 return this->check_for_expired_timers();
182 void add_time(duration_t duration)
184 this->current_time += duration;
187 bool advance_to_next_timer()
189 if (this->timers.empty())
195 const auto timestamp = next_timer_expiration_abs();
197 if (timestamp > this->current_time)
199 this->current_time = timestamp;
209 size_t num_timer_cancel()
const 211 return this->num_timer_cancel_;
215 size_t check_for_expired_timers()
218 while (find_expired_timer())
225 bool find_expired_timer()
227 auto expired = [
this](
const std::shared_ptr<MockTimer>& timer)
229 return timer->expires_at() <= this->current_time;
232 auto iter = std::find_if(this->timers.begin(), this->timers.end(), expired);
234 if (iter == this->timers.end())
241 auto action = [timer = (*iter), action = (*iter)->action]() ->
void { action(); };
242 this->post_queue.push_back(action);
243 this->timers.erase(iter);
248 void cancel(ITimer* timer)
250 const auto result = std::find_if(this->timers.begin(), this->timers.end(), [timer](
const std::shared_ptr<MockTimer>& item)
252 return item.get() == timer;
255 if (result != this->timers.end())
258 this->timers.erase(result);
262 typedef std::deque<action_t> post_queue_t;
263 typedef std::vector<std::shared_ptr<MockTimer>> timer_vector_t;
265 steady_time_t current_time;
266 size_t num_timer_cancel_ = 0;
268 post_queue_t post_queue;
269 timer_vector_t timers;
exe4cpp header-only library namespace
virtual Timer start(const duration_t &delay, const action_t &action) override
virtual Timer start(const steady_time_t &time, const action_t &action) override
size_t num_active() const
virtual void post(const action_t &action) override
size_t run_many(size_t maximum=std::numeric_limits< size_t >::max())
virtual steady_time_t get_time() override