Skip to content

Commit

Permalink
Keymap handling: Fix analog sticks
Browse files Browse the repository at this point in the history
  • Loading branch information
garbear committed Jul 5, 2017
1 parent beab9bb commit 04cf835
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 50 deletions.
3 changes: 3 additions & 0 deletions xbmc/input/joysticks/IInputHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ namespace JOYSTICK
* \param feature A feature belonging to the controller specified by ControllerID()
*
* \return True if the feature is currently accepting input, false otherwise
*
* This does not prevent the input events from being called, but can return
* false to indicate that input wasn't handled for the specified feature.
*/
virtual bool AcceptsInput(const FeatureName &feature) const = 0;

Expand Down
26 changes: 10 additions & 16 deletions xbmc/input/joysticks/generic/FeatureHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,14 @@ CScalarFeature::CScalarFeature(const FeatureName& name, IInputHandler* handler,

bool CScalarFeature::OnDigitalMotion(const CDriverPrimitive& source, bool bPressed)
{
if (!AcceptsInput(bPressed))
return false;

bool bHandled = false;

if (m_inputType == INPUT_TYPE::DIGITAL)
bHandled = OnDigitalMotion(bPressed);
else if (m_inputType == INPUT_TYPE::ANALOG)
bHandled = OnAnalogMotion(bPressed ? 1.0f : 0.0f);

return bHandled;
return bHandled && AcceptsInput(bPressed);
}

bool CScalarFeature::OnAnalogMotion(const CDriverPrimitive& source, float magnitude)
Expand All @@ -96,17 +93,14 @@ bool CScalarFeature::OnAnalogMotion(const CDriverPrimitive& source, float magnit
if (magnitude != 0.0f && magnitude != 1.0f)
m_bDiscrete = false;

if (!AcceptsInput(magnitude > 0.0f))
return false;

bool bHandled = false;

if (m_inputType == INPUT_TYPE::DIGITAL)
bHandled = OnDigitalMotion(magnitude >= ANALOG_DIGITAL_THRESHOLD);
else if (m_inputType == INPUT_TYPE::ANALOG)
bHandled = OnAnalogMotion(magnitude);

return bHandled;
return bHandled && AcceptsInput(magnitude > 0.0f);
}

void CScalarFeature::ProcessMotions(void)
Expand Down Expand Up @@ -211,9 +205,6 @@ bool CAnalogStick::OnDigitalMotion(const CDriverPrimitive& source, bool bPressed

bool CAnalogStick::OnAnalogMotion(const CDriverPrimitive& source, float magnitude)
{
if (!AcceptsInput(magnitude != 0.0f))
return false;

ANALOG_STICK_DIRECTION direction = ANALOG_STICK_DIRECTION::UNKNOWN;

std::vector<ANALOG_STICK_DIRECTION> dirs = {
Expand All @@ -233,19 +224,25 @@ bool CAnalogStick::OnAnalogMotion(const CDriverPrimitive& source, float magnitud
}
}

bool bHandled = false;

switch (direction)
{
case ANALOG_STICK_DIRECTION::UP:
m_vertAxis.SetPositiveDistance(magnitude);
bHandled = true;
break;
case ANALOG_STICK_DIRECTION::DOWN:
m_vertAxis.SetNegativeDistance(magnitude);
bHandled = true;
break;
case ANALOG_STICK_DIRECTION::RIGHT:
m_horizAxis.SetPositiveDistance(magnitude);
bHandled = true;
break;
case ANALOG_STICK_DIRECTION::LEFT:
m_horizAxis.SetNegativeDistance(magnitude);
bHandled = true;
break;
default:
// Just in case, avoid sticking
Expand All @@ -254,7 +251,7 @@ bool CAnalogStick::OnAnalogMotion(const CDriverPrimitive& source, float magnitud
break;
}

return true;
return bHandled && AcceptsInput(magnitude != 0.0f);
}

void CAnalogStick::ProcessMotions(void)
Expand Down Expand Up @@ -315,9 +312,6 @@ bool CAccelerometer::OnDigitalMotion(const CDriverPrimitive& source, bool bPress

bool CAccelerometer::OnAnalogMotion(const CDriverPrimitive& source, float magnitude)
{
if (!AcceptsInput(true))
return false;

bool bHandled = false;

CDriverPrimitive positiveX;
Expand Down Expand Up @@ -349,7 +343,7 @@ bool CAccelerometer::OnAnalogMotion(const CDriverPrimitive& source, float magnit
m_yAxis.Reset();
}

return bHandled;
return bHandled && AcceptsInput(true);
}

void CAccelerometer::ProcessMotions(void)
Expand Down
9 changes: 5 additions & 4 deletions xbmc/input/joysticks/interfaces/IKeymapHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
#pragma once

#include <set>
#include <string>

namespace KODI
Expand All @@ -35,13 +36,13 @@ namespace JOYSTICK
virtual ~IKeymapHandler() = default;

/*!
* \brief Get the pressed state of the key
* \brief Get the pressed state of the given keys
*
* \param keyName The key name
* \param keyNames The key names
*
* \return True if the key is pressed, false otherwise
* \return True if all keys are pressed or no keys are given, false otherwise
*/
virtual bool IsPressed(const std::string& keyName) const = 0;
virtual bool HotkeysPressed(const std::set<std::string> &keyNames) const = 0;

/*!
* \brief Get the key name of the last button pressed
Expand Down
30 changes: 9 additions & 21 deletions xbmc/input/joysticks/keymaps/KeyHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ bool CKeyHandler::OnAnalogMotion(float magnitude, unsigned int motionTimeMs)
bool bHandled = false;

// Calculate press state
const bool bPressed = (magnitude >= DIGITAL_ANALOG_THRESHOLD);
const bool bPressed = IsPressed(magnitude);
const bool bJustPressed = bPressed && !m_bHeld;

if (bJustPressed)
Expand Down Expand Up @@ -124,7 +124,7 @@ bool CKeyHandler::HandleActions(std::vector<const KeymapAction*> actions, float
actions.erase(std::remove_if(actions.begin(), actions.end(),
[this](const KeymapAction *action)
{
return !HotkeysPressed(action->hotkeys);
return !m_keymapHandler->HotkeysPressed(action->hotkeys);
}), actions.end());

if (actions.empty())
Expand Down Expand Up @@ -161,7 +161,7 @@ bool CKeyHandler::HandleActions(std::vector<const KeymapAction*> actions, float
}
else if (actions.size() > 1)
{
// If button was help before being released, send a relesae action
// If button was help before being released, send a release action
if (m_bHeld)
{
// Holdtime is zero, so use previous holdtime from before button release
Expand Down Expand Up @@ -200,7 +200,7 @@ bool CKeyHandler::HandleAction(const KeymapAction& action, float magnitude, unsi
{
bSendAction = true;
}
else
else if (IsPressed(magnitude))
{
// Dispatch action if button was pressed this frame
if (holdTimeMs == 0)
Expand All @@ -221,23 +221,6 @@ bool CKeyHandler::HandleAction(const KeymapAction& action, float magnitude, unsi
return m_bActionSent;
}

bool CKeyHandler::HotkeysPressed(const std::set<std::string> &hotkeys) const
{
// No hotkeys to press
if (hotkeys.empty())
return true;

// Look for unpressed hotkey
auto it = std::find_if(hotkeys.begin(), hotkeys.end(),
[this](const std::string &hotkey)
{
return !m_keymapHandler->IsPressed(CJoystickUtils::MakeKeyName(hotkey));
});

// Return true if all hotkeys are pressed
return it == hotkeys.end();
}

bool CKeyHandler::SendRepeatAction(unsigned int holdTimeMs)
{
bool bSendRepeat = true;
Expand All @@ -256,3 +239,8 @@ bool CKeyHandler::SendRepeatAction(unsigned int holdTimeMs)

return bSendRepeat;
}

bool CKeyHandler::IsPressed(float magnitude)
{
return magnitude >= DIGITAL_ANALOG_THRESHOLD;
}
3 changes: 2 additions & 1 deletion xbmc/input/joysticks/keymaps/KeyHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ namespace JOYSTICK
// Check criteria for sending a repeat action
bool SendRepeatAction(unsigned int holdTimeMs);

bool HotkeysPressed(const std::set<std::string> &hotkeys) const;
// Helper function
static bool IsPressed(float magnitude);

// Construction parameters
const std::string m_keyName;
Expand Down
49 changes: 44 additions & 5 deletions xbmc/input/joysticks/keymaps/KeymapHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,42 @@ CKeymapHandler::CKeymapHandler(IActionListener *actionHandler, const IKeymap *ke
assert(m_keymap != nullptr);
}

bool CKeymapHandler::IsPressed(const std::string& keyName) const
bool CKeymapHandler::HotkeysPressed(const std::set<std::string> &keyNames) const
{
auto it = m_keyHandlers.find(keyName);
if (it != m_keyHandlers.end())
return it->second->IsPressed();
bool bHotkeysPressed = true;

return false;
for (const auto &hotkey : keyNames)
{
auto it = m_keyHandlers.find(hotkey);
if (it == m_keyHandlers.end() || !it->second->IsPressed())
{
bHotkeysPressed = false;
break;
}
}

return bHotkeysPressed;
}

std::string CKeymapHandler::ControllerID() const
{
return m_keymap->ControllerID();
}

bool CKeymapHandler::AcceptsInput(const FeatureName& feature) const
{
if (HasAction(CJoystickUtils::MakeKeyName(feature)))
return true;

for (auto dir : CJoystickUtils::GetDirections())
{
if (HasAction(CJoystickUtils::MakeKeyName(feature, dir)))
return true;
}

return false;
}

bool CKeymapHandler::OnButtonPress(const FeatureName& feature, bool bPressed)
{
const std::string keyName = CJoystickUtils::MakeKeyName(feature);
Expand Down Expand Up @@ -139,3 +161,20 @@ IKeyHandler *CKeymapHandler::GetKeyHandler(const std::string &keyName)

return it->second.get();
}

bool CKeymapHandler::HasAction(const std::string &keyName) const
{
bool bHasAction = false;

const auto &actions = m_keymap->GetActions(keyName);
for (const auto &action : actions)
{
if (HotkeysPressed(action.hotkeys))
{
bHasAction = true;
break;
}
}

return bHasAction;
}
7 changes: 4 additions & 3 deletions xbmc/input/joysticks/keymaps/KeymapHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ namespace JOYSTICK
virtual ~CKeymapHandler() = default;

// implementation of IKeymapHandler
virtual bool IsPressed(const std::string& keyName) const override;
virtual bool HotkeysPressed(const std::set<std::string>& keyNames) const override;
virtual std::string GetLastPressed() const override { return m_lastPressed; }
virtual void OnPress(const std::string& keyName) override { m_lastPressed = keyName; }

// implementation of IInputHandler
virtual std::string ControllerID() const override;
virtual bool HasFeature(const FeatureName& feature) const override { return true; }
virtual bool AcceptsInput(const FeatureName& feature) const override { return true; }
virtual bool AcceptsInput(const FeatureName& feature) const override;
virtual bool OnButtonPress(const FeatureName& feature, bool bPressed) override;
virtual void OnButtonHold(const FeatureName& feature, unsigned int holdTimeMs) override;
virtual bool OnButtonMotion(const FeatureName& feature, float magnitude, unsigned int motionTimeMs) override;
Expand All @@ -68,8 +68,9 @@ namespace JOYSTICK
bool ActivateDirection(const FeatureName& feature, float magnitude, ANALOG_STICK_DIRECTION dir, unsigned int motionTimeMs);
void DeactivateDirection(const FeatureName& feature, ANALOG_STICK_DIRECTION dir);

// Helper function
// Helper functions
IKeyHandler *GetKeyHandler(const std::string &keyName);
bool HasAction(const std::string &keyName) const;

// Construction parameters
IActionListener *const m_actionHandler;
Expand Down

0 comments on commit 04cf835

Please sign in to comment.