23 std::lock_guard<std::mutex> lock(mutex);
24 auto& priorityMap = listeners[size_t(type)];
26 assert(!
contains(priorityMap, &listener, &Entry::listener));
29 priorityMap.emplace(it, Entry{priority, &listener});
35 std::lock_guard<std::mutex> lock(mutex);
36 auto& priorityMap = listeners[size_t(type)];
37 priorityMap.erase(
rfind_unguarded(priorityMap, &listener, &Entry::listener));
49 std::unique_lock<std::mutex> lock(mutex);
50 if (!listeners[
size_t(
getType(event))].empty()) {
51 scheduledEvents.push_back(std::move(event));
57 condition.notify_all();
65 return contains(listeners[
size_t(type)], listener, &Entry::listener);
70 static PriorityMap priorityMapCopy;
71 static EventQueue eventsCopy;
79 std::unique_lock<std::mutex> lock(mutex);
87 while (!scheduledEvents.empty()) {
88 assert(eventsCopy.empty());
89 swap(eventsCopy, scheduledEvents);
90 for (
auto& event : eventsCopy) {
92 priorityMapCopy = listeners[size_t(type)];
94 int blockPriority = Priority::LOWEST;
95 for (
const auto&
e : priorityMapCopy) {
98 if (!isRegistered(type,
e.listener))
continue;
100 if (
e.priority >= blockPriority)
break;
103 if (
int block =
e.listener->signalEvent(event)) {
104 assert(block >
e.priority);
105 blockPriority = block;
116 std::chrono::microseconds duration(us);
117 std::unique_lock<std::mutex> lock(cvMutex);
118 return condition.wait_for(lock, duration) == std::cv_status::timeout;
void unregisterEventListener(EventType type, EventListener &listener)
Unregisters a previously registered event listener.
void distributeEvent(Event &&event)
Schedule the given event for delivery.
EventDistributor(Reactor &reactor)
bool sleep(unsigned us)
Sleep for the specified amount of time, but return early when (another thread) called the distributeE...
void registerEventListener(EventType type, EventListener &listener, Priority priority=OTHER)
Registers a given object to receive certain events.
void deliverEvents()
This actually delivers the events.
Priority
Priorities from high to low, higher priority listeners can block events for lower priority listeners.
void execute()
Execute all expired RTSchedulables.
Contains the main loop of openMSX.
RTScheduler & getRTScheduler()
Interpreter & getInterpreter()
InputEventGenerator & getInputEventGenerator()
bool isMainThread()
Returns true when called from the main thread.
This file implemented 3 utility functions:
EventType getType(const Event &event)
auto upper_bound(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
void swap(openmsx::MemBuffer< T > &l, openmsx::MemBuffer< T > &r) noexcept
auto rfind_unguarded(RANGE &range, const VAL &val, Proj proj={})
Similar to the find(_if)_unguarded functions above, but searches from the back to front.
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.