Skip to content

Commit

Permalink
Added most recent QInput as a testable Instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
TReed0803 committed Jan 16, 2015
1 parent 6fbb830 commit 022a4d6
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 48 deletions.
155 changes: 116 additions & 39 deletions 3a_EfficientInputManager/ProfileApplication/Instances/QInput.cpp
@@ -1,88 +1,165 @@
#include "QInput.h"
#include <algorithm>
#include <QCursor>
#include <vector>
#include <limits>
#include <algorithm>

/*******************************************************************************
* Static Helper Structs
******************************************************************************/
struct KeyInstance : std::pair<int, QInput::KeyState>
template <typename T>
struct InputInstance : std::pair<T, QInput::InputState>
{
inline explicit KeyInstance(int k) : std::pair<int, QInput::KeyState>(k, QInput::KeyInvalid) {}
inline KeyInstance(int k, QInput::KeyState s) : std::pair<int, QInput::KeyState>(k, s) {}
inline bool operator<(const KeyInstance &rhs) const
{
return first < rhs.first;
}
inline bool operator==(const KeyInstance &rhs) const
typedef std::pair<T, QInput::InputState> base_class;
inline InputInstance(T value) : base_class(value, QInput::InputInvalid) {}
inline InputInstance(T value, QInput::InputState state) : base_class(value, state) {}
inline bool operator==(const InputInstance &rhs) const
{
return first == rhs.first;
}
};

// Instance types
typedef InputInstance<Qt::Key> KeyInstance;
typedef InputInstance<Qt::MouseButton> ButtonInstance;

// Container types
typedef std::vector<KeyInstance> KeyContainer;
static const KeyInstance InvalidInstance = KeyInstance(std::numeric_limits<int>::max(), QInput::KeyInvalid);
typedef std::vector<ButtonInstance> ButtonContainer;

// Globals
static KeyContainer sg_keyInstances;
static ButtonContainer sg_buttonInstances;
static QPoint sg_mouseCurrPosition;
static QPoint sg_mousePrevPosition;
static QPoint sg_mouseDelta;

/*******************************************************************************
* Static Helper Fucntions
******************************************************************************/
static inline KeyContainer::iterator FindKey(Qt::Key k)
static inline KeyContainer::iterator FindKey(Qt::Key value)
{
return std::find(sg_keyInstances.begin(), sg_keyInstances.end(), value);
}

static inline ButtonContainer::iterator FindButton(Qt::MouseButton value)
{
KeyContainer::iterator it = sg_keyInstances.begin();
KeyContainer::iterator end = sg_keyInstances.end();
while (it != end)
return std::find(sg_buttonInstances.begin(), sg_buttonInstances.end(), value);
}

template <typename TPair>
static inline void UpdateStates(TPair &instance)
{
switch (instance.second)
{
if (it->first == k)
return it;
++it;
case QInput::InputRegistered:
instance.second = QInput::InputTriggered;
break;
case QInput::InputTriggered:
instance.second = QInput::InputPressed;
break;
case QInput::InputUnregistered:
instance.second = QInput::InputReleased;
break;
default:
break;
}
return it;
}

template <typename TPair>
static inline bool CheckReleased(const TPair &instance)
{
return instance.second == QInput::InputReleased;
}

template <typename Container>
static inline void Update(Container &container)
{
typedef typename Container::iterator Iter;
typedef typename Container::value_type TPair;

// Remove old data
Iter remove = std::remove_if(container.begin(), container.end(), &CheckReleased<TPair>);
container.erase(remove, container.end());

// Update existing data
std::for_each(container.begin(), container.end(), &UpdateStates<TPair>);
}

/*******************************************************************************
* QInput Implementation
******************************************************************************/
QInput::KeyState QInput::keyState(Qt::Key k)
QInput::InputState QInput::keyState(Qt::Key k)
{
KeyContainer::iterator it = FindKey(k);
return (it != sg_keyInstances.end()) ? it->second : KeyInvalid;
return (it != sg_keyInstances.end()) ? it->second : InputInvalid;
}

QInput::InputState QInput::buttonState(Qt::MouseButton k)
{
ButtonContainer::iterator it = FindButton(k);
return (it != sg_buttonInstances.end()) ? it->second : InputInvalid;
}

