From dc32d5ae8d7c491e63b568c4f47cb07d12a655b2 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 12 Oct 2015 18:03:21 -0700 Subject: [PATCH 1/8] Current status of my code for json --- .../controllers/src/controllers/Mapping.cpp | 10 +++- .../controllers/src/controllers/Mapping.h | 4 +- .../NewControllerScriptingInterface.cpp | 4 ++ .../NewControllerScriptingInterface.h | 2 + .../controllers/impl/MappingBuilderProxy.cpp | 50 ++++++++++++++++++- .../controllers/impl/MappingBuilderProxy.h | 12 +++++ .../src/controllers/impl/RouteBuilderProxy.h | 4 ++ .../src/input-plugins/UserInputMapper.cpp | 24 ++++++++- .../src/input-plugins/UserInputMapper.h | 5 +- tests/controllers/src/main.cpp | 4 +- 10 files changed, 111 insertions(+), 8 deletions(-) diff --git a/libraries/controllers/src/controllers/Mapping.cpp b/libraries/controllers/src/controllers/Mapping.cpp index 0063a1d24a..b6214a43fc 100644 --- a/libraries/controllers/src/controllers/Mapping.cpp +++ b/libraries/controllers/src/controllers/Mapping.cpp @@ -1,5 +1,11 @@ +// +// Created by Bradley Austin Davis 2015/10/09 +// 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 "Mapping.h" -namespace controller { -} + diff --git a/libraries/controllers/src/controllers/Mapping.h b/libraries/controllers/src/controllers/Mapping.h index 5b54a1745b..39fe6ba788 100644 --- a/libraries/controllers/src/controllers/Mapping.h +++ b/libraries/controllers/src/controllers/Mapping.h @@ -28,9 +28,9 @@ namespace controller { using Pointer = std::shared_ptr; Map _channelMappings; + QString _name; - void parse(const QString& json); - QString serialize(); + protected: }; } diff --git a/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp b/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp index f5d6276b91..c4d1bb65c4 100644 --- a/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp @@ -301,6 +301,10 @@ namespace controller { return Endpoint::Pointer(); } + UserInputMapper::Input NewControllerScriptingInterface::inputFor(const QString& inputName) { + return DependencyManager::get()->findDeviceInput(inputName); + } + Endpoint::Pointer NewControllerScriptingInterface::endpointFor(const UserInputMapper::Input& inputId) { auto iterator = _endpoints.find(inputId); if (_endpoints.end() == iterator) { diff --git a/libraries/controllers/src/controllers/NewControllerScriptingInterface.h b/libraries/controllers/src/controllers/NewControllerScriptingInterface.h index 6bf0bda40d..39791eacb2 100644 --- a/libraries/controllers/src/controllers/NewControllerScriptingInterface.h +++ b/libraries/controllers/src/controllers/NewControllerScriptingInterface.h @@ -68,6 +68,8 @@ namespace controller { Endpoint::Pointer endpointFor(const UserInputMapper::Input& endpoint); Endpoint::Pointer compositeEndpointFor(Endpoint::Pointer first, Endpoint::Pointer second); + UserInputMapper::Input inputFor(const QString& inputName); + friend class MappingBuilderProxy; friend class RouteBuilderProxy; private: diff --git a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp index 4e2c6a4d8c..71a8a417fd 100644 --- a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp @@ -11,11 +11,14 @@ #include #include +#include +#include + #include "RouteBuilderProxy.h" #include "../NewControllerScriptingInterface.h" #include "../Logging.h" -namespace controller { +using namespace controller; QObject* MappingBuilderProxy::from(const QJSValue& source) { qCDebug(controllers) << "Creating new Route builder proxy from " << source.toString(); @@ -41,4 +44,49 @@ QObject* MappingBuilderProxy::join(const QJSValue& source1, const QJSValue& sour return from(_parent.compositeEndpointFor(source1Endpoint, source2Endpoint)); } + +const QString JSON_NAME = QStringLiteral("name"); +const QString JSON_CHANNELS = QStringLiteral("channels"); +const QString JSON_CHANNEL_FROM = QStringLiteral("from"); +const QString JSON_CHANNEL_TO = QStringLiteral("to"); +const QString JSON_CHANNEL_FILTERS = QStringLiteral("filters"); + + +void MappingBuilderProxy::parse(const QJsonObject& json) { + _mapping->_name = json[JSON_NAME].toString(); + + _mapping->_channelMappings.clear(); + const auto& jsonChannels = json[JSON_CHANNELS].toArray(); + for (const auto& channelIt : jsonChannels) { + parseRoute(channelIt); + } +} + +void MappingBuilderProxy::parseRoute(const QJsonValue& json) { + if (json.isObject()) { + const auto& jsonChannel = json.toObject(); + + auto newRoute = from(jsonChannel[JSON_CHANNEL_FROM]); + if (newRoute) { + auto route = dynamic_cast(newRoute); + route->filters(jsonChannel[JSON_CHANNEL_FILTERS]); + route->to(jsonChannel[JSON_CHANNEL_TO]); + + return + } + } +} + +QObject* MappingBuilderProxy::from(const QJsonValue& json) { + if (json.isString()) { + return from(_parent.endpointFor(_parent.inputFor(json.toString()))); + } else if (json.isObject()) { + // Endpoint is defined as an object, we expect a js function then + return nullptr; + } +} + + +Filter::List MappingBuilderProxy::parseFilters(const QJsonValue& json) const { + return Filter::List(); } diff --git a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h index b5e02bbfdf..d0101b95a7 100644 --- a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h @@ -32,12 +32,24 @@ public: Q_INVOKABLE QObject* from(const QScriptValue& source); Q_INVOKABLE QObject* join(const QJSValue& source1, const QJSValue& source2); + + // JSON route creation point + Q_INVOKABLE QObject* from(const QJsonValue& json); + + + void parse(const QJsonObject& json); + // void serialize(QJsonObject& json); + protected: QObject* from(const Endpoint::Pointer& source); friend class RouteBuilderProxy; NewControllerScriptingInterface& _parent; Mapping::Pointer _mapping; + + + void parseRoute(const QJsonValue& json); + }; } diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h index 63cd106edb..a62a465700 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h @@ -40,6 +40,10 @@ class RouteBuilderProxy : public QObject { Q_INVOKABLE QObject* constrainToInteger(); Q_INVOKABLE QObject* constrainToPositiveInteger(); + // JSON route creation point + Q_INVOKABLE QObject* filters(const QJsonValue& json); + Q_INVOKABLE void to(const QJsonValue& json); + private: void to(const Endpoint::Pointer& destination); void addFilter(Filter::Lambda lambda); diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp index c29acc09af..325dc5dfe7 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp @@ -64,7 +64,7 @@ void UserInputMapper::resetDevice(uint16 deviceID) { } } -int UserInputMapper::findDevice(QString name) { +int UserInputMapper::findDevice(QString name) const { for (auto device : _registeredDevices) { if (device.second->_name.split(" (")[0] == name) { return device.first; @@ -82,6 +82,28 @@ QVector UserInputMapper::getDeviceNames() { return result; } +UserInputMapper::Input UserInputMapper::findDeviceInput(const QString& inputName) const { + + // Split the full input name as such: deviceName.inputName + auto names = inputName.split('.'); + + if (names.size() >= 2) { + // Get the device name: + auto deviceName = names[0]; + auto inputName = names[1]; + + int deviceID = findDevice(deviceName); + if (deviceID != Input::INVALID_DEVICE) { + // getAllInputsForDevice(deviceID); + } + + + } + + return Input(); +} + + bool UserInputMapper::addInputChannel(Action action, const Input& input, float scale) { return addInputChannel(action, input, Input(), scale); diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.h b/libraries/input-plugins/src/input-plugins/UserInputMapper.h index 304e74e8cc..b7b105df5e 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.h +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.h @@ -140,9 +140,12 @@ public: QVector getAvailableInputs(uint16 deviceID) { return _registeredDevices[deviceID]->getAvailabeInputs(); } void resetAllDeviceBindings(); void resetDevice(uint16 deviceID); - int findDevice(QString name); + int findDevice(QString name) const; QVector getDeviceNames(); + Input findDeviceInput(const QString& inputName) const; + + // Actions are the output channels of the Mapper, that's what the InputChannel map to // For now the Actions are hardcoded, this is bad, but we will fix that in the near future enum Action { diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index d694bcae1d..b42359e48a 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -83,7 +83,9 @@ int main(int argc, char** argv) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; - + for (auto path : qApp->libraryPaths()) { + qDebug() << path; + } { DependencyManager::set(); foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) { From cb62527bf93a1b32dcce94095a38583f163b4412 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 14 Oct 2015 09:22:30 -0700 Subject: [PATCH 2/8] Refactoring the filter for supporting the factory --- .../controllers/src/controllers/Filter.cpp | 63 ++++++++- .../controllers/src/controllers/Filter.h | 132 ++++++++++++++++-- .../controllers/impl/MappingBuilderProxy.cpp | 9 +- .../controllers/impl/MappingBuilderProxy.h | 1 + .../controllers/impl/RouteBuilderProxy.cpp | 64 +++++---- .../src/controllers/impl/RouteBuilderProxy.h | 1 + 6 files changed, 218 insertions(+), 52 deletions(-) diff --git a/libraries/controllers/src/controllers/Filter.cpp b/libraries/controllers/src/controllers/Filter.cpp index 17715eceff..b7175f1716 100644 --- a/libraries/controllers/src/controllers/Filter.cpp +++ b/libraries/controllers/src/controllers/Filter.cpp @@ -11,11 +11,66 @@ #include #include -namespace controller { +#include +#include - Filter::Pointer Filter::parse(const QJsonObject& json) { - // FIXME parse the json object and determine the instance type to create - return Filter::Pointer(); +#include "SharedUtil.h" + +using namespace controller; + + +const QString JSON_FILTER_TYPE = QStringLiteral("type"); +const QString JSON_FILTER_PARAMS = QStringLiteral("params"); + +Filter::Factory Filter::_factory; + +Filter::Pointer Filter::parse(const QJsonObject& json) { + // The filter is an object, now let s check for type and potential arguments + Filter::Pointer filter; + auto filterType = json[JSON_FILTER_TYPE]; + if (filterType.isString()) { + filter.reset(Filter::getFactory().create(filterType.toString().toStdString())); + if (filter) { + // Filter is defined, need to read the parameters and validate + auto parameters = json[JSON_FILTER_PARAMS]; + if (parameters.isArray()) { + if (filter->parseParameters(parameters.toArray())) { + } + } + + return filter; + } } + return Filter::Pointer(); } +Filter::Factory::ClassEntry ScaleFilter::_factoryEntry; + +bool ScaleFilter::parseParameters(const QJsonArray& parameters) { + if (parameters.size() > 1) { + _scale = parameters[0].toDouble(); + } + return true; +} + +Filter::Factory::ClassEntry PulseFilter::_factoryEntry; + + +float PulseFilter::apply(float value) const { + float result = 0.0; + + if (0.0 != value) { + float now = secTimestampNow(); + float delta = now - _lastEmitTime; + if (delta >= _interval) { + _lastEmitTime = now; + result = value; + } + } + + return result; +} + +bool PulseFilter::parseParameters(const QJsonArray& parameters) { + return false; +} diff --git a/libraries/controllers/src/controllers/Filter.h b/libraries/controllers/src/controllers/Filter.h index f3978e2c0a..425bba7512 100644 --- a/libraries/controllers/src/controllers/Filter.h +++ b/libraries/controllers/src/controllers/Filter.h @@ -14,13 +14,49 @@ #include #include #include +#include #include class QJsonObject; +class QJsonArray; + namespace controller { + /* + template class Factory { + public: + template class Entry { + public: + virtual T* create() = 0; + }; + + template class DefaultEntry{ + public: + T* create() { return new S(); } + }; + + using EntryMap = std::map>>; + + void registerEntry(const std::string& name, std::unique_ptr>& entry) { + if (entry) { + _entries[name] = entry; + } + } + + T* create(const std::string& name) const { + auto& entryIt = _entries.find(name); + if (entryIt != _entries.end()) { + return (*entryIt).second->create(); + } + return nullptr; + } + + protected: + EntryMap _entries; + }; + */ // Encapsulates part of a filter chain class Filter { public: @@ -30,18 +66,71 @@ namespace controller { using List = std::list; using Lambda = std::function; - static Filter::Pointer parse(const QJsonObject& json); - }; + // Factory features + virtual bool parseParameters(const QJsonArray& parameters) = 0; + class Factory { + public: + + class Entry { + public: + virtual Filter* create() = 0; + + Entry() = default; + virtual ~Entry() = default; + }; + + template class ClassEntry { + public: + virtual Filter* create() { return (Filter*) new T(); } + + ClassEntry() = default; + virtual ~ClassEntry() = default; + }; + + using EntryMap = std::map>; + + void registerEntry(const std::string& name, const std::shared_ptr& entry) { + if (entry) { + _entries.insert(EntryMap::value_type(name, entry)); + } + } + + Filter* create(const std::string& name) const { + auto& entryIt = _entries.find(name); + if (entryIt != _entries.end()) { + return (*entryIt).second->create(); + } + return nullptr; + } + + protected: + EntryMap _entries; + }; + + static Filter::Pointer parse(const QJsonObject& json); + static Factory& getFactory() { return _factory; } + protected: + static Factory _factory; + }; +} + +#define REGISTER_FILTER_CLASS(classEntry) static Filter::Factory::ClassEntry _factoryEntry; + +namespace controller { class LambdaFilter : public Filter { public: + // LambdaFilter() {} LambdaFilter(Lambda f) : _function(f) {}; virtual float apply(float value) const { return _function(value); } + virtual bool parseParameters(const QJsonArray& parameters) { return true; } + +// REGISTER_FILTER_CLASS(LambdaFilter); private: Lambda _function; }; @@ -50,17 +139,21 @@ namespace controller { public: }; + + class ScaleFilter : public Filter { + public: + ScaleFilter() {} + ScaleFilter(float scale): _scale(scale) {} - //class ScaleFilter : public Filter { - //public: - // ScaleFilter(float scale); - // virtual float apply(float scale) const override { - // return value * _scale; - // } + virtual float apply(float value) const override { + return value * _scale; + } + virtual bool parseParameters(const QJsonArray& parameters); - //private: - // const float _scale; - //}; + REGISTER_FILTER_CLASS(ScaleFilter); + private: + float _scale = 1.0f; + }; //class AbstractRangeFilter : public Filter { //public: @@ -84,6 +177,23 @@ namespace controller { // const float _interval; //}; + + class PulseFilter : public Filter { + public: + REGISTER_FILTER_CLASS(PulseFilter); + PulseFilter() {} + PulseFilter(float interval) : _interval(interval) {} + + + virtual float apply(float value) const override; + + virtual bool parseParameters(const QJsonArray& parameters); + + private: + mutable float _lastEmitTime{ -std::numeric_limits::max() }; + float _interval = 1.0f; + }; + ////class DeadzoneFilter : public AbstractRangeFilter { ////public: //// DeadzoneFilter(float min, float max = 1.0f); diff --git a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp index 71a8a417fd..9080555cac 100644 --- a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp @@ -11,8 +11,8 @@ #include #include -#include -#include +#include +#include #include "RouteBuilderProxy.h" #include "../NewControllerScriptingInterface.h" @@ -71,8 +71,6 @@ void MappingBuilderProxy::parseRoute(const QJsonValue& json) { auto route = dynamic_cast(newRoute); route->filters(jsonChannel[JSON_CHANNEL_FILTERS]); route->to(jsonChannel[JSON_CHANNEL_TO]); - - return } } } @@ -87,6 +85,3 @@ QObject* MappingBuilderProxy::from(const QJsonValue& json) { } -Filter::List MappingBuilderProxy::parseFilters(const QJsonValue& json) const { - return Filter::List(); -} diff --git a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h index d0101b95a7..799fc99399 100644 --- a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.h @@ -17,6 +17,7 @@ class QJSValue; class QScriptValue; +class QJsonValue; namespace controller { diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp index e6b67e9ca6..d606b52608 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp @@ -9,6 +9,9 @@ #include +#include +#include + #include #include "MappingBuilderProxy.h" @@ -61,9 +64,7 @@ QObject* RouteBuilderProxy::clamp(float min, float max) { } QObject* RouteBuilderProxy::scale(float multiplier) { - addFilter([=](float value) { - return value * multiplier; - }); + addFilter(Filter::Pointer(new ScaleFilter(multiplier))); return this; } @@ -99,39 +100,12 @@ QObject* RouteBuilderProxy::constrainToPositiveInteger() { } -class PulseFilter : public Filter { -public: - PulseFilter(float interval) : _interval(interval) {} - - virtual float apply(float value) const override { - float result = 0.0; - - if (0.0 != value) { - float now = secTimestampNow(); - float delta = now - _lastEmitTime; - if (delta >= _interval) { - _lastEmitTime = now; - result = value; - } - } - - return result; - } - -private: - mutable float _lastEmitTime{ -std::numeric_limits::max() }; - const float _interval; -}; - - QObject* RouteBuilderProxy::pulse(float interval) { Filter::Pointer filter = std::make_shared(interval); addFilter(filter); return this; } - - void RouteBuilderProxy::addFilter(Filter::Lambda lambda) { Filter::Pointer filterPointer = std::make_shared < LambdaFilter > (lambda); addFilter(filterPointer); @@ -141,4 +115,34 @@ void RouteBuilderProxy::addFilter(Filter::Pointer filter) { _route->_filters.push_back(filter); } + +QObject* RouteBuilderProxy::filters(const QJsonValue& json) { + // We expect an array of objects to define the filters + if (json.isArray()) { + const auto& jsonFilters = json.toArray(); + for (auto jsonFilter : jsonFilters) { + if (jsonFilter.isObject()) { + // The filter is an object, now let s check for type and potential arguments + Filter::Pointer filter = Filter::parse(jsonFilter.toObject()); + if (filter) { + addFilter(filter); + } + } + } + } + + return this; +} + +void RouteBuilderProxy::to(const QJsonValue& json) { + if (json.isString()) { + + return to(_parent.endpointFor(_parent.inputFor(json.toString()))); + } else if (json.isObject()) { + // Endpoint is defined as an object, we expect a js function then + return to(nullptr); + } + +} + } diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h index a62a465700..573e841e85 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h @@ -16,6 +16,7 @@ class QJSValue; class QScriptValue; +class QJsonValue; namespace controller { From 1302b6a2388d466064363067ec428166a1488670 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 14 Oct 2015 10:47:49 -0700 Subject: [PATCH 3/8] Improving the Factory registration --- .../controllers/src/controllers/Filter.h | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libraries/controllers/src/controllers/Filter.h b/libraries/controllers/src/controllers/Filter.h index 425bba7512..4d21966731 100644 --- a/libraries/controllers/src/controllers/Filter.h +++ b/libraries/controllers/src/controllers/Filter.h @@ -75,24 +75,30 @@ namespace controller { class Entry { public: virtual Filter* create() = 0; - + virtual const std::string& getName() const = 0; + Entry() = default; virtual ~Entry() = default; }; - template class ClassEntry { + template class ClassEntry { public: - virtual Filter* create() { return (Filter*) new T(); } + Filter* create() override { return (Filter*) new T(); } + const std::string& getName() const override { + return _name + }; - ClassEntry() = default; + ClassEntry() : _name(name) {}; virtual ~ClassEntry() = default; + + const std::string _name; }; using EntryMap = std::map>; - void registerEntry(const std::string& name, const std::shared_ptr& entry) { + void registerEntry(const std::shared_ptr& entry) { if (entry) { - _entries.insert(EntryMap::value_type(name, entry)); + _entries.insert(EntryMap::value_type(entry->getName(), entry)); } } @@ -115,7 +121,9 @@ namespace controller { }; } -#define REGISTER_FILTER_CLASS(classEntry) static Filter::Factory::ClassEntry _factoryEntry; +#define REGISTER_FILTER_CLASS(classEntry, className) \ + using FactoryEntry = Filter::Factory::ClassEntry;\ + static FactoryEntry _factoryEntry; namespace controller { @@ -150,7 +158,8 @@ namespace controller { } virtual bool parseParameters(const QJsonArray& parameters); - REGISTER_FILTER_CLASS(ScaleFilter); + // static Filter::Factory::ClassEntry _factoryEntry; + REGISTER_FILTER_CLASS(ScaleFilter, "scale"); private: float _scale = 1.0f; }; From 12e103c90c03c707c9c13601166e06ee99d17fb2 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 14 Oct 2015 17:41:39 -0700 Subject: [PATCH 4/8] Get json creating the mappings from js --- examples/controllers/controllerMappings.js | 71 ++++++++ .../controllers/src/controllers/Filter.cpp | 46 ++++- .../controllers/src/controllers/Filter.h | 157 +++++++++--------- .../NewControllerScriptingInterface.cpp | 35 +++- .../NewControllerScriptingInterface.h | 1 + .../controllers/impl/RouteBuilderProxy.cpp | 28 +--- .../src/input-plugins/UserInputMapper.cpp | 46 ++++- .../src/input-plugins/UserInputMapper.h | 5 +- 8 files changed, 275 insertions(+), 114 deletions(-) create mode 100644 examples/controllers/controllerMappings.js diff --git a/examples/controllers/controllerMappings.js b/examples/controllers/controllerMappings.js new file mode 100644 index 0000000000..45383886c2 --- /dev/null +++ b/examples/controllers/controllerMappings.js @@ -0,0 +1,71 @@ + +// +// controllerScriptingExamples.js +// examples +// +// Created by Sam Gondelman on 6/2/15 +// 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 +// + +// Assumes you only have the default keyboard connected + +myFirstMapping = function() { +return { + "name": "example mapping from Standard to actions", + "channels": [ { + "from": "Keyboard.A", + "filters": [ { + "type": "clamp", + "params": [0, 1], + } + ], + "to": "Actions.LONGITUDINAL_FORWARD", + }, { + "from": "Keyboard.Left", + "filters": [ { + "type": "clamp", + "params": [0, 1], + }, { + "type": "invert" + } + ], + "to": "Actions.LONGITUDINAL_BACKWARD", + }, { + "from": "Keyboard.C", + "filters": [ { + "type": "scale", + "params": [2.0], + } + ], + "to": "Actions.Yaw", + }, { + "from": "Keyboard.B", + "to": "Actions.Yaw" + } + ] +} +} + + +//Script.include('mapping-test0.json'); +var myFirstMappingJSON = myFirstMapping(); +print('myFirstMappingJSON' + JSON.stringify(myFirstMappingJSON)); + +var mapping = NewControllers.parseMapping(JSON.stringify(myFirstMappingJSON)); + +Object.keys(Controller.Standard).forEach(function (input) { + print("Controller.Standard." + input + ":" + Controller.Standard[input]); +}); + +Object.keys(Controller.Hardware).forEach(function (deviceName) { + Object.keys(Controller.Hardware[deviceName]).forEach(function (input) { + print("Controller.Hardware." + deviceName + "." + input + ":" + Controller.Hardware[deviceName][input]); + }); +}); + +Object.keys(Controller.Actions).forEach(function (actionName) { + print("Controller.Actions." + actionName + ":" + Controller.Actions[actionName]); +}); diff --git a/libraries/controllers/src/controllers/Filter.cpp b/libraries/controllers/src/controllers/Filter.cpp index b7175f1716..3e1079b984 100644 --- a/libraries/controllers/src/controllers/Filter.cpp +++ b/libraries/controllers/src/controllers/Filter.cpp @@ -44,7 +44,7 @@ Filter::Pointer Filter::parse(const QJsonObject& json) { return Filter::Pointer(); } -Filter::Factory::ClassEntry ScaleFilter::_factoryEntry; +ScaleFilter::FactoryEntryBuilder ScaleFilter::_factoryEntryBuilder; bool ScaleFilter::parseParameters(const QJsonArray& parameters) { if (parameters.size() > 1) { @@ -53,7 +53,39 @@ bool ScaleFilter::parseParameters(const QJsonArray& parameters) { return true; } -Filter::Factory::ClassEntry PulseFilter::_factoryEntry; +InvertFilter::FactoryEntryBuilder InvertFilter::_factoryEntryBuilder; + + +ClampFilter::FactoryEntryBuilder ClampFilter::_factoryEntryBuilder; + +bool ClampFilter::parseParameters(const QJsonArray& parameters) { + if (parameters.size() > 1) { + _min = parameters[0].toDouble(); + } + if (parameters.size() > 2) { + _max = parameters[1].toDouble(); + } + return true; +} + +DeadZoneFilter::FactoryEntryBuilder DeadZoneFilter::_factoryEntryBuilder; + +float DeadZoneFilter::apply(float value) const { + float scale = 1.0f / (1.0f - _min); + if (abs(value) < _min) { + return 0.0f; + } + return (value - _min) * scale; +} + +bool DeadZoneFilter::parseParameters(const QJsonArray& parameters) { + if (parameters.size() > 1) { + _min = parameters[0].toDouble(); + } + return true; +} + +PulseFilter::FactoryEntryBuilder PulseFilter::_factoryEntryBuilder; float PulseFilter::apply(float value) const { @@ -72,5 +104,13 @@ float PulseFilter::apply(float value) const { } bool PulseFilter::parseParameters(const QJsonArray& parameters) { - return false; + if (parameters.size() > 1) { + _interval = parameters[0].toDouble(); + } + return true; } + +ConstrainToIntegerFilter::FactoryEntryBuilder ConstrainToIntegerFilter::_factoryEntryBuilder; + +ConstrainToPositiveIntegerFilter::FactoryEntryBuilder ConstrainToPositiveIntegerFilter::_factoryEntryBuilder; + diff --git a/libraries/controllers/src/controllers/Filter.h b/libraries/controllers/src/controllers/Filter.h index 4d21966731..4d8c483b08 100644 --- a/libraries/controllers/src/controllers/Filter.h +++ b/libraries/controllers/src/controllers/Filter.h @@ -16,6 +16,8 @@ #include #include +#include + #include class QJsonObject; @@ -23,40 +25,7 @@ class QJsonArray; namespace controller { - /* - template class Factory { - public: - template class Entry { - public: - virtual T* create() = 0; - }; - - template class DefaultEntry{ - public: - T* create() { return new S(); } - }; - - using EntryMap = std::map>>; - - void registerEntry(const std::string& name, std::unique_ptr>& entry) { - if (entry) { - _entries[name] = entry; - } - } - - T* create(const std::string& name) const { - auto& entryIt = _entries.find(name); - if (entryIt != _entries.end()) { - return (*entryIt).second->create(); - } - return nullptr; - } - - protected: - EntryMap _entries; - }; - */ // Encapsulates part of a filter chain class Filter { public: @@ -67,36 +36,40 @@ namespace controller { using Lambda = std::function; // Factory features - virtual bool parseParameters(const QJsonArray& parameters) = 0; + virtual bool parseParameters(const QJsonArray& parameters) { return true; } class Factory { public: class Entry { public: - virtual Filter* create() = 0; - virtual const std::string& getName() const = 0; + virtual Filter* create() const = 0; + virtual const char* getName() const = 0; - Entry() = default; - virtual ~Entry() = default; + Entry() {}; + virtual ~Entry() {}; }; - template class ClassEntry { + template class ClassEntry : public Entry { public: - Filter* create() override { return (Filter*) new T(); } - const std::string& getName() const override { - return _name - }; + virtual Filter* create() const { return (Filter*) new T(); } + virtual const char* getName() const { return T::getName(); }; - ClassEntry() : _name(name) {}; + ClassEntry() {}; virtual ~ClassEntry() = default; - const std::string _name; + class Builder { + public: + Builder() { + std::shared_ptr classEntry(new ClassEntry()); + Filter::getFactory().registerEntry(classEntry); + } + }; }; using EntryMap = std::map>; - void registerEntry(const std::shared_ptr& entry) { + void registerEntry(std::shared_ptr& entry) { if (entry) { _entries.insert(EntryMap::value_type(entry->getName(), entry)); } @@ -122,8 +95,9 @@ namespace controller { } #define REGISTER_FILTER_CLASS(classEntry, className) \ - using FactoryEntry = Filter::Factory::ClassEntry;\ - static FactoryEntry _factoryEntry; + static const char* getName() { return className; } \ + using FactoryEntryBuilder = Filter::Factory::ClassEntry::Builder;\ + static FactoryEntryBuilder _factoryEntryBuilder; namespace controller { @@ -150,6 +124,7 @@ namespace controller { class ScaleFilter : public Filter { public: + REGISTER_FILTER_CLASS(ScaleFilter, "scale"); ScaleFilter() {} ScaleFilter(float scale): _scale(scale) {} @@ -158,38 +133,48 @@ namespace controller { } virtual bool parseParameters(const QJsonArray& parameters); - // static Filter::Factory::ClassEntry _factoryEntry; - REGISTER_FILTER_CLASS(ScaleFilter, "scale"); private: float _scale = 1.0f; }; - //class AbstractRangeFilter : public Filter { - //public: - // RangeFilter(float min, float max) : _min(min), _max(max) {} + class InvertFilter : public ScaleFilter { + public: + REGISTER_FILTER_CLASS(InvertFilter, "invert"); + InvertFilter() : ScaleFilter(-1.0f) {} + + virtual bool parseParameters(const QJsonArray& parameters) { return true; } - //protected: - // const float _min; - // const float _max; - //}; + private: + }; - ///* - //* Constrains will emit the input value on the first call, and every *interval* seconds, otherwise returns 0 - //*/ - //class PulseFilter : public Filter { - //public: - // PulseFilter(float interval); - // virtual float apply(float value) const override; + class ClampFilter : public Filter { + public: + REGISTER_FILTER_CLASS(ClampFilter, "clamp"); + ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {}; - //private: - // float _lastEmitTime{ -std::numeric_limits::max() }; - // const float _interval; - //}; + virtual float apply(float value) const override { + return glm::clamp(value, _min, _max); + } + virtual bool parseParameters(const QJsonArray& parameters) override; + protected: + float _min = 0.0f; + float _max = 1.0f; + }; + class DeadZoneFilter : public Filter { + public: + REGISTER_FILTER_CLASS(DeadZoneFilter, "deadZone"); + DeadZoneFilter(float min = 0.0) : _min(min) {}; + + virtual float apply(float value) const override; + virtual bool parseParameters(const QJsonArray& parameters) override; + protected: + float _min = 0.0f; + }; class PulseFilter : public Filter { public: - REGISTER_FILTER_CLASS(PulseFilter); + REGISTER_FILTER_CLASS(PulseFilter, "pulse"); PulseFilter() {} PulseFilter(float interval) : _interval(interval) {} @@ -199,15 +184,31 @@ namespace controller { virtual bool parseParameters(const QJsonArray& parameters); private: - mutable float _lastEmitTime{ -std::numeric_limits::max() }; + mutable float _lastEmitTime{ -::std::numeric_limits::max() }; float _interval = 1.0f; }; - ////class DeadzoneFilter : public AbstractRangeFilter { - ////public: - //// DeadzoneFilter(float min, float max = 1.0f); - //// virtual float apply(float newValue, float oldValue) override; - ////}; + class ConstrainToIntegerFilter : public Filter { + public: + REGISTER_FILTER_CLASS(ConstrainToIntegerFilter, "constrainToInteger"); + ConstrainToIntegerFilter() {}; + + virtual float apply(float value) const override { + return glm::sign(value); + } + protected: + }; + + class ConstrainToPositiveIntegerFilter : public Filter { + public: + REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter, "constrainToPositiveInteger"); + ConstrainToPositiveIntegerFilter() {}; + + virtual float apply(float value) const override { + return (value <= 0.0f) ? 0.0f : 1.0f; + } + protected: + }; //class EasingFilter : public Filter { //public: @@ -236,12 +237,6 @@ namespace controller { // const float _exponent; //}; - //class ClampFilter : public RangeFilter { - //public: - // ClampFilter(float min = 0.0, float max = 1.0) : RangeFilter(min, max) {}; - // virtual float apply(float value) const override; - //}; - //class AbsFilter : public Filter { //public: // virtual float apply(float value) const override; diff --git a/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp b/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp index c80e5fc721..baeae55128 100644 --- a/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/NewControllerScriptingInterface.cpp @@ -12,6 +12,9 @@ #include +#include +#include + #include #include #include @@ -22,8 +25,6 @@ #include "impl/MappingBuilderProxy.h" #include "Logging.h" -static const uint16_t ACTIONS_DEVICE = UserInputMapper::Input::INVALID_DEVICE - (uint16_t)1; - namespace controller { @@ -161,7 +162,7 @@ namespace controller { int actionNumber = 0; qCDebug(controllers) << "Setting up standard actions"; for (const auto& actionName : actionNames) { - UserInputMapper::Input actionInput(ACTIONS_DEVICE, actionNumber++, UserInputMapper::ChannelType::AXIS); + UserInputMapper::Input actionInput(UserInputMapper::Input::ACTIONS_DEVICE, actionNumber++, UserInputMapper::ChannelType::AXIS); qCDebug(controllers) << "\tAction: " << actionName << " " << QString::number(actionInput.getID(), 16); // Expose the IDs to JS _actions.insert(sanatizeName(actionName), actionInput.getID()); @@ -182,6 +183,34 @@ namespace controller { return new MappingBuilderProxy(*this, mapping); } + QObject* NewControllerScriptingInterface::parseMapping(const QString& json) { + + QJsonObject obj; + QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + // check validity of the document + if (!doc.isNull()) { + if (doc.isObject()) { + obj = doc.object(); + + auto mapping = std::make_shared("default"); + auto mappingBuilder = new MappingBuilderProxy(*this, mapping); + + mappingBuilder->parse(obj); + + _mappingsByName[mapping->_name] = mapping; + + } else { + qDebug() << "Mapping json Document is not an object" << endl; + } + } else { + qDebug() << "Invalid JSON...\n" << json << endl; + } + + return nullptr; + } + + Q_INVOKABLE QObject* newMapping(const QJsonObject& json); + void NewControllerScriptingInterface::enableMapping(const QString& mappingName, bool enable) { auto iterator = _mappingsByName.find(mappingName); if (_mappingsByName.end() == iterator) { diff --git a/libraries/controllers/src/controllers/NewControllerScriptingInterface.h b/libraries/controllers/src/controllers/NewControllerScriptingInterface.h index bdc291bc03..784b8cf5bd 100644 --- a/libraries/controllers/src/controllers/NewControllerScriptingInterface.h +++ b/libraries/controllers/src/controllers/NewControllerScriptingInterface.h @@ -40,6 +40,7 @@ namespace controller { Q_INVOKABLE void update(); Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString()); + Q_INVOKABLE QObject* parseMapping(const QString& json); Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true); Q_INVOKABLE void disableMapping(const QString& mappingName) { enableMapping(mappingName, false); diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp index d606b52608..38efcfdb00 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp @@ -57,9 +57,7 @@ QObject* RouteBuilderProxy::filter(const QScriptValue& expression) { QObject* RouteBuilderProxy::clamp(float min, float max) { - addFilter([=](float value) { - return glm::clamp(value, min, max); - }); + addFilter(Filter::Pointer(new ClampFilter(min, max))); return this; } @@ -69,40 +67,28 @@ QObject* RouteBuilderProxy::scale(float multiplier) { } QObject* RouteBuilderProxy::invert() { - return scale(-1.0f); + addFilter(Filter::Pointer(new InvertFilter())); + return this; } QObject* RouteBuilderProxy::deadZone(float min) { - assert(min < 1.0f); - float scale = 1.0f / (1.0f - min); - addFilter([=](float value) { - if (abs(value) < min) { - return 0.0f; - } - return (value - min) * scale; - }); - + addFilter(Filter::Pointer(new DeadZoneFilter(min))); return this; } QObject* RouteBuilderProxy::constrainToInteger() { - addFilter([=](float value) { - return glm::sign(value); - }); + addFilter(Filter::Pointer(new ConstrainToIntegerFilter())); return this; } QObject* RouteBuilderProxy::constrainToPositiveInteger() { - addFilter([=](float value) { - return (value <= 0.0f) ? 0.0f : 1.0f; - }); + addFilter(Filter::Pointer(new ConstrainToPositiveIntegerFilter())); return this; } QObject* RouteBuilderProxy::pulse(float interval) { - Filter::Pointer filter = std::make_shared(interval); - addFilter(filter); + addFilter(Filter::Pointer(new PulseFilter(interval))); return this; } diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp index 325dc5dfe7..0f797e9ad0 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp @@ -12,10 +12,15 @@ #include "UserInputMapper.h" #include "StandardController.h" +#include +Q_DECLARE_LOGGING_CATEGORY(userInputMapper) +Q_LOGGING_CATEGORY(userInputMapper, "hifi.userInputMapper") + const UserInputMapper::Input UserInputMapper::Input::INVALID_INPUT = UserInputMapper::Input(UINT16_MAX); const uint16_t UserInputMapper::Input::INVALID_DEVICE = INVALID_INPUT.getDevice(); const uint16_t UserInputMapper::Input::INVALID_CHANNEL = INVALID_INPUT.getChannel(); -const uint16_t UserInputMapper::Input::INVALID_TYPE = (uint16_t)INVALID_INPUT.getType(); +const uint16_t UserInputMapper::Input::INVALID_TYPE = (uint16_t)INVALID_INPUT.getType(); +const uint16_t UserInputMapper::Input::ACTIONS_DEVICE = INVALID_DEVICE - (uint16)1; // Default contruct allocate the poutput size with the current hardcoded action channels UserInputMapper::UserInputMapper() { @@ -31,6 +36,7 @@ UserInputMapper::~UserInputMapper() { bool UserInputMapper::registerDevice(uint16 deviceID, const DeviceProxy::Pointer& proxy){ proxy->_name += " (" + QString::number(deviceID) + ")"; _registeredDevices[deviceID] = proxy; + qCDebug(userInputMapper) << "Registered input device <" << proxy->_name << "> deviceID = " << deviceID; return true; } @@ -65,12 +71,18 @@ void UserInputMapper::resetDevice(uint16 deviceID) { } int UserInputMapper::findDevice(QString name) const { + if (_standardDevice && (_standardDevice->getName() == name)) { + return getStandardDeviceID(); + } + for (auto device : _registeredDevices) { if (device.second->_name.split(" (")[0] == name) { return device.first; + } else if (device.second->_baseName == name) { + return device.first; } } - return 0; + return Input::INVALID_DEVICE; } QVector UserInputMapper::getDeviceNames() { @@ -94,10 +106,34 @@ UserInputMapper::Input UserInputMapper::findDeviceInput(const QString& inputName int deviceID = findDevice(deviceName); if (deviceID != Input::INVALID_DEVICE) { - // getAllInputsForDevice(deviceID); + const auto& deviceProxy = _registeredDevices.at(deviceID); + auto deviceInputs = deviceProxy->getAvailabeInputs(); + + for (auto input : deviceInputs) { + if (input.second == inputName) { + return input.first; + } + } + + qCDebug(userInputMapper) << "Couldn\'t find InputChannel named <" << inputName << "> for device <" << deviceName << ">"; + + } else if (deviceName == "Actions") { + deviceID = Input::ACTIONS_DEVICE; + int actionNum = 0; + for (auto action : _actionNames) { + if (action == inputName) { + return Input(Input::ACTIONS_DEVICE, actionNum, ChannelType::AXIS); + } + actionNum++; + } + + qCDebug(userInputMapper) << "Couldn\'t find ActionChannel named <" << inputName << "> among actions"; + + } else { + qCDebug(userInputMapper) << "Couldn\'t find InputDevice named <" << deviceName << ">"; } - - + } else { + qCDebug(userInputMapper) << "Couldn\'t understand <" << inputName << "> as a valid inputDevice.inputName"; } return Input(); diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.h b/libraries/input-plugins/src/input-plugins/UserInputMapper.h index b7b105df5e..fae77cca92 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.h +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.h @@ -85,6 +85,7 @@ public: static const uint16 INVALID_DEVICE; static const uint16 INVALID_CHANNEL; static const uint16 INVALID_TYPE; + static const uint16 ACTIONS_DEVICE; }; @@ -119,9 +120,11 @@ public: class DeviceProxy { public: - DeviceProxy(QString name) { _name = name; } + DeviceProxy(QString name) : _baseName(name), _name(name) {} + const QString& getBaseName() const { return _baseName; } const QString& getName() const { return _name; } + QString _baseName; QString _name; ButtonGetter getButton = [] (const Input& input, int timestamp) -> bool { return false; }; AxisGetter getAxis = [] (const Input& input, int timestamp) -> float { return 0.0f; }; From 416df1c44c7f1c181ab7fd81e66f5888a3bfb4a2 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 15 Oct 2015 14:21:08 -0700 Subject: [PATCH 5/8] Fixing the mac build --- libraries/controllers/src/controllers/Filter.h | 2 +- .../src/controllers/impl/RouteBuilderProxy.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/controllers/src/controllers/Filter.h b/libraries/controllers/src/controllers/Filter.h index 4d8c483b08..876f57c97d 100644 --- a/libraries/controllers/src/controllers/Filter.h +++ b/libraries/controllers/src/controllers/Filter.h @@ -76,7 +76,7 @@ namespace controller { } Filter* create(const std::string& name) const { - auto& entryIt = _entries.find(name); + const auto& entryIt = _entries.find(name); if (entryIt != _entries.end()) { return (*entryIt).second->create(); } diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp index aeef081b5f..dcf2b30f66 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp @@ -121,12 +121,12 @@ QObject* RouteBuilderProxy::filters(const QJsonValue& json) { } void RouteBuilderProxy::to(const QJsonValue& json) { - if (json.isString()) { - - return to(_parent.endpointFor(_parent.inputFor(json.toString()))); + if (json.isString()) { + + return to(_parent.endpointFor(_parent.inputFor(json.toString()))); } else if (json.isObject()) { // Endpoint is defined as an object, we expect a js function then - return to(nullptr); + //return to((Endpoint*) nullptr); } } From 249efa383ea41d534d802426fb966a4a5b17cfe9 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 15 Oct 2015 14:49:22 -0700 Subject: [PATCH 6/8] MErging maybe finally ?????? --- .../src/controllers/UserInputMapper.cpp | 171 ------------------ 1 file changed, 171 deletions(-) diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 2d03fbe58b..b62e2e0e8f 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -93,177 +93,6 @@ QVector UserInputMapper::getDeviceNames() { } UserInputMapper::Input UserInputMapper::findDeviceInput(const QString& inputName) const { -/*======= - -// Default contruct allocate the poutput size with the current hardcoded action channels -UserInputMapper::UserInputMapper() { - registerStandardDevice(); - assignDefaulActionScales(); - createActionNames(); -} - -UserInputMapper::~UserInputMapper() { -} - - -int UserInputMapper::recordDeviceOfType(const QString& deviceName) { - if (!_deviceCounts.contains(deviceName)) { - _deviceCounts[deviceName] = 0; - } - _deviceCounts[deviceName] += 1; - - return _deviceCounts[deviceName]; -} - -bool UserInputMapper::registerDevice(uint16 deviceID, const DeviceProxy::Pointer& proxy) { - int numberOfType = recordDeviceOfType(proxy->_name); - - if (numberOfType > 1) { - proxy->_name += QString::number(numberOfType); - } - - _registeredDevices[deviceID] = proxy; - return true; -} - -UserInputMapper::DeviceProxy::Pointer UserInputMapper::getDeviceProxy(const Input& input) { - auto device = _registeredDevices.find(input.getDevice()); - if (device != _registeredDevices.end()) { - return (device->second); - } else { - return DeviceProxy::Pointer(); - } -} - -QString UserInputMapper::getDeviceName(uint16 deviceID) { - if (_registeredDevices.find(deviceID) != _registeredDevices.end()) { - return _registeredDevices[deviceID]->_name; - } - return QString("unknown"); -} - - -void UserInputMapper::resetAllDeviceBindings() { - for (auto device : _registeredDevices) { - device.second->resetDeviceBindings(); - } -} - -void UserInputMapper::resetDevice(uint16 deviceID) { - auto device = _registeredDevices.find(deviceID); - if (device != _registeredDevices.end()) { - device->second->resetDeviceBindings(); - } -} - -int UserInputMapper::findDevice(QString name) { - for (auto device : _registeredDevices) { - if (device.second->_name.split(" (")[0] == name) { - return device.first; - } - } - return 0; -} - -QVector UserInputMapper::getDeviceNames() { - QVector result; - for (auto device : _registeredDevices) { - QString deviceName = device.second->_name.split(" (")[0]; - result << deviceName; - } - return result; -} - - -bool UserInputMapper::addInputChannel(Action action, const Input& input, float scale) { - return addInputChannel(action, input, Input(), scale); -} - -bool UserInputMapper::addInputChannel(Action action, const Input& input, const Input& modifier, float scale) { - // Check that the device is registered - if (!getDeviceProxy(input)) { - qDebug() << "UserInputMapper::addInputChannel: The input comes from a device #" << input.getDevice() << "is unknown. no inputChannel mapped."; - return false; - } - - auto inputChannel = InputChannel(input, modifier, action, scale); - - // Insert or replace the input to modifiers - if (inputChannel.hasModifier()) { - auto& modifiers = _inputToModifiersMap[input.getID()]; - modifiers.push_back(inputChannel._modifier); - std::sort(modifiers.begin(), modifiers.end()); - } - - // Now update the action To Inputs side of things - _actionToInputsMap.insert(ActionToInputsMap::value_type(action, inputChannel)); - - return true; -} - -int UserInputMapper::addInputChannels(const InputChannels& channels) { - int nbAdded = 0; - for (auto& channel : channels) { - nbAdded += addInputChannel(channel._action, channel._input, channel._modifier, channel._scale); - } - return nbAdded; -} - -bool UserInputMapper::removeInputChannel(InputChannel inputChannel) { - // Remove from Input to Modifiers map - if (inputChannel.hasModifier()) { - _inputToModifiersMap.erase(inputChannel._input.getID()); - } - - // Remove from Action to Inputs map - std::pair ret; - ret = _actionToInputsMap.equal_range(inputChannel._action); - for (ActionToInputsMap::iterator it=ret.first; it!=ret.second; ++it) { - if (it->second == inputChannel) { - _actionToInputsMap.erase(it); - return true; - } - } - - return false; -} - -void UserInputMapper::removeAllInputChannels() { - _inputToModifiersMap.clear(); - _actionToInputsMap.clear(); -} - -void UserInputMapper::removeAllInputChannelsForDevice(uint16 device) { - QVector channels = getAllInputsForDevice(device); - for (auto& channel : channels) { - removeInputChannel(channel); - } -} - -void UserInputMapper::removeDevice(int device) { - removeAllInputChannelsForDevice((uint16) device); - _registeredDevices.erase(device); -} - -int UserInputMapper::getInputChannels(InputChannels& channels) const { - for (auto& channel : _actionToInputsMap) { - channels.push_back(channel.second); - } - - return _actionToInputsMap.size(); -} - -QVector UserInputMapper::getAllInputsForDevice(uint16 device) { - InputChannels allChannels; - getInputChannels(allChannels); - - QVector channels; - for (InputChannel inputChannel : allChannels) { - if (inputChannel._input._device == device) { - channels.push_back(inputChannel); - } - } ->>>>>>> 80cffdb764d3faa5516c8b0eb0a49d84cc395416*/ // Split the full input name as such: deviceName.inputName auto names = inputName.split('.'); From 1b03b6867c075a1c4b4430a0a682a8a4d9fb62aa Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 15 Oct 2015 15:01:34 -0700 Subject: [PATCH 7/8] Fixing the include file names... --- libraries/controllers/src/controllers/Filter.cpp | 4 ++-- .../controllers/src/controllers/impl/MappingBuilderProxy.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/controllers/src/controllers/Filter.cpp b/libraries/controllers/src/controllers/Filter.cpp index 3e1079b984..43317fd62d 100644 --- a/libraries/controllers/src/controllers/Filter.cpp +++ b/libraries/controllers/src/controllers/Filter.cpp @@ -11,8 +11,8 @@ #include #include -#include -#include +#include +#include #include "SharedUtil.h" diff --git a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp index b347d8b7c6..fe7a5c24af 100644 --- a/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/MappingBuilderProxy.cpp @@ -11,8 +11,9 @@ #include #include -#include -#include +#include +#include + #include "RouteBuilderProxy.h" #include "../ScriptingInterface.h" From 63ad9ae19837c2d829a42a63cb99a108d82350d8 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 15 Oct 2015 15:02:55 -0700 Subject: [PATCH 8/8] Fixing the include file names... --- .../controllers/src/controllers/impl/RouteBuilderProxy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp index dcf2b30f66..033e94daa0 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp @@ -9,8 +9,8 @@ #include -#include -#include +#include +#include #include