| 97 | } |
| 98 | |
| 99 | bool EventQueue::processEvent(Event &event, double timeout, Stopwatch &timer) |
| 100 | { |
| 101 | // if no events are waiting then handle timers and then wait |
| 102 | while (m_buffer->isEmpty()) { |
| 103 | // handle timers first |
| 104 | if (hasTimerExpired(event)) { |
| 105 | return true; |
| 106 | } |
| 107 | |
| 108 | // get time remaining in timeout |
| 109 | double timeLeft = timeout - timer.getTime(); |
| 110 | if (timeout >= 0.0 && timeLeft <= 0.0) { |
| 111 | return false; |
| 112 | } |
| 113 | |
| 114 | // get time until next timer expires. if there is a timer |
| 115 | // and it'll expire before the client's timeout then use |
| 116 | // that duration for our timeout instead. |
| 117 | if (double timerTimeout = getNextTimerTimeout(); |
| 118 | timeout < 0.0 || (timerTimeout >= 0.0 && timerTimeout < timeLeft)) { |
| 119 | timeLeft = timerTimeout; |
| 120 | } |
| 121 | |
| 122 | // wait for an event |
| 123 | m_buffer->waitForEvent(timeLeft); |
| 124 | } |
| 125 | |
| 126 | // get the event |
| 127 | uint32_t dataID; |
| 128 | IEventQueueBuffer::Type type = m_buffer->getEvent(event, dataID); |
| 129 | switch (type) { |
| 130 | using enum IEventQueueBuffer::Type; |
| 131 | case Unknown: |
| 132 | if (timeout < 0.0 || timeout <= timer.getTime()) { |
| 133 | // don't want to fail if client isn't expecting that |
| 134 | // so if getEvent() fails with an infinite timeout |
| 135 | // then just try getting another event. |
| 136 | processEvent(event, timeout, timer); |
| 137 | } |
| 138 | return false; |
| 139 | |
| 140 | case System: |
| 141 | return true; |
| 142 | |
| 143 | case User: { |
| 144 | std::scoped_lock lock{m_mutex}; |
| 145 | event = removeEvent(dataID); |
| 146 | return true; |
| 147 | } |
| 148 | |
| 149 | default: |
| 150 | assert(0 && "invalid event type"); |
| 151 | return false; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | bool EventQueue::getEvent(Event &event, double timeout) |
| 156 | { |
nothing calls this directly
no test coverage detected