QPoint QInput::mousePosition()
{
return QCursor::pos();
}

QPoint QInput::mouseDelta()
{
return sg_mouseDelta;
}

void QInput::update()
{
for (KeyContainer::iterator it = sg_keyInstances.begin(); it != sg_keyInstances.end();)
{
switch (it->second)
{
case KeyTriggered:
it->second = KeyPressed;
++it;
break;
case KeyReleased:
it = sg_keyInstances.erase(it);
break;
default:
++it;
break;
}
}
// Update Mouse Delta
sg_mousePrevPosition = sg_mouseCurrPosition;
sg_mouseCurrPosition = QCursor::pos();
sg_mouseDelta = sg_mouseCurrPosition - sg_mousePrevPosition;

// Update KeyState values
Update(sg_buttonInstances);
Update(sg_keyInstances);
}

void QInput::registerKeyPress(int k)
{
sg_keyInstances.push_back(KeyInstance(k, KeyTriggered));
KeyContainer::iterator it = FindKey((Qt::Key)k);
if (it == sg_keyInstances.end())
{
sg_keyInstances.push_back(KeyInstance((Qt::Key)k, InputRegistered));
}
}

void QInput::registerKeyRelease(int k)
{
KeyContainer::iterator it = FindKey((Qt::Key)k);
if (it != sg_keyInstances.end())
{
it->second = KeyReleased;
it->second = InputUnregistered;
}
}

void QInput::registerMousePress(Qt::MouseButton btn)
{
ButtonContainer::iterator it = FindButton(btn);
if (it == sg_buttonInstances.end())
{
sg_buttonInstances.push_back(ButtonInstance(btn, InputRegistered));
}
}

void QInput::registerMouseRelease(Qt::MouseButton btn)
{
ButtonContainer::iterator it = FindButton(btn);
if (it != sg_buttonInstances.end())
{
it->second = InputUnregistered;
}
}

void QInput::reset()
{
sg_keyInstances.clear();
sg_buttonInstances.clear();
}
44 changes: 35 additions & 9 deletions 3a_EfficientInputManager/ProfileApplication/Instances/QInput.h
Expand Up @@ -2,47 +2,73 @@
#define QINPUT_H

#include <Qt>
#include <QPoint>

class QInput
{
public:

// Possible key states
enum KeyState
enum InputState
{
KeyInvalid,
KeyTriggered,
KeyPressed,
KeyReleased
InputInvalid,
InputRegistered,
InputUnregistered,
InputTriggered,
InputPressed,
InputReleased
};

// State checking
static KeyState keyState(Qt::Key k);
static InputState keyState(Qt::Key k);
static bool keyTriggered(Qt::Key k);
static bool keyPressed(Qt::Key k);
static bool keyReleased(Qt::Key k);
static InputState buttonState(Qt::MouseButton k);
static bool buttonTriggered(Qt::MouseButton k);
static bool buttonPressed(Qt::MouseButton k);
static bool buttonReleased(Qt::MouseButton k);
static QPoint mousePosition();
static QPoint mouseDelta();

// State updating
static void update();
static void registerKeyPress(int k);
static void registerKeyRelease(int k);
static void registerMousePress(Qt::MouseButton btn);
static void registerMouseRelease(Qt::MouseButton btn);
static void reset();
friend class Window;
};

inline bool QInput::keyTriggered(Qt::Key k)
{
return keyState(k) == KeyTriggered;
return keyState(k) == InputTriggered;
}

inline bool QInput::keyPressed(Qt::Key k)
{
return keyState(k) == KeyPressed;
return keyState(k) == InputPressed;
}

inline bool QInput::keyReleased(Qt::Key k)
{
return keyState(k) == KeyReleased;
return keyState(k) == InputReleased;
}

inline bool QInput::buttonTriggered(Qt::MouseButton k)
{
return buttonState(k) == InputTriggered;
}

inline bool QInput::buttonPressed(Qt::MouseButton k)
{
return buttonState(k) == InputPressed;
}

inline bool QInput::buttonReleased(Qt::MouseButton k)
{
return buttonState(k) == InputReleased;
}

#endif // QINPUT_H

0 comments on commit 022a4d6

Please sign in to comment.