void RunLoop::runImpl(RunMode runMode) { ASSERT(this == &RunLoop::current()); Status statusOfThisLoop = Status::Clear; { LockHolder locker(m_loopLock); m_mainLoops.append(&statusOfThisLoop); } Deque<RefPtr<TimerBase::ScheduledTask>> firedTimers; while (true) { if (!populateTasks(runMode, statusOfThisLoop, firedTimers)) return; // Dispatch scheduled timers. while (!firedTimers.isEmpty()) { RefPtr<TimerBase::ScheduledTask> task = firedTimers.takeFirst(); if (task->fired()) { // Reschedule because the timer requires repeating. // Since we will query the timers' time points before sleeping, // we do not call wakeUp() here. schedule(*task); } } performWork(); } }
void InputDaemon::refresh() { stop(); Logger::LogInfo("Refreshing joystick list"); QEventLoop q; connect(eventWorker, SIGNAL(sdlStarted()), &q, SLOT(quit())); QMetaObject::invokeMethod(eventWorker, "refresh", Qt::BlockingQueuedConnection); if (eventWorker->isSDLOpen()) { q.exec(); } disconnect(eventWorker, SIGNAL(sdlStarted()), &q, SLOT(quit())); pollResetTimer.stop(); // Put in an extra delay before refreshing the joysticks QTimer temp; connect(&temp, SIGNAL(timeout()), &q, SLOT(quit())); temp.start(100); q.exec(); refreshJoysticks(); QTimer::singleShot(100, eventWorker, SLOT(performWork())); stopped = false; }
LRESULT RunLoop::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case PerformWorkMessage: performWork(); return 0; case WM_TIMER: RunLoop::TimerBase::timerFired(this, wParam); return 0; } return ::DefWindowProc(hWnd, message, wParam, lParam); }
InputDaemon::InputDaemon(QMap<SDL_JoystickID, InputDevice*> *joysticks, AntiMicroSettings *settings, bool graphical, QObject *parent) : QObject(parent), pollResetTimer(this) { this->joysticks = joysticks; this->stopped = false; this->graphical = graphical; this->settings = settings; eventWorker = new SDLEventReader(joysticks, settings); refreshJoysticks(); sdlWorkerThread = 0; if (graphical) { sdlWorkerThread = new QThread(); eventWorker->moveToThread(sdlWorkerThread); } if (graphical) { connect(sdlWorkerThread, SIGNAL(started()), eventWorker, SLOT(performWork())); connect(eventWorker, SIGNAL(eventRaised()), this, SLOT(run())); connect(JoyButton::getMouseHelper(), SIGNAL(gamepadRefreshRateUpdated(uint)), eventWorker, SLOT(updatePollRate(uint))); connect(JoyButton::getMouseHelper(), SIGNAL(gamepadRefreshRateUpdated(uint)), this, SLOT(updatePollResetRate(uint))); connect(JoyButton::getMouseHelper(), SIGNAL(mouseRefreshRateUpdated(uint)), this, SLOT(updatePollResetRate(uint))); // Timer in case SDL does not produce an axis event during a joystick // poll. pollResetTimer.setSingleShot(true); pollResetTimer.setInterval( qMax(JoyButton::getMouseRefreshRate(), JoyButton::getGamepadRefreshRate()) + 1); connect(&pollResetTimer, SIGNAL(timeout()), this, SLOT(resetActiveButtonMouseDistances())); //sdlWorkerThread->start(QThread::HighPriority); //QMetaObject::invokeMethod(eventWorker, "performWork", Qt::QueuedConnection); } }
void InputDaemon::run () { PadderCommon::inputDaemonMutex.lock(); // SDL has found events. The timeout is not necessary. pollResetTimer.stop(); if (!stopped) { //Logger::LogInfo(QString("Gamepad Poll %1").arg(QTime::currentTime().toString("hh:mm:ss.zzz"))); JoyButton::resetActiveButtonMouseDistances(); QQueue<SDL_Event> sdlEventQueue; firstInputPass(&sdlEventQueue); #ifdef USE_SDL_2 modifyUnplugEvents(&sdlEventQueue); #endif secondInputPass(&sdlEventQueue); clearBitArrayStatusInstances(); } if (stopped) { if (joysticks->size() > 0) { emit complete(joysticks->value(0)); } emit complete(); stopped = false; } else { QTimer::singleShot(0, eventWorker, SLOT(performWork())); pollResetTimer.start(); } PadderCommon::inputDaemonMutex.unlock(); }
SDLEventReader::SDLEventReader(QMap<SDL_JoystickID, InputDevice *> *joysticks, AntiMicroSettings *settings, QObject *parent) : QObject(parent) { this->joysticks = joysticks; this->settings = settings; settings->getLock()->lock(); this->pollRate = settings->value("GamepadPollRate", AntiMicroSettings::defaultSDLGamepadPollRate).toUInt(); settings->getLock()->unlock(); pollRateTimer.setParent(this); #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) pollRateTimer.setTimerType(Qt::PreciseTimer); #endif initSDL(); connect(&pollRateTimer, SIGNAL(timeout()), this, SLOT(performWork())); }
void InputDaemon::refresh() { stop(); eventWorker->refresh(); QEventLoop q; connect(eventWorker, SIGNAL(sdlStarted()), &q, SLOT(quit())); q.exec(); disconnect(eventWorker, SIGNAL(sdlStarted()), &q, SLOT(quit())); // Put in an extra delay before refreshing the joysticks QTimer temp; connect(&temp, SIGNAL(timeout()), &q, SLOT(quit())); temp.start(100); q.exec(); refreshJoysticks(); QTimer::singleShot(0, eventWorker, SLOT(performWork())); }
InputDaemon::InputDaemon(QHash<SDL_JoystickID, InputDevice*> *joysticks, bool graphical, QObject *parent) : #else InputDaemon::InputDaemon(QHash<int, InputDevice*> *joysticks, bool graphical, QObject *parent) : #endif QObject(parent) { this->joysticks = joysticks; this->stopped = false; this->graphical = graphical; eventWorker = new SDLEventReader(joysticks); thread = new QThread(); eventWorker->moveToThread(thread); if (graphical) { connect(thread, SIGNAL(started()), eventWorker, SLOT(performWork())); connect(eventWorker, SIGNAL(eventRaised()), this, SLOT(run())); thread->start(); } refreshJoysticks(); } InputDaemon::~InputDaemon() { if (eventWorker) { quit(); } if (thread) { thread->quit(); thread->wait(); delete thread; thread = 0; } } void InputDaemon::run () { SDL_Event event; #ifdef USE_SDL_2 event.type = SDL_FIRSTEVENT; #else event.type = SDL_NOEVENT; #endif if (!stopped) { event = eventWorker->getCurrentEvent(); do { switch (event.type) { case SDL_JOYBUTTONDOWN: { #ifdef USE_SDL_2 InputDevice *joy = trackjoysticks.value(event.jbutton.which); #else InputDevice *joy = joysticks->value(event.jbutton.which); #endif if (joy) { SetJoystick* set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.jbutton.button); if (button) { button->joyEvent(true); } } break; } case SDL_JOYBUTTONUP: { #ifdef USE_SDL_2 InputDevice *joy = trackjoysticks.value(event.jbutton.which); #else InputDevice *joy = joysticks->value(event.jbutton.which); #endif if (joy) { SetJoystick* set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.jbutton.button); if (button) { button->joyEvent(false); } } break; } case SDL_JOYAXISMOTION: { #ifdef USE_SDL_2 InputDevice *joy = trackjoysticks.value(event.jaxis.which); #else InputDevice *joy = joysticks->value(event.jaxis.which); #endif if (joy) { SetJoystick* set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.jaxis.axis); if (axis) { axis->joyEvent(event.jaxis.value); } } break; } case SDL_JOYHATMOTION: { #ifdef USE_SDL_2 InputDevice *joy = trackjoysticks.value(event.jhat.which); #else InputDevice *joy = joysticks->value(event.jhat.which); #endif if (joy) { SetJoystick* set = joy->getActiveSetJoystick(); JoyDPad *dpad = set->getJoyDPad(event.jhat.hat); if (dpad) { dpad->joyEvent(event.jhat.value); } } break; } #ifdef USE_SDL_2 case SDL_CONTROLLERAXISMOTION: { InputDevice *joy = trackcontrollers.value(event.caxis.which); if (joy) { SetJoystick* set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.caxis.axis); if (axis) { axis->joyEvent(event.caxis.value); } } break; } case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: { InputDevice *joy = trackcontrollers.value(event.cbutton.which); if (joy) { SetJoystick* set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.cbutton.button); if (button) { button->joyEvent(event.type == SDL_CONTROLLERBUTTONDOWN ? true : false); } } break; } case SDL_JOYDEVICEREMOVED: { InputDevice *device = joysticks->value(event.jdevice.which); if (device) { removeDevice(device); } break; } case SDL_JOYDEVICEADDED: { addInputDevice(event.jdevice.which); break; } #endif case SDL_QUIT: { stopped = true; break; } default: break; } } while (SDL_PollEvent(&event) > 0); } if (stopped) { if (joysticks->count() > 0) { emit complete(joysticks->value(0)); } emit complete(); stopped = false; // Check for a grabbed instance of an SDL_QUIT event. If the last event was // not an SDL_QUIT event, push an event onto the queue so SdlEventReader // will finish properly. #ifdef USE_SDL_2 if (event.type != SDL_FIRSTEVENT && event.type != SDL_QUIT) #else if (event.type != SDL_NOEVENT && event.type != SDL_QUIT) #endif { event.type = SDL_QUIT; SDL_PushEvent(&event); QTimer::singleShot(0, eventWorker, SLOT(performWork())); } } else { QTimer::singleShot(0, eventWorker, SLOT(performWork())); } }