Fcitx
eventdispatcher.cpp
1 /*
2  * SPDX-FileCopyrightText: 2019-2019 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #include "eventdispatcher.h"
8 #include <functional>
9 #include <memory>
10 #include <mutex>
11 #include <queue>
12 #include <utility>
13 #include "event.h"
14 #include "eventloopinterface.h"
15 #include "macros.h"
16 
17 namespace fcitx {
19 public:
20  void dispatchEvent() {
21  std::queue<std::function<void()>> eventList;
22  {
23  std::lock_guard<std::mutex> lock(mutex_);
24  using std::swap;
25  std::swap(eventList, eventList_);
26  }
27  while (!eventList.empty()) {
28  auto functor = std::move(eventList.front());
29  eventList.pop();
30  functor();
31  }
32  }
33 
34  // Mutex to be used to protect fields below.
35  mutable std::mutex mutex_;
36  std::queue<std::function<void()>> eventList_;
37  std::unique_ptr<EventSourceAsync> asyncEvent_;
38  EventLoop *loop_ = nullptr;
39 };
40 
42  : d_ptr(std::make_unique<EventDispatcherPrivate>()) {}
43 
44 EventDispatcher::~EventDispatcher() = default;
45 
47  FCITX_D();
48  std::lock_guard<std::mutex> lock(d->mutex_);
49  d->asyncEvent_ = event->addAsyncEvent([d](EventSource *) {
50  d->dispatchEvent();
51  return true;
52  });
53  d->loop_ = event;
54 }
55 
57  FCITX_D();
58  std::lock_guard<std::mutex> lock(d->mutex_);
59  d->asyncEvent_.reset();
60  d->loop_ = nullptr;
61 }
62 
63 void EventDispatcher::schedule(std::function<void()> functor) {
64  FCITX_D();
65  std::lock_guard<std::mutex> lock(d->mutex_);
66  // functor can be null and we will still trigger async event.
67  if (functor) {
68  if (!d->asyncEvent_) {
69  return;
70  }
71  d->eventList_.push(std::move(functor));
72  }
73  d->asyncEvent_->send();
74 }
75 
77  FCITX_D();
78  std::lock_guard<std::mutex> lock(d->mutex_);
79  return d->loop_;
80 }
81 
82 } // namespace fcitx
EventDispatcher()
Construct a new event dispatcher.
Definition: action.cpp:17
Definition: matchrule.h:78
EventLoop * eventLoop() const
Return the currently attached event loop.
void attach(EventLoop *event)
Attach EventDispatcher to an EventLoop.
void detach()
Detach event dispatcher from event loop, must be called from the same thread from event loop...
void schedule(std::function< void()> functor)
A thread-safe function to schedule a functor to be call from event loop.