Allow input devices to break up their mappings into multiple files

This commit is contained in:
Brad Davis 2015-12-30 22:25:16 -08:00
parent c77b66f88c
commit 000130617e
7 changed files with 111 additions and 16 deletions

View file

@ -1,15 +1,6 @@
{
"name": "Standard to Action",
"channels": [
{ "from": "Standard.DU", "when": "Application.NavigationFocused", "to": "Actions.UiNavUp" },
{ "from": "Standard.DD", "when": "Application.NavigationFocused", "to": "Actions.UiNavDown" },
{ "from": "Standard.DL", "when": "Application.NavigationFocused", "to": "Actions.UiNavLeft" },
{ "from": "Standard.DR", "when": "Application.NavigationFocused", "to": "Actions.UiNavRight" },
{ "from": "Standard.A", "when": "Application.NavigationFocused", "to": "Actions.UiNavSelect" },
{ "from": "Standard.B", "when": "Application.NavigationFocused", "to": "Actions.UiNavBack" },
{ "from": "Standard.LB", "when": "Application.NavigationFocused", "to": "Actions.UiNavPreviousGroup" },
{ "from": "Standard.RB", "when": "Application.NavigationFocused", "to": "Actions.UiNavNextGroup" },
{ "from": "Standard.LY", "to": "Actions.TranslateZ" },
{ "from": "Standard.LX", "to": "Actions.TranslateX" },

View file

@ -0,0 +1,61 @@
{
"name": "Standard to Action",
"when": "Application.NavigationFocused",
"channels": [
{ "disabled_from": { "makeAxis" : [ "Standard.DD", "Standard.DU" ] }, "to": "Actions.UiNavVertical" },
{ "disabled_from": { "makeAxis" : [ "Standard.DL", "Standard.DR" ] }, "to": "Actions.UiNavLateral" },
{ "disabled_from": { "makeAxis" : [ "Standard.LB", "Standard.RB" ] }, "to": "Actions.UiNavGroup" },
{ "from": "Standard.DU", "to": "Actions.UiNavVertical" },
{ "from": "Standard.DD", "to": "Actions.UiNavVertical", "filters": "invert" },
{ "from": "Standard.DL", "to": "Actions.UiNavLateral", "filters": "invert" },
{ "from": "Standard.DR", "to": "Actions.UiNavLateral" },
{ "from": "Standard.LB", "to": "Actions.UiNavGroup","filters": "invert" },
{ "from": "Standard.RB", "to": "Actions.UiNavGroup" },
{ "from": [ "Standard.A", "Standard.X", "Standard.RT", "Standard.LT" ], "to": "Actions.UiNavSelect" },
{ "from": [ "Standard.B", "Standard.Y", "Standard.RightPrimaryThumb", "Standard.LeftPrimaryThumb" ], "to": "Actions.UiNavBack" },
{
"from": [ "Standard.RT", "Standard.LT" ],
"to": "Actions.UiNavSelect",
"filters": [
{ "type": "deadZone", "min": 0.5 },
"constrainToInteger"
]
},
{
"from": "Standard.LX", "to": "Actions.UiNavLateral",
"filters": [
{ "type": "deadZone", "min": 0.95 },
"constrainToInteger",
{ "type": "pulse", "interval": 0.4 }
]
},
{
"from": "Standard.LY", "to": "Actions.UiNavVertical",
"filters": [
"invert",
{ "type": "deadZone", "min": 0.95 },
"constrainToInteger",
{ "type": "pulse", "interval": 0.4 }
]
},
{
"from": "Standard.RX", "to": "Actions.UiNavLateral",
"filters": [
{ "type": "deadZone", "min": 0.95 },
"constrainToInteger",
{ "type": "pulse", "interval": 0.4 }
]
},
{
"from": "Standard.RY", "to": "Actions.UiNavVertical",
"filters": [
"invert",
{ "type": "deadZone", "min": 0.95 },
"constrainToInteger",
{ "type": "pulse", "interval": 0.4 }
]
}
]
}

View file

@ -83,6 +83,7 @@ protected:
friend class UserInputMapper;
virtual Input::NamedVector getAvailableInputs() const = 0;
virtual QStringList getDefaultMappingConfigs() const { return QStringList() << getDefaultMappingConfig(); }
virtual QString getDefaultMappingConfig() const { return QString(); }
virtual EndpointPointer createEndpoint(const Input& input) const;

View file

@ -131,10 +131,10 @@ EndpointPointer StandardController::createEndpoint(const Input& input) const {
return std::make_shared<StandardEndpoint>(input);
}
QString StandardController::getDefaultMappingConfig() const {
QStringList StandardController::getDefaultMappingConfigs() const {
static const QString DEFAULT_MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/standard.json";
return DEFAULT_MAPPING_JSON;
static const QString DEFAULT_NAV_MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/standard_navigation.json";
return QStringList() << DEFAULT_NAV_MAPPING_JSON << DEFAULT_MAPPING_JSON;
}
}

View file

@ -27,7 +27,7 @@ class StandardController : public QObject, public InputDevice {
public:
virtual EndpointPointer createEndpoint(const Input& input) const override;
virtual Input::NamedVector getAvailableInputs() const override;
virtual QString getDefaultMappingConfig() const override;
virtual QStringList getDefaultMappingConfigs() const override;
virtual void update(float deltaTime, bool jointsCaptured) override;
virtual void focusOutEvent() override;

View file

@ -100,7 +100,7 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
}
_registeredDevices[deviceID] = device;
auto mapping = loadMapping(device->getDefaultMappingConfig());
auto mapping = loadMappings(device->getDefaultMappingConfigs());
if (mapping) {
_mappingsByDevice[deviceID] = mapping;
enableMapping(mapping);
@ -139,7 +139,7 @@ void UserInputMapper::loadDefaultMapping(uint16 deviceID) {
}
auto mapping = loadMapping(proxyEntry->second->getDefaultMappingConfig());
auto mapping = loadMappings(proxyEntry->second->getDefaultMappingConfigs());
if (mapping) {
auto prevMapping = _mappingsByDevice[deviceID];
disableMapping(prevMapping);
@ -710,6 +710,21 @@ Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile) {
return parseMapping(json);
}
MappingPointer UserInputMapper::loadMappings(const QStringList& jsonFiles) {
Mapping::Pointer result;
for (const QString& jsonFile : jsonFiles) {
auto subMapping = loadMapping(jsonFile);
if (subMapping) {
if (!result) {
result = subMapping;
} else {
auto& routes = result->routes;
routes.insert(routes.end(), subMapping->routes.begin(), subMapping->routes.end());
}
}
}
return result;
}
static const QString JSON_NAME = QStringLiteral("name");
@ -888,7 +903,7 @@ Endpoint::Pointer UserInputMapper::parseDestination(const QJsonValue& value) {
Endpoint::Pointer UserInputMapper::parseAxis(const QJsonValue& value) {
if (value.isObject()) {
auto object = value.toObject();
auto object = value.toObject();
if (object.contains("makeAxis")) {
auto axisValue = object.value("makeAxis");
if (axisValue.isArray()) {
@ -985,6 +1000,20 @@ Route::Pointer UserInputMapper::parseRoute(const QJsonValue& value) {
return result;
}
void injectConditional(Route::Pointer& route, Conditional::Pointer& conditional) {
if (!conditional) {
return;
}
if (!route->conditional) {
route->conditional = conditional;
return;
}
route->conditional = std::make_shared<AndConditional>(conditional, route->conditional);
}
Mapping::Pointer UserInputMapper::parseMapping(const QJsonValue& json) {
if (!json.isObject()) {
return Mapping::Pointer();
@ -994,12 +1023,24 @@ Mapping::Pointer UserInputMapper::parseMapping(const QJsonValue& json) {
auto mapping = std::make_shared<Mapping>("default");
mapping->name = obj[JSON_NAME].toString();
const auto& jsonChannels = obj[JSON_CHANNELS].toArray();
Conditional::Pointer globalConditional;
if (obj.contains(JSON_CHANNEL_WHEN)) {
auto conditionalsValue = obj[JSON_CHANNEL_WHEN];
globalConditional = parseConditional(conditionalsValue);
}
for (const auto& channelIt : jsonChannels) {
Route::Pointer route = parseRoute(channelIt);
if (!route) {
qWarning() << "Couldn't parse route";
continue;
}
if (globalConditional) {
injectConditional(route, globalConditional);
}
mapping->routes.push_back(route);
}
_mappingsByName[mapping->name] = mapping;

View file

@ -107,6 +107,7 @@ namespace controller {
MappingPointer newMapping(const QString& mappingName);
MappingPointer parseMapping(const QString& json);
MappingPointer loadMapping(const QString& jsonFile);
MappingPointer loadMappings(const QStringList& jsonFiles);
void loadDefaultMapping(uint16 deviceID);
void enableMapping(const QString& mappingName, bool enable = true);