Skip to content

Commit

Permalink
Joystick: Convert Manager from Tool To Singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Oct 16, 2024
1 parent 13031c3 commit b1299b9
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 161 deletions.
2 changes: 1 addition & 1 deletion src/API/QGCCorePlugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ QQmlApplicationEngine* QGCCorePlugin::createQmlApplicationEngine(QObject* parent
{ "eventMonitor", QVariant::fromValue(&eventMonitor) }
}); */
qmlEngine->addImportPath("qrc:/qml");
qmlEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
qmlEngine->rootContext()->setContextProperty("joystickManager", JoystickManager::instance());
qmlEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
return qmlEngine;
}
Expand Down
5 changes: 2 additions & 3 deletions src/Camera/QGCCameraManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ void QGCCameraManager::_vehicleReady(bool ready)
if(ready) {
if(qgcApp()->toolbox()->multiVehicleManager()->activeVehicle() == _vehicle) {
_vehicleReadyState = true;
JoystickManager *pJoyMgr = qgcApp()->toolbox()->joystickManager();
_activeJoystickChanged(pJoyMgr->activeJoystick());
connect(pJoyMgr, &JoystickManager::activeJoystickChanged, this, &QGCCameraManager::_activeJoystickChanged);
_activeJoystickChanged(JoystickManager::instance()->activeJoystick());
connect(JoystickManager::instance(), &JoystickManager::activeJoystickChanged, this, &QGCCameraManager::_activeJoystickChanged);
}
}
}
Expand Down
12 changes: 3 additions & 9 deletions src/Joystick/JoystickAndroid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,8 @@ bool JoystickAndroid::_getHat(int hat,int i) {
}
}

static JoystickManager *_manager = nullptr;

