timer_event.h
#pragma once
#include <atomic>
#include <functional>
#include <memory>
#include "array_list.h"
#include "asio/steady_timer.hpp"
#include "asio/dispatch.hpp"
namespace flower {
constexpr uint16_t timer_max_count = std::numeric_limits<uint16_t>::max();
class timer_event final : public std::enable_shared_from_this<timer_event> {
public:
using ptr = std::shared_ptr<timer_event>;
using call_back = std::function<void(timer_event::ptr)>;
using event_list = array_list<ptr>;
timer_event() = delete;
timer_event(asio::io_context& io, timer_event::event_list& event, uint32_t expires, uint32_t interval,
int32_t count, call_back&& cb);
~timer_event() = default;
void start_timer();
void cancel();
int32_t get_sn() {
return sn_;
}
void set_sn(int32_t sn) {
sn_ = sn;
}
private:
void execute();
void recovery() {
event_.remove(sn_);
}
private:
uint64_t interval_;
int32_t count_;
std::atomic_int32_t sn_;
call_back call_back_;
asio::steady_timer timer_;
event_list& event_;
bool is_forever_;
};
} // namespace flower
timer_event.cpp
#include "timer_event.h"
#include "logger.h"
namespace flower {
timer_event::timer_event(asio::io_context& io, timer_event::event_list& event, uint32_t expires, uint32_t interval,
int32_t count, call_back&& cb)
: interval_(interval)
, count_(count)
, call_back_(std::move(cb))
, sn_(-1)
, timer_(io, std::chrono::milliseconds(expires))
, event_(event)
, is_forever_(false) {
if (count_ == 0) {
is_forever_ = true;
}
}
void timer_event::start_timer() {
timer_.async_wait([this, self = shared_from_this()](asio::error_code ec) {
if (ec) {
return;
}
if (!call_back_) {
recovery();
return;
}
call_back_(shared_from_this());
if (!is_forever_ && --count_ <= 0) {
recovery();
return;
}
timer_.expires_at(timer_.expiry() + std::chrono::milliseconds(interval_), ec);
if (ec) {
LOG_INFO("timer_event::start_timer what:{}", ec.message());
return;
}
start_timer();
});
}
void timer_event::cancel() {
asio::error_code ec;
timer_.cancel(ec);
recovery();
}
} // namespace flower