From 5ccbc5c029e336c91822db8a585cb500ba64e841 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 1 Oct 2018 10:47:06 -0700 Subject: [PATCH] Disable Hand Touch when Leap Motion is running --- interface/src/Application.cpp | 2 ++ .../src/controllers/ScriptingInterface.h | 25 +++++++++++++++++++ libraries/plugins/src/plugins/Plugin.h | 4 +++ .../plugins/src/plugins/PluginManager.cpp | 18 ++++++++++++- libraries/plugins/src/plugins/PluginManager.h | 5 ++++ .../hifiLeapMotion/src/LeapMotionPlugin.cpp | 6 ++--- plugins/hifiLeapMotion/src/LeapMotionPlugin.h | 4 +-- plugins/hifiNeuron/src/NeuronPlugin.cpp | 8 ++++-- plugins/hifiNeuron/src/NeuronPlugin.h | 3 +-- plugins/hifiSdl2/src/SDL2Manager.cpp | 12 +++++---- plugins/hifiSdl2/src/SDL2Manager.h | 3 +-- scripts/system/controllers/handTouch.js | 10 +++++++- 12 files changed, 81 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3a34c87ef1..22cb9148a2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1055,6 +1055,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto controllerScriptingInterface = DependencyManager::get().data(); _controllerScriptingInterface = dynamic_cast(controllerScriptingInterface); + connect(PluginManager::getInstance().data(), &PluginManager::inputDeviceRunningChanged, + controllerScriptingInterface, &controller::ScriptingInterface::updateRunningInputDevices); _entityClipboard->createRootElement(); diff --git a/libraries/controllers/src/controllers/ScriptingInterface.h b/libraries/controllers/src/controllers/ScriptingInterface.h index b0004bc12d..b71bae60bc 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.h +++ b/libraries/controllers/src/controllers/ScriptingInterface.h @@ -431,6 +431,13 @@ namespace controller { */ Q_INVOKABLE QString getInputRecorderSaveDirectory(); + /**jsdoc + * Get all the active and enabled (running) input devices + * @function Controller.getRunningInputDevices + * @returns {string[]} An array of strings with the names + */ + Q_INVOKABLE QStringList getRunningInputDeviceNames() { return _runningInputDeviceNames; } + bool isMouseCaptured() const { return _mouseCaptured; } bool isTouchCaptured() const { return _touchCaptured; } bool isWheelCaptured() const { return _wheelCaptured; } @@ -531,6 +538,11 @@ namespace controller { */ virtual void releaseActionEvents() { _actionsCaptured = false; } + void updateRunningInputDevices(const QString& deviceName, bool isRunning, const QStringList& runningDevices) { + _runningInputDeviceNames = runningDevices; + emit inputDeviceRunningChanged(deviceName, isRunning); + } + signals: /**jsdoc * Triggered when an action occurs. @@ -590,6 +602,17 @@ namespace controller { */ void hardwareChanged(); + /**jsdoc + * Triggered when a device is enabled/disabled + * Enabling/Disabling Leapmotion on settings/controls will trigger this signal. + * @function Controller.deviceRunningChanged + * @param {string} deviceName - The name of the device that is getting enabled/disabled + * @param {boolean} isEnabled - Return if the device is enabled. + * @returns {Signal} + */ + void inputDeviceRunningChanged(QString deviceName, bool isRunning); + + private: // Update the exposed variant maps reporting active hardware void updateMaps(); @@ -598,6 +621,8 @@ namespace controller { QVariantMap _actions; QVariantMap _standard; + QStringList _runningInputDeviceNames; + std::atomic _mouseCaptured{ false }; std::atomic _touchCaptured { false }; std::atomic _wheelCaptured { false }; diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 2d4a24a1fe..a0494ba6d8 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -75,8 +75,11 @@ public: virtual void saveSettings() const {} virtual void loadSettings() {} + virtual bool isRunning() const { return _active; } signals: + void deviceStatusChanged(const QString& deviceName, bool isRunning) const; + // These signals should be emitted when a device is first known to be available. In some cases this will // be in `init()`, in other cases, like Neuron, this isn't known until activation. // SDL2 isn't a device itself, but can have 0+ subdevices. subdeviceConnected is used in this case. @@ -85,6 +88,7 @@ signals: protected: bool _active { false }; + bool _enabled { false }; bool _sessionStatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 94ce16cf00..32d8486e7a 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -225,8 +225,11 @@ void PluginManager::disableDisplayPlugin(const QString& name) { const InputPluginList& PluginManager::getInputPlugins() { static std::once_flag once; - static auto deviceAddedCallback = [](QString deviceName) { + static auto deviceAddedCallback = [&](QString deviceName) { qCDebug(plugins) << "Added device: " << deviceName; + QStringList runningDevices = getRunningInputDeviceNames(); + bool isDeviceRunning = runningDevices.indexOf(deviceName) >= 0; + emit inputDeviceRunningChanged(deviceName, isDeviceRunning, runningDevices); UserActivityLogger::getInstance().connectedDevice("input", deviceName); }; static auto subdeviceAddedCallback = [](QString pluginName, QString deviceName) { @@ -252,6 +255,9 @@ const InputPluginList& PluginManager::getInputPlugins() { for (auto plugin : _inputPlugins) { connect(plugin.get(), &Plugin::deviceConnected, this, deviceAddedCallback, Qt::QueuedConnection); connect(plugin.get(), &Plugin::subdeviceConnected, this, subdeviceAddedCallback, Qt::QueuedConnection); + connect(plugin.get(), &Plugin::deviceStatusChanged, this, [&](const QString& deviceName, bool isRunning) { + emit inputDeviceRunningChanged(deviceName, isRunning, getRunningInputDeviceNames()); + }, Qt::QueuedConnection); plugin->setContainer(_container); plugin->init(); } @@ -259,6 +265,16 @@ const InputPluginList& PluginManager::getInputPlugins() { return _inputPlugins; } +QStringList PluginManager::getRunningInputDeviceNames() const { + QStringList runningDevices; + for (auto plugin: _inputPlugins) { + if (plugin->isRunning()) { + runningDevices << plugin->getName(); + } + } + return runningDevices; +} + void PluginManager::setPreferredDisplayPlugins(const QStringList& displays) { preferredDisplayPlugins = displays; } diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 65a4012aed..c7489fd7e4 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -19,6 +19,7 @@ using PluginManagerPointer = QSharedPointer; class PluginManager : public QObject, public Dependency { SINGLETON_DEPENDENCY + Q_OBJECT public: static PluginManagerPointer getInstance(); @@ -44,6 +45,10 @@ public: void setInputPluginProvider(const InputPluginProvider& provider); void setCodecPluginProvider(const CodecPluginProvider& provider); void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister); + QStringList getRunningInputDeviceNames() const; + +signals: + void inputDeviceRunningChanged(const QString& pluginName, bool isRunning, const QStringList& runningDevices); private: PluginManager() = default; diff --git a/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp b/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp index 174dd02426..5c5b975676 100644 --- a/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp +++ b/plugins/hifiLeapMotion/src/LeapMotionPlugin.cpp @@ -21,7 +21,7 @@ Q_DECLARE_LOGGING_CATEGORY(inputplugins) Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins") -const char* LeapMotionPlugin::NAME = "Leap Motion"; +const char* LeapMotionPlugin::NAME = "LeapMotion"; const char* LeapMotionPlugin::LEAPMOTION_ID_STRING = "Leap Motion"; const bool DEFAULT_ENABLED = false; @@ -203,7 +203,6 @@ static const char* getControllerJointName(controller::StandardPoseChannel i) { return "unknown"; } - void LeapMotionPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { if (!_enabled) { return; @@ -312,13 +311,13 @@ void LeapMotionPlugin::InputDevice::update(float deltaTime, const controller::In void LeapMotionPlugin::init() { loadSettings(); - auto preferences = DependencyManager::get(); static const QString LEAPMOTION_PLUGIN { "Leap Motion" }; { auto getter = [this]()->bool { return _enabled; }; auto setter = [this](bool value) { _enabled = value; + emit deviceStatusChanged(getName(), isRunning()); saveSettings(); if (!_enabled) { auto userInputMapper = DependencyManager::get(); @@ -406,6 +405,7 @@ void LeapMotionPlugin::loadSettings() { settings.beginGroup(idString); { _enabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool(); + emit deviceStatusChanged(getName(), isRunning()); _sensorLocation = settings.value(SETTINGS_SENSOR_LOCATION_KEY, QVariant(DEFAULT_SENSOR_LOCATION)).toString(); _desktopHeightOffset = settings.value(SETTINGS_DESKTOP_HEIGHT_OFFSET_KEY, QVariant(DEFAULT_DESKTOP_HEIGHT_OFFSET)).toFloat(); diff --git a/plugins/hifiLeapMotion/src/LeapMotionPlugin.h b/plugins/hifiLeapMotion/src/LeapMotionPlugin.h index 391d569567..7f5a81d58a 100644 --- a/plugins/hifiLeapMotion/src/LeapMotionPlugin.h +++ b/plugins/hifiLeapMotion/src/LeapMotionPlugin.h @@ -30,7 +30,7 @@ public: // Plugin methods virtual const QString getName() const override { return NAME; } const QString getID() const override { return LEAPMOTION_ID_STRING; } - + bool isRunning() const override { return _active && _enabled; } virtual void init() override; virtual bool activate() override; @@ -43,8 +43,6 @@ protected: static const char* NAME; static const char* LEAPMOTION_ID_STRING; const float DEFAULT_DESKTOP_HEIGHT_OFFSET = 0.2f; - - bool _enabled { false }; QString _sensorLocation; float _desktopHeightOffset { DEFAULT_DESKTOP_HEIGHT_OFFSET }; diff --git a/plugins/hifiNeuron/src/NeuronPlugin.cpp b/plugins/hifiNeuron/src/NeuronPlugin.cpp index 4e27777628..15e99932e1 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.cpp +++ b/plugins/hifiNeuron/src/NeuronPlugin.cpp @@ -369,7 +369,11 @@ void NeuronPlugin::init() { static const QString NEURON_PLUGIN { "Perception Neuron" }; { auto getter = [this]()->bool { return _enabled; }; - auto setter = [this](bool value) { _enabled = value; saveSettings(); }; + auto setter = [this](bool value) { + _enabled = value; + saveSettings(); + emit deviceStatusChanged(getName(), _enabled && _active); + }; auto preference = new CheckPreference(NEURON_PLUGIN, "Enabled", getter, setter); preferences->addPreference(preference); } @@ -493,7 +497,7 @@ void NeuronPlugin::loadSettings() { { // enabled _enabled = settings.value("enabled", QVariant(DEFAULT_ENABLED)).toBool(); - + emit deviceStatusChanged(getName(), _enabled && _active); // serverAddress _serverAddress = settings.value("serverAddress", QVariant(DEFAULT_SERVER_ADDRESS)).toString(); diff --git a/plugins/hifiNeuron/src/NeuronPlugin.h b/plugins/hifiNeuron/src/NeuronPlugin.h index 34d084160f..c2909c54fb 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.h +++ b/plugins/hifiNeuron/src/NeuronPlugin.h @@ -30,7 +30,7 @@ public: virtual bool isSupported() const override; virtual const QString getName() const override { return NAME; } const QString getID() const override { return NEURON_ID_STRING; } - + bool isRunning() const override { return _active && _enabled; } virtual bool activate() override; virtual void deactivate() override; @@ -67,7 +67,6 @@ protected: static const char* NAME; static const char* NEURON_ID_STRING; - bool _enabled; QString _serverAddress; int _serverPort; void* _socketRef; diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index df0cef06c8..7b042909a8 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -79,10 +79,11 @@ bool SDL2Manager::activate() { auto preferences = DependencyManager::get(); static const QString SDL2_PLUGIN { "Game Controller" }; { - auto getter = [this]()->bool { return _isEnabled; }; + auto getter = [this]()->bool { return _enabled; }; auto setter = [this](bool value) { - _isEnabled = value; + _enabled = value; saveSettings(); + emit deviceStatusChanged(getName(), isRunning()); }; auto preference = new CheckPreference(SDL2_PLUGIN, "Enabled", getter, setter); preferences->addPreference(preference); @@ -147,7 +148,7 @@ void SDL2Manager::saveSettings() const { QString idString = getID(); settings.beginGroup(idString); { - settings.setValue(QString(SETTINGS_ENABLED_KEY), _isEnabled); + settings.setValue(QString(SETTINGS_ENABLED_KEY), _enabled); } settings.endGroup(); } @@ -157,7 +158,8 @@ void SDL2Manager::loadSettings() { QString idString = getID(); settings.beginGroup(idString); { - _isEnabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool(); + _enabled = settings.value(SETTINGS_ENABLED_KEY, QVariant(DEFAULT_ENABLED)).toBool(); + emit deviceStatusChanged(getName(), isRunning()); } settings.endGroup(); } @@ -173,7 +175,7 @@ void SDL2Manager::pluginFocusOutEvent() { } void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { - if (!_isEnabled) { + if (!_enabled) { return; } diff --git a/plugins/hifiSdl2/src/SDL2Manager.h b/plugins/hifiSdl2/src/SDL2Manager.h index 48e779a204..0daad6fd8b 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.h +++ b/plugins/hifiSdl2/src/SDL2Manager.h @@ -26,7 +26,7 @@ public: bool isSupported() const override; const QString getName() const override { return NAME; } const QString getID() const override { return SDL2_ID_STRING; } - + bool isRunning() const override { return _active && _enabled; } QStringList getSubdeviceNames() override; void init() override; @@ -81,7 +81,6 @@ private: int buttonRelease() const { return SDL_RELEASED; } QMap _openJoysticks; - bool _isEnabled { false }; bool _isInitialized { false }; static const char* NAME; static const char* SDL2_ID_STRING; diff --git a/scripts/system/controllers/handTouch.js b/scripts/system/controllers/handTouch.js index db79aa4a77..97a24cb3f2 100644 --- a/scripts/system/controllers/handTouch.js +++ b/scripts/system/controllers/handTouch.js @@ -16,7 +16,9 @@ (function () { + var LEAP_MOTION_NAME = "LeapMotion"; var handTouchEnabled = true; + var leapMotionEnabled = Controller.getRunningInputDeviceNames().indexOf(LEAP_MOTION_NAME) >= 0; var MSECONDS_AFTER_LOAD = 2000; var updateFingerWithIndex = 0; var untouchableEntities = []; @@ -870,6 +872,12 @@ handTouchEnabled = !shouldDisable; }); + Controller.inputDeviceRunningChanged.connect(function (deviceName, isEnabled) { + if (deviceName == LEAP_MOTION_NAME) { + leapMotionEnabled = isEnabled; + } + }); + MyAvatar.disableHandTouchForIDChanged.connect(function (entityID, disable) { var entityIndex = untouchableEntities.indexOf(entityID); if (disable) { @@ -902,7 +910,7 @@ Script.update.connect(function () { - if (!handTouchEnabled) { + if (!handTouchEnabled || leapMotionEnabled) { return; }