From 0fdd32709f6eb7c52c3dc98568823516cb94671b Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 23 Oct 2015 13:28:36 -0700 Subject: [PATCH] Moving conditionals and endpoints out of UserInputMapper Conflicts: libraries/controllers/src/controllers/UserInputMapper.cpp --- .../src/controllers/UserInputMapper.cpp | 341 +----------------- .../controllers/{ => impl}/Conditional.cpp | 0 .../src/controllers/{ => impl}/Conditional.h | 0 .../src/controllers/{ => impl}/Endpoint.cpp | 0 .../src/controllers/{ => impl}/Endpoint.h | 4 +- .../src/controllers/{ => impl}/Filter.cpp | 0 .../src/controllers/{ => impl}/Filter.h | 0 .../src/controllers/{ => impl}/Mapping.cpp | 0 .../src/controllers/{ => impl}/Mapping.h | 0 .../controllers/impl/MappingBuilderProxy.h | 4 +- .../src/controllers/{ => impl}/Route.cpp | 0 .../src/controllers/{ => impl}/Route.h | 0 .../src/controllers/impl/RouteBuilderProxy.h | 8 +- .../impl/conditionals/AndConditional.cpp | 20 + .../impl/conditionals/AndConditional.h | 32 ++ .../impl/conditionals/EndpointConditional.cpp | 9 + .../impl/conditionals/EndpointConditional.h | 27 ++ .../impl/conditionals/NotConditional.cpp | 9 + .../impl/conditionals/NotConditional.h | 16 + .../impl/conditionals/ScriptConditional.cpp | 27 ++ .../impl/conditionals/ScriptConditional.h | 34 ++ .../impl/endpoints/ActionEndpoint.cpp | 40 ++ .../impl/endpoints/ActionEndpoint.h | 41 +++ .../impl/endpoints/AnyEndpoint.cpp | 63 ++++ .../controllers/impl/endpoints/AnyEndpoint.h | 32 ++ .../impl/endpoints/ArrayEndpoint.cpp | 9 + .../impl/endpoints/ArrayEndpoint.h | 43 +++ .../impl/endpoints/CompositeEndpoint.cpp | 32 ++ .../impl/endpoints/CompositeEndpoint.h | 26 ++ .../impl/endpoints/InputEndpoint.cpp | 41 +++ .../impl/endpoints/InputEndpoint.h | 39 ++ .../controllers/impl/endpoints/JSEndpoint.cpp | 9 + .../controllers/impl/endpoints/JSEndpoint.h | 41 +++ .../impl/endpoints/ScriptEndpoint.cpp | 43 +++ .../impl/endpoints/ScriptEndpoint.h | 39 ++ .../impl/endpoints/StandardEndpoint.cpp | 9 + .../impl/endpoints/StandardEndpoint.h | 60 +++ 37 files changed, 766 insertions(+), 332 deletions(-) rename libraries/controllers/src/controllers/{ => impl}/Conditional.cpp (100%) rename libraries/controllers/src/controllers/{ => impl}/Conditional.h (100%) rename libraries/controllers/src/controllers/{ => impl}/Endpoint.cpp (100%) rename libraries/controllers/src/controllers/{ => impl}/Endpoint.h (98%) rename libraries/controllers/src/controllers/{ => impl}/Filter.cpp (100%) rename libraries/controllers/src/controllers/{ => impl}/Filter.h (100%) rename libraries/controllers/src/controllers/{ => impl}/Mapping.cpp (100%) rename libraries/controllers/src/controllers/{ => impl}/Mapping.h (100%) rename libraries/controllers/src/controllers/{ => impl}/Route.cpp (100%) rename libraries/controllers/src/controllers/{ => impl}/Route.h (100%) create mode 100644 libraries/controllers/src/controllers/impl/conditionals/AndConditional.cpp create mode 100644 libraries/controllers/src/controllers/impl/conditionals/AndConditional.h create mode 100644 libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp create mode 100644 libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h create mode 100644 libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp create mode 100644 libraries/controllers/src/controllers/impl/conditionals/NotConditional.h create mode 100644 libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.cpp create mode 100644 libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h create mode 100644 libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp create mode 100644 libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 30fd650eba..19a4b78207 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -24,9 +24,22 @@ #include "Logging.h" -#include "Endpoint.h" -#include "Route.h" -#include "Mapping.h" +#include "impl/conditionals/AndConditional.h" +#include "impl/conditionals/EndpointConditional.h" +#include "impl/conditionals/ScriptConditional.h" + +#include "impl/endpoints/ActionEndpoint.h" +#include "impl/endpoints/AnyEndpoint.h" +#include "impl/endpoints/ArrayEndpoint.h" +#include "impl/endpoints/CompositeEndpoint.h" +#include "impl/endpoints/InputEndpoint.h" +#include "impl/endpoints/JSEndpoint.h" +#include "impl/endpoints/ScriptEndpoint.h" +#include "impl/endpoints/StandardEndpoint.h" + +#include "impl/Route.h" +#include "impl/Mapping.h" + namespace controller { const uint16_t UserInputMapper::ACTIONS_DEVICE = Input::INVALID_DEVICE - 0xFF; @@ -42,300 +55,6 @@ controller::UserInputMapper::UserInputMapper() { namespace controller { -class ScriptEndpoint : public Endpoint { - Q_OBJECT; -public: - ScriptEndpoint(const QScriptValue& callable) - : Endpoint(Input::INVALID_INPUT), _callable(callable) { - } - - virtual float value(); - virtual void apply(float newValue, float oldValue, const Pointer& source); - -protected: - Q_INVOKABLE void updateValue(); - Q_INVOKABLE virtual void internalApply(float newValue, float oldValue, int sourceID); -private: - QScriptValue _callable; - float _lastValue = 0.0f; -}; - -class StandardEndpoint : public VirtualEndpoint { -public: - StandardEndpoint(const Input& input) : VirtualEndpoint(input) {} - virtual bool writeable() const override { return !_written; } - virtual bool readable() const override { return !_read; } - virtual void reset() override { - apply(0.0f, 0.0f, Endpoint::Pointer()); - apply(Pose(), Pose(), Endpoint::Pointer()); - _written = _read = false; - } - - virtual float value() override { - _read = true; - return VirtualEndpoint::value(); - } - - virtual void apply(float newValue, float oldValue, const Pointer& source) override { - // For standard endpoints, the first NON-ZERO write counts. - if (newValue != 0.0) { - _written = true; - } - VirtualEndpoint::apply(newValue, oldValue, source); - } - - virtual Pose pose() override { - _read = true; - return VirtualEndpoint::pose(); - } - - virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override { - if (newValue != Pose()) { - _written = true; - } - VirtualEndpoint::apply(newValue, oldValue, source); - } - -private: - bool _written { false }; - bool _read { false }; -}; - - -class JSEndpoint : public Endpoint { -public: - JSEndpoint(const QJSValue& callable) - : Endpoint(Input::INVALID_INPUT), _callable(callable) { - } - - virtual float value() { - float result = (float)_callable.call().toNumber();; - return result; - } - - virtual void apply(float newValue, float oldValue, const Pointer& source) { - _callable.call(QJSValueList({ QJSValue(newValue) })); - } - -private: - QJSValue _callable; -}; - -float ScriptEndpoint::value() { - updateValue(); - return _lastValue; -} - -void ScriptEndpoint::updateValue() { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "updateValue", Qt::QueuedConnection); - return; - } - - _lastValue = (float)_callable.call().toNumber(); -} - -void ScriptEndpoint::apply(float newValue, float oldValue, const Pointer& source) { - internalApply(newValue, oldValue, source->getInput().getID()); -} - -void ScriptEndpoint::internalApply(float newValue, float oldValue, int sourceID) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "internalApply", Qt::QueuedConnection, - Q_ARG(float, newValue), - Q_ARG(float, oldValue), - Q_ARG(int, sourceID)); - return; - } - _callable.call(QScriptValue(), - QScriptValueList({ QScriptValue(newValue), QScriptValue(oldValue), QScriptValue(sourceID) })); -} - -static const Input INVALID_STANDARD_INPUT = Input(UserInputMapper::STANDARD_DEVICE, Input::INVALID_CHANNEL, ChannelType::INVALID); - -class CompositeEndpoint : public Endpoint, Endpoint::Pair { -public: - CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second) - : Endpoint(Input::INVALID_INPUT), Pair(first, second) { - if (first->getInput().device == UserInputMapper::STANDARD_DEVICE && - second->getInput().device == UserInputMapper::STANDARD_DEVICE) { - this->_input = INVALID_STANDARD_INPUT; - } - } - - virtual float value() { - float result = first->value() * -1.0f + second->value(); - return result; - } - - virtual void apply(float newValue, float oldValue, const Pointer& source) { - // Composites are read only - } -}; - -class ArrayEndpoint : public Endpoint { - friend class UserInputMapper; -public: - using Pointer = std::shared_ptr; - ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { } - - virtual float value() override { - return 0.0; - } - - virtual void apply(float newValue, float oldValue, const Endpoint::Pointer& source) override { - for (auto& child : _children) { - if (child->writeable()) { - child->apply(newValue, oldValue, source); - } - } - } - - virtual bool readable() const override { return false; } - -private: - Endpoint::List _children; -}; - -class AnyEndpoint : public Endpoint { - friend class UserInputMapper; -public: - using Pointer = std::shared_ptr; - AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPUT), _children(children) { - bool standard = true; - // Ensure if we're building a composite of standard devices the composite itself - // is treated as a standard device for rule processing order - for (auto endpoint : children) { - if (endpoint->getInput().device != UserInputMapper::STANDARD_DEVICE) { - standard = false; - break; - } - } - if (standard) { - this->_input = INVALID_STANDARD_INPUT; - } - } - - virtual float value() override { - float result = 0.0f; - for (auto& child : _children) { - float childResult = child->value(); - if (childResult != 0.0f && result == 0.0f) { - result = childResult; - } - } - return result; - } - - virtual void apply(float newValue, float oldValue, const Endpoint::Pointer& source) override { - qFatal("AnyEndpoint is read only"); - } - - // AnyEndpoint is used for reading, so return false if any child returns false (has been written to) - virtual bool writeable() const override { - for (auto& child : _children) { - if (!child->writeable()) { - return false; - } - } - return true; - } - - virtual bool readable() const override { - for (auto& child : _children) { - if (!child->readable()) { - return false; - } - } - return true; - } - -private: - Endpoint::List _children; -}; - -class InputEndpoint : public Endpoint { -public: - InputEndpoint(const Input& id = Input::INVALID_INPUT) - : Endpoint(id) { - } - - virtual float value() override { - _read = true; - if (isPose()) { - return pose().valid ? 1.0f : 0.0f; - } - auto userInputMapper = DependencyManager::get(); - auto deviceProxy = userInputMapper->getDeviceProxy(_input); - if (!deviceProxy) { - return 0.0f; - } - return deviceProxy->getValue(_input, 0); - } - - // FIXME need support for writing back to vibration / force feedback effects - virtual void apply(float newValue, float oldValue, const Pointer& source) override {} - - virtual Pose pose() override { - _read = true; - if (!isPose()) { - return Pose(); - } - auto userInputMapper = DependencyManager::get(); - auto deviceProxy = userInputMapper->getDeviceProxy(_input); - if (!deviceProxy) { - return Pose(); - } - return deviceProxy->getPose(_input, 0); - } - - virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override { } - - virtual bool writeable() const { return false; } - virtual bool readable() const { return !_read; } - virtual void reset() { _read = false; } - -private: - bool _read { false }; -}; - -class ActionEndpoint : public Endpoint { -public: - ActionEndpoint(const Input& id = Input::INVALID_INPUT) - : Endpoint(id) { - } - - virtual float value() override { return _currentValue; } - virtual void apply(float newValue, float oldValue, const Pointer& source) override { - _currentValue += newValue; - if (_input != Input::INVALID_INPUT) { - auto userInputMapper = DependencyManager::get(); - userInputMapper->deltaActionState(Action(_input.getChannel()), newValue); - } - } - - virtual Pose pose() override { return _currentPose; } - virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override { - _currentPose = newValue; - if (!_currentPose.isValid()) { - return; - } - if (_input != Input::INVALID_INPUT) { - auto userInputMapper = DependencyManager::get(); - userInputMapper->setActionState(Action(_input.getChannel()), _currentPose); - } - } - - virtual void reset() override { - _currentValue = 0.0f; - _currentPose = Pose(); - } - -private: - float _currentValue{ 0.0f }; - Pose _currentPose{}; -}; - UserInputMapper::~UserInputMapper() { } @@ -1019,33 +738,6 @@ Endpoint::Pointer UserInputMapper::parseEndpoint(const QJsonValue& value) { return result; } -class AndConditional : public Conditional { -public: - using Pointer = std::shared_ptr; - - AndConditional(Conditional::List children) : _children(children) { } - - virtual bool satisfied() override { - for (auto& conditional : _children) { - if (!conditional->satisfied()) { - return false; - } - } - return true; - } - -private: - Conditional::List _children; -}; - -class EndpointConditional : public Conditional { -public: - EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {} - virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0; } -private: - Endpoint::Pointer _endpoint; -}; - Conditional::Pointer UserInputMapper::parseConditional(const QJsonValue& value) { if (value.isArray()) { // Support "when" : [ "GamePad.RB", "GamePad.LB" ] @@ -1290,4 +982,3 @@ void UserInputMapper::disableMapping(const Mapping::Pointer& mapping) { } -#include "UserInputMapper.moc" diff --git a/libraries/controllers/src/controllers/Conditional.cpp b/libraries/controllers/src/controllers/impl/Conditional.cpp similarity index 100% rename from libraries/controllers/src/controllers/Conditional.cpp rename to libraries/controllers/src/controllers/impl/Conditional.cpp diff --git a/libraries/controllers/src/controllers/Conditional.h b/libraries/controllers/src/controllers/impl/Conditional.h similarity index 100% rename from libraries/controllers/src/controllers/Conditional.h rename to libraries/controllers/src/controllers/impl/Conditional.h diff --git a/libraries/controllers/src/controllers/Endpoint.cpp b/libraries/controllers/src/controllers/impl/Endpoint.cpp similarity index 100% rename from libraries/controllers/src/controllers/Endpoint.cpp rename to libraries/controllers/src/controllers/impl/Endpoint.cpp diff --git a/libraries/controllers/src/controllers/Endpoint.h b/libraries/controllers/src/controllers/impl/Endpoint.h similarity index 98% rename from libraries/controllers/src/controllers/Endpoint.h rename to libraries/controllers/src/controllers/impl/Endpoint.h index 7a94b06e7e..f5fe058d82 100644 --- a/libraries/controllers/src/controllers/Endpoint.h +++ b/libraries/controllers/src/controllers/impl/Endpoint.h @@ -16,8 +16,8 @@ #include -#include "Input.h" -#include "Pose.h" +#include "../Input.h" +#include "../Pose.h" class QScriptValue; diff --git a/libraries/controllers/src/controllers/Filter.cpp b/libraries/controllers/src/controllers/impl/Filter.cpp similarity index 100% rename from libraries/controllers/src/controllers/Filter.cpp rename to libraries/controllers/src/controllers/impl/Filter.cpp diff --git a/libraries/controllers/src/controllers/Filter.h b/libraries/controllers/src/controllers/impl/Filter.h similarity index 100% rename from libraries/controllers/src/controllers/Filter.h rename to libraries/controllers/src/controllers/impl/Filter.h diff --git a/libraries/controllers/src/controllers/Mapping.cpp b/libraries/controllers/src/controllers/impl/Mapping.cpp similarity index 100% rename from libraries/controllers/src/controllers/Mapping.cpp rename to libraries/controllers/src/controllers/impl/Mapping.cpp diff --git a/libraries/controllers/src/controllers/Mapping.h b/libraries/controllers/src/controllers/impl/Mapping.h similarity index 100% rename from libraries/controllers/src/controllers/Mapping.h rename to libraries/controllers/src/controllers/impl/Mapping.h diff --git a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h index 93aa022647..ac9a5a300d 100644 --- a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h @@ -12,8 +12,8 @@ #include #include -#include "../Mapping.h" -#include "../Endpoint.h" +#include "Mapping.h" +#include "Endpoint.h" class QJSValue; class QScriptValue; diff --git a/libraries/controllers/src/controllers/Route.cpp b/libraries/controllers/src/controllers/impl/Route.cpp similarity index 100% rename from libraries/controllers/src/controllers/Route.cpp rename to libraries/controllers/src/controllers/impl/Route.cpp diff --git a/libraries/controllers/src/controllers/Route.h b/libraries/controllers/src/controllers/impl/Route.h similarity index 100% rename from libraries/controllers/src/controllers/Route.h rename to libraries/controllers/src/controllers/impl/Route.h diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h index 0484c5890d..2303f6184f 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h @@ -11,10 +11,12 @@ #include -#include "../Filter.h" -#include "../Route.h" -#include "../Mapping.h" +#include "Filter.h" +#include "Route.h" +#include "Mapping.h" + #include "../UserInputMapper.h" + class QJSValue; class QScriptValue; class QJsonValue; diff --git a/libraries/controllers/src/controllers/impl/conditionals/AndConditional.cpp b/libraries/controllers/src/controllers/impl/conditionals/AndConditional.cpp new file mode 100644 index 0000000000..1633f9a439 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/AndConditional.cpp @@ -0,0 +1,20 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AndConditional.h" + +using namespace controller; + +bool AndConditional::satisfied() { + for (auto& conditional : _children) { + if (!conditional->satisfied()) { + return false; + } + } + return true; +} diff --git a/libraries/controllers/src/controllers/impl/conditionals/AndConditional.h b/libraries/controllers/src/controllers/impl/conditionals/AndConditional.h new file mode 100644 index 0000000000..5fc8b7df2a --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/AndConditional.h @@ -0,0 +1,32 @@ +// +// Created by Bradley Austin Davis 2015/10/20 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_AndConditional_h +#define hifi_Controllers_AndConditional_h + +#include "../Conditional.h" + +namespace controller { + +class AndConditional : public Conditional { +public: + using Pointer = std::shared_ptr; + + AndConditional(Conditional::List children) : _children(children) { } + + virtual bool satisfied() override; + +private: + Conditional::List _children; +}; + +} + + +#endif diff --git a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp new file mode 100644 index 0000000000..03e16b8cf9 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.cpp @@ -0,0 +1,9 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "EndpointConditional.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h new file mode 100644 index 0000000000..1e4205afc7 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h @@ -0,0 +1,27 @@ +// +// Created by Bradley Austin Davis 2015/10/20 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_EndpointConditional_h +#define hifi_Controllers_EndpointConditional_h + +#include "../Conditional.h" +#include "../Endpoint.h" + +namespace controller { + +class EndpointConditional : public Conditional { +public: + EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {} + virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0; } +private: + Endpoint::Pointer _endpoint; +}; + +} +#endif diff --git a/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp b/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp new file mode 100644 index 0000000000..0c8d602b9e --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/NotConditional.cpp @@ -0,0 +1,9 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "NotConditional.h" diff --git a/libraries/controllers/src/controllers/impl/conditionals/NotConditional.h b/libraries/controllers/src/controllers/impl/conditionals/NotConditional.h new file mode 100644 index 0000000000..3acda07106 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/NotConditional.h @@ -0,0 +1,16 @@ +// +// Created by Bradley Austin Davis 2015/10/20 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_NotConditional_h +#define hifi_Controllers_NotConditional_h + +#include "../Conditional.h" + + +#endif diff --git a/libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.cpp b/libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.cpp new file mode 100644 index 0000000000..277b63ed11 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.cpp @@ -0,0 +1,27 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ScriptConditional.h" + +#include + +using namespace controller; + +bool ScriptConditional::satisfied() { + updateValue(); + return _lastValue; +} + +void ScriptConditional::updateValue() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "updateValue", Qt::QueuedConnection); + return; + } + + _lastValue = _callable.call().toBool(); +} diff --git a/libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.h b/libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.h new file mode 100644 index 0000000000..800692d02c --- /dev/null +++ b/libraries/controllers/src/controllers/impl/conditionals/ScriptConditional.h @@ -0,0 +1,34 @@ +// +// Created by Bradley Austin Davis 2015/10/20 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_ScriptConditional_h +#define hifi_Controllers_ScriptConditional_h + +#include + +#include + +#include "../Conditional.h" + +namespace controller { + +class ScriptConditional : public QObject, public Conditional { + Q_OBJECT; +public: + ScriptConditional(const QScriptValue& callable) : _callable(callable) { } + virtual bool satisfied() override; +protected: + Q_INVOKABLE void updateValue(); +private: + QScriptValue _callable; + bool _lastValue { false }; +}; + +} +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp new file mode 100644 index 0000000000..d07ef38185 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp @@ -0,0 +1,40 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ActionEndpoint.h" + +#include + +#include "../../UserInputMapper.h" + +using namespace controller; + +void ActionEndpoint::apply(float newValue, float oldValue, const Pointer& source) { + _currentValue += newValue; + if (_input != Input::INVALID_INPUT) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->deltaActionState(Action(_input.getChannel()), newValue); + } +} + +void ActionEndpoint::apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) { + _currentPose = newValue; + if (!_currentPose.isValid()) { + return; + } + if (_input != Input::INVALID_INPUT) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->setActionState(Action(_input.getChannel()), _currentPose); + } +} + +void ActionEndpoint::reset() { + _currentValue = 0.0f; + _currentPose = Pose(); +} + diff --git a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h new file mode 100644 index 0000000000..eaae1e3798 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h @@ -0,0 +1,41 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_ActionEndpoint_h +#define hifi_Controllers_ActionEndpoint_h + +#include "../Endpoint.h" + +#include "../../Actions.h" +#include + +#include "../../UserInputMapper.h" + +namespace controller { + +class ActionEndpoint : public Endpoint { +public: + ActionEndpoint(const Input& id = Input::INVALID_INPUT) : Endpoint(id) { } + + virtual float value() override { return _currentValue; } + virtual void apply(float newValue, float oldValue, const Pointer& source) override; + + virtual Pose pose() override { return _currentPose; } + virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override; + + virtual void reset() override; + +private: + float _currentValue{ 0.0f }; + Pose _currentPose{}; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp new file mode 100644 index 0000000000..b3310e4424 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp @@ -0,0 +1,63 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnyEndpoint.h" + +#include "../../UserInputMapper.h" + +using namespace controller; + +AnyEndpoint::AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPUT), _children(children) { + bool standard = true; + // Ensure if we're building a composite of standard devices the composite itself + // is treated as a standard device for rule processing order + for (auto endpoint : children) { + if (endpoint->getInput().device != UserInputMapper::STANDARD_DEVICE) { + standard = false; + break; + } + } + if (standard) { + this->_input.device = UserInputMapper::STANDARD_DEVICE; + } +} + +float AnyEndpoint::value() { + float result = 0; + for (auto& child : _children) { + float childResult = child->value(); + if (childResult != 0.0f) { + result = childResult; + } + } + return result; +} + +void AnyEndpoint::apply(float newValue, float oldValue, const Endpoint::Pointer& source) { + qFatal("AnyEndpoint is read only"); +} + +// AnyEndpoint is used for reading, so return false if any child returns false (has been written to) +bool AnyEndpoint::writeable() const { + for (auto& child : _children) { + if (!child->writeable()) { + return false; + } + } + return true; +} + +bool AnyEndpoint::readable() const { + for (auto& child : _children) { + if (!child->readable()) { + return false; + } + } + return true; +} + diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h new file mode 100644 index 0000000000..25db6a5a2a --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h @@ -0,0 +1,32 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_AnyEndpoint_h +#define hifi_Controllers_AnyEndpoint_h + +#include "../Endpoint.h" + +namespace controller { + +class AnyEndpoint : public Endpoint { + friend class UserInputMapper; +public: + AnyEndpoint(Endpoint::List children); + virtual float value() override; + virtual void apply(float newValue, float oldValue, const Endpoint::Pointer& source) override; + virtual bool writeable() const override; + virtual bool readable() const override; + +private: + Endpoint::List _children; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp new file mode 100644 index 0000000000..c083a7147d --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.cpp @@ -0,0 +1,9 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ArrayEndpoint.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h new file mode 100644 index 0000000000..676f43868a --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h @@ -0,0 +1,43 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_ArrayEndpoint_h +#define hifi_Controllers_ArrayEndpoint_h + +#include "../Endpoint.h" + +namespace controller { + +class ArrayEndpoint : public Endpoint { + friend class UserInputMapper; +public: + using Pointer = std::shared_ptr; + ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { } + + virtual float value() override { + return 0.0; + } + + virtual void apply(float newValue, float oldValue, const Endpoint::Pointer& source) override { + for (auto& child : _children) { + if (child->writeable()) { + child->apply(newValue, oldValue, source); + } + } + } + + virtual bool readable() const override { return false; } + +private: + Endpoint::List _children; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp new file mode 100644 index 0000000000..9d89a7d2b3 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp @@ -0,0 +1,32 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "CompositeEndpoint.h" + +#include "../../UserInputMapper.h" + +namespace controller { + +CompositeEndpoint::CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second) + : Endpoint(Input::INVALID_INPUT), Pair(first, second) { + if (first->getInput().device == UserInputMapper::STANDARD_DEVICE && + second->getInput().device == UserInputMapper::STANDARD_DEVICE) { + this->_input.device = UserInputMapper::STANDARD_DEVICE; + } +} + +float CompositeEndpoint::value() { + float result = first->value() * -1.0f + second->value(); + return result; +} + +void CompositeEndpoint::apply(float newValue, float oldValue, const Pointer& source) { + // Composites are read only +} + +} diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h new file mode 100644 index 0000000000..b525a2e4ab --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h @@ -0,0 +1,26 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_CompositeEndpoint_h +#define hifi_Controllers_CompositeEndpoint_h + +#include "../Endpoint.h" + +namespace controller { + class CompositeEndpoint : public Endpoint, Endpoint::Pair { + public: + CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second); + + virtual float value() override; + virtual void apply(float newValue, float oldValue, const Pointer& source) override; + }; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp new file mode 100644 index 0000000000..32cd5b65e0 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp @@ -0,0 +1,41 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "InputEndpoint.h" + +#include + +#include "../../UserInputMapper.h" + +using namespace controller; +float InputEndpoint::value(){ + _read = true; + if (isPose()) { + return pose().valid ? 1.0f : 0.0f; + } + auto userInputMapper = DependencyManager::get(); + auto deviceProxy = userInputMapper->getDeviceProxy(_input); + if (!deviceProxy) { + return 0.0f; + } + return deviceProxy->getValue(_input, 0); +} + +Pose InputEndpoint::pose() { + _read = true; + if (!isPose()) { + return Pose(); + } + auto userInputMapper = DependencyManager::get(); + auto deviceProxy = userInputMapper->getDeviceProxy(_input); + if (!deviceProxy) { + return Pose(); + } + return deviceProxy->getPose(_input, 0); +} + diff --git a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h new file mode 100644 index 0000000000..195cd33683 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h @@ -0,0 +1,39 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_InputEndpoint_h +#define hifi_Controllers_InputEndpoint_h + +#include "../Endpoint.h" + +namespace controller { + +class InputEndpoint : public Endpoint { +public: + InputEndpoint(const Input& id = Input::INVALID_INPUT) + : Endpoint(id) { + } + + virtual float value() override; + // FIXME need support for writing back to vibration / force feedback effects + virtual void apply(float newValue, float oldValue, const Pointer& source) override {} + virtual Pose pose() override; + virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override { } + + virtual bool writeable() const { return false; } + virtual bool readable() const { return !_read; } + virtual void reset() { _read = false; } + +private: + bool _read { false }; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp new file mode 100644 index 0000000000..4560741d12 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp @@ -0,0 +1,9 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "JSEndpoint.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h new file mode 100644 index 0000000000..38ac92bfb6 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h @@ -0,0 +1,41 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_JSEndpoint_h +#define hifi_Controllers_JSEndpoint_h + +#include "../Endpoint.h" + +#include +#include + +namespace controller { + +class JSEndpoint : public Endpoint { +public: + JSEndpoint(const QJSValue& callable) + : Endpoint(Input::INVALID_INPUT), _callable(callable) { + } + + virtual float value() { + float result = (float)_callable.call().toNumber(); + return result; + } + + virtual void apply(float newValue, float oldValue, const Pointer& source) { + _callable.call(QJSValueList({ QJSValue(newValue) })); + } + +private: + QJSValue _callable; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp new file mode 100644 index 0000000000..3dedcef4e4 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp @@ -0,0 +1,43 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ScriptEndpoint.h" + +#include + +using namespace controller; + +float ScriptEndpoint::value() { + updateValue(); + return _lastValue; +} + +void ScriptEndpoint::updateValue() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "updateValue", Qt::QueuedConnection); + return; + } + + _lastValue = (float)_callable.call().toNumber(); +} + +void ScriptEndpoint::apply(float newValue, float oldValue, const Pointer& source) { + internalApply(newValue, oldValue, source->getInput().getID()); +} + +void ScriptEndpoint::internalApply(float newValue, float oldValue, int sourceID) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "internalApply", Qt::QueuedConnection, + Q_ARG(float, newValue), + Q_ARG(float, oldValue), + Q_ARG(int, sourceID)); + return; + } + _callable.call(QScriptValue(), + QScriptValueList({ QScriptValue(newValue), QScriptValue(oldValue), QScriptValue(sourceID) })); +} diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h new file mode 100644 index 0000000000..e3c7abe812 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h @@ -0,0 +1,39 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_ScriptEndpoint_h +#define hifi_Controllers_ScriptEndpoint_h + +#include + +#include "../Endpoint.h" + +namespace controller { + +class ScriptEndpoint : public Endpoint { + Q_OBJECT; +public: + ScriptEndpoint(const QScriptValue& callable) + : Endpoint(Input::INVALID_INPUT), _callable(callable) { + } + + virtual float value(); + virtual void apply(float newValue, float oldValue, const Pointer& source); + +protected: + Q_INVOKABLE void updateValue(); + Q_INVOKABLE virtual void internalApply(float newValue, float oldValue, int sourceID); +private: + QScriptValue _callable; + float _lastValue = 0.0f; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp new file mode 100644 index 0000000000..09920d249c --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.cpp @@ -0,0 +1,9 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "StandardEndpoint.h" \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h new file mode 100644 index 0000000000..44803a22fd --- /dev/null +++ b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h @@ -0,0 +1,60 @@ +// +// Created by Bradley Austin Davis 2015/10/23 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_Controllers_StandardEndpoint_h +#define hifi_Controllers_StandardEndpoint_h + +#include "../Endpoint.h" + +namespace controller { + +class StandardEndpoint : public VirtualEndpoint { +public: + StandardEndpoint(const Input& input) : VirtualEndpoint(input) {} + virtual bool writeable() const override { return !_written; } + virtual bool readable() const override { return !_read; } + virtual void reset() override { + apply(0.0f, 0.0f, Endpoint::Pointer()); + apply(Pose(), Pose(), Endpoint::Pointer()); + _written = _read = false; + } + + virtual float value() override { + _read = true; + return VirtualEndpoint::value(); + } + + virtual void apply(float newValue, float oldValue, const Pointer& source) override { + // For standard endpoints, the first NON-ZERO write counts. + if (newValue != 0.0) { + _written = true; + } + VirtualEndpoint::apply(newValue, oldValue, source); + } + + virtual Pose pose() override { + _read = true; + return VirtualEndpoint::pose(); + } + + virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override { + if (newValue != Pose()) { + _written = true; + } + VirtualEndpoint::apply(newValue, oldValue, source); + } + +private: + bool _written { false }; + bool _read { false }; +}; + +} + +#endif