在上一篇文章《C++实现简化版Qt的QObject(4):增加简单实用的事件机制》中,我们实现了普通线程的事件机制。
但是事件机制往往需要和操作系统主线程消息循环一起工作。
因此,今天,我们在之前的CEventLoop的实现之上,通过IEventLoopHost扩展,实现一个windows系统的主线程消息循环扩展,使得我们可以在主线程post task。
CEventLoop 代码
首先,昨天我们写的CEventLoop代码如下:
class CEventLoop {
public:
using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point;
using Duration = Clock::duration;
using Handler = std::function<void()>;
struct TimedHandler {
TimePoint time;
Handler handler;
bool operator<(const TimedHandler& other) const {
return time > other.time;
}
};
class IEventLoopHost {
public:
virtual void onPostTask() = 0;
virtual void onWaitForTask(std::condition_variable& cond, std::unique_lock<std::mutex>& locker) = 0;
virtual void onEvent(TimedHandler& event) = 0;
virtual void onWaitForRun(std::condition_variable& cond, std::unique_lock<std::mutex>& locker, const TimePoint& timePoint) = 0;
};
private:
IEventLoopHost* host = nullptr;
std::priority_queue<TimedHandler> tasks_;
std::mutex mutex_;
std::condition_variable cond_;
std::atomic<bool> running_{
true };
public:
void setHost(IEventLoopHost* host) {
this->host = host;
}
void post(Handler handler, Duration delay = Duration::zero()) {
std::unique_lock<std::mutex> lock(mutex_);
tasks_.push({
Clock::now() + delay, std::move(handler) });
cond_.notify_one();
if (host) {
host->onPostTask();
}
}
void run() {
while (running_) {
std::unique_lock<std::mutex>