Skip to content

Commit

Permalink
[storage] v1.0.22: Sanitize loaded button maps for duplicate primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
garbear committed Aug 19, 2016
1 parent 235062d commit b15053e
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
88 changes: 88 additions & 0 deletions src/storage/ButtonMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@

#include "ButtonMap.h"
#include "Device.h"
#include "log/Log.h"
#include "storage/StorageUtils.h"

#include "kodi_peripheral_utils.hpp"
#include "p8-platform/util/timeutils.h"

#include <algorithm>

using namespace JOYSTICK;

#define RESOURCE_LIFETIME_MS 2000 // 2 seconds
Expand Down Expand Up @@ -101,8 +106,91 @@ bool CButtonMap::Refresh(void)
if (!Load())
return false;

Sanitize();

m_timestamp = now;
}

return true;
}

void CButtonMap::Sanitize()
{
for (auto it = m_buttonMap.begin(); it != m_buttonMap.end(); ++it)
{
const std::string& controllerId = it->first;
FeatureVector& features = it->second;

// Loop through features
for (unsigned int iFeature = 0; iFeature < features.size(); ++iFeature)
{
auto& feature = features[iFeature];

// Loop through feature's primitives
auto& primitives = feature.Primitives();
for (unsigned int iPrimitive = 0; iPrimitive < primitives.size(); ++iPrimitive)
{
auto& primitive = primitives[iPrimitive];

if (primitive.Type() == JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN)
continue;

bool bFound = false;

// Search for prior feature with the primitive
ADDON::JoystickFeature existingFeature;

for (unsigned int iExistingFeature = 0; iExistingFeature < iFeature; ++iExistingFeature)
{
const auto& existingPrimitives = features[iExistingFeature].Primitives();
if (std::find(existingPrimitives.begin(), existingPrimitives.end(), primitive) != existingPrimitives.end())
{
existingFeature = features[iExistingFeature];
bFound = true;
break;
}
}

if (!bFound)
{
// Search for primitive in prior primitives
for (unsigned int iExistingPrimitive = 0; iExistingPrimitive < iPrimitive; ++iExistingPrimitive)
{
if (primitives[iExistingPrimitive] == primitive)
{
bFound = true;
break;
}
}
}

// Invalid the primitive if it has already been seen
if (bFound)
{
esyslog("%s: %s (%s) conflicts with %s (%s), skipping",
controllerId.c_str(),
CStorageUtils::PrimitiveToString(primitive).c_str(),
existingFeature.Type() != JOYSTICK_FEATURE_TYPE_UNKNOWN ? existingFeature.Name().c_str() : feature.Name().c_str(),
CStorageUtils::PrimitiveToString(primitive).c_str(),
feature.Name().c_str());

primitive = ADDON::DriverPrimitive();
}
}
}

// Erase invalid features
features.erase(std::remove_if(features.begin(), features.end(),
[](const ADDON::JoystickFeature& feature)
{
auto& primitives = feature.Primitives();

return std::find_if(primitives.begin(), primitives.end(),
[](const ADDON::DriverPrimitive& primitive)
{
return primitive.Type() != JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN;
}) == primitives.end();

}), features.end());
}
}
2 changes: 2 additions & 0 deletions src/storage/ButtonMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ namespace JOYSTICK
virtual bool Load(void) = 0;
virtual bool Save(void) const = 0;

void Sanitize();

const std::string m_strResourcePath;
DevicePtr m_device;
ButtonMap m_buttonMap;
Expand Down
34 changes: 34 additions & 0 deletions src/storage/StorageUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,37 @@ std::string CStorageUtils::FormatHexString(int iVal)

return StringUtils::Format("%04X", iVal);
};

std::string CStorageUtils::PrimitiveToString(const ADDON::DriverPrimitive& primitive)
{
switch (primitive.Type())
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
return StringUtils::Format("button %u", primitive.DriverIndex());
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_HAT_DIRECTION:
switch (primitive.HatDirection())
{
case JOYSTICK_DRIVER_HAT_UP:
return StringUtils::Format("hat up");
case JOYSTICK_DRIVER_HAT_RIGHT:
return StringUtils::Format("hat right");
case JOYSTICK_DRIVER_HAT_DOWN:
return StringUtils::Format("hat down");
case JOYSTICK_DRIVER_HAT_LEFT:
return StringUtils::Format("hat left");
default:
break;
}
break;
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS:
return StringUtils::Format("axis %s%u",
primitive.SemiAxisDirection() == JOYSTICK_DRIVER_SEMIAXIS_POSITIVE ? "+" : "-",
primitive.DriverIndex());
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
return StringUtils::Format("motor %u", primitive.DriverIndex());
default:
break;
}

return "";
}
3 changes: 3 additions & 0 deletions src/storage/StorageUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace ADDON
{
struct DriverPrimitive;
class Joystick;
}

Expand Down Expand Up @@ -72,6 +73,8 @@ namespace JOYSTICK
*/
static std::string FormatHexString(int iVal);

static std::string PrimitiveToString(const ADDON::DriverPrimitive& primitive);

private:
static std::set<std::string> m_existingDirs; // Cache list of existing dirs
};
Expand Down

0 comments on commit b15053e

Please sign in to comment.