//helper method
bool JoystickAndroid::init(JoystickManager *manager) {
_manager = manager;

bool JoystickAndroid::init() {
//this gets list of all possible buttons - this is needed to check how many buttons our gamepad supports
//instead of the whole logic below we could have just a simple array of hardcoded int values as these 'should' not change

Expand Down Expand Up @@ -296,10 +292,8 @@ static void jniUpdateAvailableJoysticks(JNIEnv *envA, jobject thizA)
Q_UNUSED(envA);
Q_UNUSED(thizA);

if (_manager != nullptr) {
qCDebug(JoystickLog) << "jniUpdateAvailableJoysticks triggered";
emit _manager->updateAvailableJoysticksSignal();
}
qCDebug(JoystickLog) << "jniUpdateAvailableJoysticks triggered";
emit JoystickManager::instance()->updateAvailableJoysticksSignal();
}

void JoystickAndroid::setNativeMethods()
Expand Down
4 changes: 1 addition & 3 deletions src/Joystick/JoystickAndroid.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@
#include <QtCore/private/qandroidextras_p.h>

class MultiVehicleManager;
class JoystickManager;

class JoystickAndroid : public Joystick, public QtAndroidPrivate::GenericMotionEventListener, public QtAndroidPrivate::KeyEventListener
{
public:
JoystickAndroid(const QString& name, int axisCount, int buttonCount, int id, MultiVehicleManager* multiVehicleManager);

~JoystickAndroid();

static bool init(JoystickManager *manager);
static bool init();

static void setNativeMethods();

Expand Down
130 changes: 60 additions & 70 deletions src/Joystick/JoystickManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,85 @@
*
****************************************************************************/


#include "JoystickManager.h"
#include "MultiVehicleManager.h"
#include "Joystick.h"
#if defined(QGC_SDL_JOYSTICK)
#include "JoystickSDL.h"
#elif defined(Q_OS_ANDROID)
#include "JoystickAndroid.h"
#endif
#include "QGCApplication.h"
#include "MultiVehicleManager.h"
#include "QGCLoggingCategory.h"

#include <QtCore/qapplicationstatic.h>
#include <QtCore/QSettings>
#include <QtCore/QTimer>
#include <QtQml/QQmlEngine>
#include <QtQml/QtQml>

QGC_LOGGING_CATEGORY(JoystickManagerLog, "JoystickManagerLog")
QGC_LOGGING_CATEGORY(JoystickManagerLog, "qgc.joystick.joystickmanager")

JoystickManager::JoystickManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _activeJoystick(nullptr)
, _multiVehicleManager(nullptr)
Q_APPLICATION_STATIC(JoystickManager, _joystickManager);

JoystickManager::JoystickManager(QObject *parent)
: QObject(parent)
, _joystickCheckTimer(new QTimer(this))
{
// qCDebug(JoystickManagerLog) << Q_FUNC_INFO << this;

(void) qmlRegisterUncreatableType<JoystickManager>("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
(void) qmlRegisterUncreatableType<Joystick>("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");

_joystickCheckTimer->setInterval(1000);
_joystickCheckTimer->setSingleShot(true);
}

JoystickManager::~JoystickManager()
{
QMap<QString, Joystick*>::iterator i;
for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
qCDebug(JoystickManagerLog) << "Releasing joystick:" << i.key();
i.value()->stop();
delete i.value();
for (QMap<QString, Joystick*>::key_value_iterator it = _name2JoystickMap.keyValueBegin(); it != _name2JoystickMap.keyValueEnd(); ++it) {
qCDebug(JoystickManagerLog) << "Releasing joystick:" << it->first;
it->second->stop();
delete it->second;
}

// qCDebug(JoystickManagerLog) << Q_FUNC_INFO << this;
}

void JoystickManager::setToolbox(QGCToolbox *toolbox)
JoystickManager *JoystickManager::instance()
{
QGCTool::setToolbox(toolbox);

_multiVehicleManager = _toolbox->multiVehicleManager();

QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<JoystickManager>("QGroundControl.JoystickManager", 1, 0, "JoystickManager", "Reference only");
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", "Reference only");
return _joystickManager();
}

void JoystickManager::init() {
void JoystickManager::init()
{
#ifdef QGC_SDL_JOYSTICK
if (!JoystickSDL::init()) {
return;
}
_setActiveJoystickFromSettings();
#elif defined(Q_OS_ANDROID)
if (!JoystickAndroid::init(this)) {
if (!JoystickAndroid::init()) {
return;
}
connect(this, &JoystickManager::updateAvailableJoysticksSignal, this, &JoystickManager::restartJoystickCheckTimer);
(void) connect(this, &JoystickManager::updateAvailableJoysticksSignal, this, [this]() {
_joystickCheckTimerCounter = 5;
_joystickCheckTimer->start();
});
#endif
connect(&_joystickCheckTimer, &QTimer::timeout, this, &JoystickManager::_updateAvailableJoysticks);
(void) connect(_joystickCheckTimer, &QTimer::timeout, this, &JoystickManager::_updateAvailableJoysticks);
_joystickCheckTimerCounter = 5;
_joystickCheckTimer.start(1000);
_joystickCheckTimer->start();
}

void JoystickManager::_setActiveJoystickFromSettings(void)
void JoystickManager::_setActiveJoystickFromSettings()
{
QMap<QString,Joystick*> newMap;

#ifdef QGC_SDL_JOYSTICK
// Get the latest joystick mapping
newMap = JoystickSDL::discover(_multiVehicleManager);
newMap = JoystickSDL::discover(qgcApp()->toolbox()->multiVehicleManager());
#elif defined(Q_OS_ANDROID)
newMap = JoystickAndroid::discover(_multiVehicleManager);
newMap = JoystickAndroid::discover(qgcApp()->toolbox()->multiVehicleManager());
#endif

if (_activeJoystick && !newMap.contains(_activeJoystick->name())) {
Expand All @@ -90,47 +95,45 @@ void JoystickManager::_setActiveJoystickFromSettings(void)

// Check to see if our current mapping contains any joysticks that are not in the new mapping
// If so, those joysticks have been unplugged, and need to be cleaned up
QMap<QString, Joystick*>::iterator i;
for (i = _name2JoystickMap.begin(); i != _name2JoystickMap.end(); ++i) {
if (!newMap.contains(i.key())) {
qCDebug(JoystickManagerLog) << "Releasing joystick:" << i.key();
i.value()->stopPolling();
i.value()->wait(1000);
i.value()->deleteLater();
for (QMap<QString, Joystick*>::key_value_iterator it = _name2JoystickMap.keyValueBegin(); it != _name2JoystickMap.keyValueEnd(); ++it) {
if (!newMap.contains(it->first)) {
qCDebug(JoystickManagerLog) << "Releasing joystick:" << it->first;
it->second->stopPolling();
it->second->wait(1000);
it->second->deleteLater();
}
}

_name2JoystickMap = newMap;
emit availableJoysticksChanged();

if (!_name2JoystickMap.count()) {
if (_name2JoystickMap.isEmpty()) {
setActiveJoystick(nullptr);
return;
}

QSettings settings;

settings.beginGroup(_settingsGroup);
QString name = settings.value(_settingsKeyActiveJoystick).toString();

QString name = settings.value(_settingsKeyActiveJoystick).toString();
if (name.isEmpty()) {
name = _name2JoystickMap.first()->name();
}

setActiveJoystick(_name2JoystickMap.value(name, _name2JoystickMap.first()));
settings.setValue(_settingsKeyActiveJoystick, _activeJoystick->name());

settings.endGroup();
}

Joystick* JoystickManager::activeJoystick(void)
Joystick *JoystickManager::activeJoystick()
{
return _activeJoystick;
}

void JoystickManager::setActiveJoystick(Joystick* joystick)
void JoystickManager::setActiveJoystick(Joystick *joystick)
{
QSettings settings;

if (joystick != nullptr && !_name2JoystickMap.contains(joystick->name())) {
if (joystick && !_name2JoystickMap.contains(joystick->name())) {
qCWarning(JoystickManagerLog) << "Set active not in map" << joystick->name();
return;
}
Expand All @@ -148,49 +151,42 @@ void JoystickManager::setActiveJoystick(Joystick* joystick)
if (_activeJoystick != nullptr) {
qCDebug(JoystickManagerLog) << "Set active:" << _activeJoystick->name();

QSettings settings;
settings.beginGroup(_settingsGroup);
settings.setValue(_settingsKeyActiveJoystick, _activeJoystick->name());
settings.endGroup();
}

emit activeJoystickChanged(_activeJoystick);
emit activeJoystickNameChanged(_activeJoystick?_activeJoystick->name():"");
emit activeJoystickNameChanged(_activeJoystick ? _activeJoystick->name() : "");
}

QVariantList JoystickManager::joysticks(void)
QVariantList JoystickManager::joysticks()
{
QVariantList list;

for (const QString &name: _name2JoystickMap.keys()) {
list += QVariant::fromValue(_name2JoystickMap[name]);
for (auto it = _name2JoystickMap.constBegin(); it != _name2JoystickMap.constEnd(); ++it) {
list += QVariant::fromValue(it.value());
}

return list;
}

QStringList JoystickManager::joystickNames(void)
{
return _name2JoystickMap.keys();
}

QString JoystickManager::activeJoystickName(void)
QString JoystickManager::activeJoystickName() const
{
return _activeJoystick ? _activeJoystick->name() : QString();
return (_activeJoystick ? _activeJoystick->name() : QString());
}

bool JoystickManager::setActiveJoystickName(const QString& name)
bool JoystickManager::setActiveJoystickName(const QString &name)
{
if (_name2JoystickMap.contains(name)) {
setActiveJoystick(_name2JoystickMap[name]);
return true;
} else {
qCWarning(JoystickManagerLog) << "Set active not in map" << name;
return false;
}

qCWarning(JoystickManagerLog) << "Set active not in map" << name;
return false;
}

/*
* TODO: move this to the right place: JoystickSDL.cc and JoystickAndroid.cc respectively and call through Joystick.cc
*/
void JoystickManager::_updateAvailableJoysticks()
{
#ifdef QGC_SDL_JOYSTICK
Expand All @@ -216,13 +212,7 @@ void JoystickManager::_updateAvailableJoysticks()
_joystickCheckTimerCounter--;
_setActiveJoystickFromSettings();
if (_joystickCheckTimerCounter <= 0) {
_joystickCheckTimer.stop();
_joystickCheckTimer->stop();
}
#endif
}

void JoystickManager::restartJoystickCheckTimer()
{
_joystickCheckTimerCounter = 5;
_joystickCheckTimer.start(1000);
}
Loading

0 comments on commit b1299b9

Please sign in to comment.