Moved CycleKeySequence into separate class instead of having it bundled with CycleKeyButtonEvent, removed CycleKeyRefButtonEvent, stuck issues when multiple buttons are pressed is still present
This commit is contained in:
parent
adf08a7fff
commit
bf0ecd49a2
7 changed files with 138 additions and 278 deletions
9
TODO
9
TODO
|
@ -70,6 +70,15 @@ Stuff to do before 0.8.1 release:
|
|||
* cycle-key is incomplete, should have additional mode that allows
|
||||
next/prev without sending events, also has issues with stuck buttons
|
||||
when multiple keys are pressed
|
||||
|
||||
-> only one key should be allowed to be pressed, last one will always be released (still fishy)
|
||||
-> separate last and curr key to allow toggle without press
|
||||
-> have each ButtonEvent be responsible to release the keys it
|
||||
pressed? -> tricky, as it doesn't know those right now
|
||||
|
||||
-> need a time delay before button is actually send for situations
|
||||
where sending the key is expensive (weapon switching in game might be slow)
|
||||
|
||||
|
||||
* don't compile tests by default
|
||||
|
||||
|
|
|
@ -11,4 +11,8 @@ Y1=ABS_Y
|
|||
RB=cycle-key-named:foo:JS_1:JS_2:JS_3:JS_4
|
||||
LB=cycle-key-ref:foo:backward
|
||||
|
||||
X=cycle-key-ref:foo:backward:0
|
||||
B=cycle-key-ref:foo:forward:0
|
||||
A=cycle-key-ref:foo:none:1
|
||||
|
||||
# EOF #
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "buttonevent/abs_button_event_handler.hpp"
|
||||
#include "buttonevent/cycle_key_button_event_handler.hpp"
|
||||
#include "buttonevent/cycle_key_ref_button_event_handler.hpp"
|
||||
#include "buttonevent/exec_button_event_handler.hpp"
|
||||
#include "buttonevent/key_button_event_handler.hpp"
|
||||
#include "buttonevent/macro_button_event_handler.hpp"
|
||||
|
@ -109,7 +108,7 @@ ButtonEvent::from_string(const std::string& str, const std::string& directory)
|
|||
}
|
||||
else if (token == "cycle-key-ref")
|
||||
{
|
||||
return ButtonEvent::create(CycleKeyRefButtonEventHandler::from_string(rest));
|
||||
return ButtonEvent::create(CycleKeyButtonEventHandler::from_string_ref(rest));
|
||||
}
|
||||
else if (token == "exec")
|
||||
{
|
||||
|
|
|
@ -20,12 +20,36 @@
|
|||
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#include "ui_event_sequence.hpp"
|
||||
#include "raise_exception.hpp"
|
||||
|
||||
std::map<std::string, CycleKeyButtonEventHandler*> CycleKeyButtonEventHandler::s_lookup_table;
|
||||
std::map<std::string, CycleKeySequencePtr> CycleKeyButtonEventHandler::s_lookup_table;
|
||||
|
||||
namespace {
|
||||
|
||||
CycleKeyButtonEventHandler::Direction
|
||||
direction_from_string(const std::string& value)
|
||||
{
|
||||
if (value == "forward")
|
||||
{
|
||||
return CycleKeyButtonEventHandler::kForward;
|
||||
}
|
||||
else if (value == "backward")
|
||||
{
|
||||
return CycleKeyButtonEventHandler::kBackward;
|
||||
}
|
||||
else if (value == "none")
|
||||
{
|
||||
return CycleKeyButtonEventHandler::kNone;
|
||||
}
|
||||
else
|
||||
{
|
||||
raise_exception(std::runtime_error, "allowed values are 'forward', 'backward' and 'none'");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CycleKeyButtonEventHandler*
|
||||
CycleKeyButtonEventHandler::from_string(const std::string& value)
|
||||
|
@ -46,16 +70,9 @@ CycleKeyButtonEventHandler::from_string_named(const std::string& value)
|
|||
}
|
||||
else
|
||||
{
|
||||
Keys keys;
|
||||
|
||||
std::string name = args[0];
|
||||
for(std::vector<std::string>::const_iterator i = args.begin()+1; i != args.end(); ++i)
|
||||
{
|
||||
keys.push_back(UIEventSequence::from_string(*i));
|
||||
}
|
||||
CycleKeySequencePtr sequence = CycleKeySequence::from_range(args.begin()+1, args.end());
|
||||
|
||||
std::auto_ptr<CycleKeyButtonEventHandler> cycle(new CycleKeyButtonEventHandler(keys));
|
||||
|
||||
// if name is empty, don't put it in the lookup table
|
||||
if (!name.empty())
|
||||
{
|
||||
|
@ -63,21 +80,52 @@ CycleKeyButtonEventHandler::from_string_named(const std::string& value)
|
|||
{
|
||||
raise_exception(std::runtime_error, "duplicate name entry");
|
||||
}
|
||||
|
||||
s_lookup_table.insert(std::pair<std::string, CycleKeyButtonEventHandler*>(name, cycle.get()));
|
||||
else
|
||||
{
|
||||
s_lookup_table.insert(std::pair<std::string, CycleKeySequencePtr>(name, sequence));
|
||||
}
|
||||
}
|
||||
|
||||
return cycle.release();
|
||||
return new CycleKeyButtonEventHandler(sequence, kForward, true);
|
||||
}
|
||||
}
|
||||
|
||||
CycleKeyButtonEventHandler*
|
||||
CycleKeyButtonEventHandler::from_string_ref(const std::string& value)
|
||||
{
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
tokenizer tokens(value, boost::char_separator<char>(":", "", boost::keep_empty_tokens));
|
||||
std::vector<std::string> args(tokens.begin(), tokens.end());
|
||||
|
||||
if (args.size() > 0)
|
||||
{
|
||||
std::string name = args[0];
|
||||
Direction direction = (args.size() > 1) ? direction_from_string(args[1]) : kBackward;
|
||||
bool press = (args.size() > 2) ? boost::lexical_cast<bool>(args[2]) : true;
|
||||
|
||||
CycleKeySequencePtr cycle_sequence = CycleKeyButtonEventHandler::lookup(name);
|
||||
if (!cycle_sequence)
|
||||
{
|
||||
raise_exception(std::runtime_error, "unknown cycle sequence: " << name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CycleKeyButtonEventHandler(cycle_sequence, direction, press);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
raise_exception(std::runtime_error, "need at least one arguments");
|
||||
}
|
||||
}
|
||||
|
||||
CycleKeySequencePtr
|
||||
CycleKeyButtonEventHandler::lookup(const std::string& name)
|
||||
{
|
||||
std::map<std::string, CycleKeyButtonEventHandler*>::iterator it = s_lookup_table.find(name);
|
||||
std::map<std::string, CycleKeySequencePtr>::iterator it = s_lookup_table.find(name);
|
||||
if (it == s_lookup_table.end())
|
||||
{
|
||||
return 0;
|
||||
return CycleKeySequencePtr();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -85,20 +133,20 @@ CycleKeyButtonEventHandler::lookup(const std::string& name)
|
|||
}
|
||||
}
|
||||
|
||||
CycleKeyButtonEventHandler::CycleKeyButtonEventHandler(const Keys& keys) :
|
||||
m_keys(keys),
|
||||
m_current_key(keys.size()-1)
|
||||
CycleKeyButtonEventHandler::CycleKeyButtonEventHandler(CycleKeySequencePtr sequence,
|
||||
Direction direction,
|
||||
bool send_press) :
|
||||
m_sequence(sequence),
|
||||
m_direction(direction),
|
||||
m_send_press(send_press)
|
||||
{
|
||||
assert(!keys.empty());
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyButtonEventHandler::init(UInput& uinput, int slot, bool extra_devices)
|
||||
{
|
||||
for(Keys::iterator i = m_keys.begin(); i != m_keys.end(); ++i)
|
||||
{
|
||||
i->init(uinput, slot, extra_devices);
|
||||
}
|
||||
// CycleKeySequence will make sure that init() is only called once
|
||||
m_sequence->init(uinput, slot, extra_devices);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -106,52 +154,46 @@ CycleKeyButtonEventHandler::send(UInput& uinput, bool value)
|
|||
{
|
||||
if (value)
|
||||
{
|
||||
next_key();
|
||||
send_only(uinput, value);
|
||||
if (m_send_press && m_sequence->has_current_key())
|
||||
{
|
||||
m_sequence->send(uinput, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(m_direction)
|
||||
{
|
||||
case kBackward:
|
||||
m_sequence->prev_key();
|
||||
break;
|
||||
|
||||
case kForward:
|
||||
m_sequence->next_key();
|
||||
break;
|
||||
|
||||
case kNone:
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_send_press)
|
||||
{
|
||||
m_sequence->send(uinput, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
send_only(uinput, value);
|
||||
if (m_send_press)
|
||||
{
|
||||
m_sequence->send(uinput, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyButtonEventHandler::send_only(UInput& uinput, bool value)
|
||||
{
|
||||
m_keys[m_current_key].send(uinput, value);
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyButtonEventHandler::update(UInput& uinput, int msec_delta)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyButtonEventHandler::next_key()
|
||||
{
|
||||
if (m_current_key >= static_cast<int>(m_keys.size())-1)
|
||||
{
|
||||
m_current_key = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_key += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyButtonEventHandler::prev_key()
|
||||
{
|
||||
if (m_current_key <= 0)
|
||||
{
|
||||
m_current_key = m_keys.size()-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_key -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
CycleKeyButtonEventHandler::str() const
|
||||
{
|
||||
|
|
|
@ -24,33 +24,47 @@
|
|||
#include "button_event.hpp"
|
||||
#include "ui_event_sequence.hpp"
|
||||
|
||||
#include "buttonevent/cycle_key_sequence.hpp"
|
||||
|
||||
class CycleKeyButtonEventHandler : public ButtonEventHandler
|
||||
{
|
||||
private:
|
||||
static std::map<std::string, CycleKeyButtonEventHandler*> s_lookup_table;
|
||||
static std::map<std::string, CycleKeySequencePtr> s_lookup_table;
|
||||
|
||||
public:
|
||||
static CycleKeyButtonEventHandler* from_string(const std::string& str);
|
||||
static CycleKeyButtonEventHandler* from_string_named(const std::string& str);
|
||||
static CycleKeyButtonEventHandler* lookup(const std::string& name);
|
||||
|
||||
/**
|
||||
Syntax: "{direction}:{press}"
|
||||
|
||||
direction: can either be 'forward', 'backward', 'none' or an
|
||||
integer, in the case of an integer, the pointer is moved to that key
|
||||
|
||||
press: a bool, true if a keypress is send,
|
||||
false when only the current key should change
|
||||
*/
|
||||
static CycleKeyButtonEventHandler* from_string_ref(const std::string& value);
|
||||
|
||||
|
||||
static CycleKeySequencePtr lookup(const std::string& name);
|
||||
|
||||
public:
|
||||
enum Direction { kForward, kBackward, kNone };
|
||||
|
||||
private:
|
||||
typedef std::vector<UIEventSequence> Keys;
|
||||
Keys m_keys;
|
||||
int m_current_key;
|
||||
CycleKeySequencePtr m_sequence;
|
||||
Direction m_direction;
|
||||
bool m_send_press;
|
||||
|
||||
private:
|
||||
CycleKeyButtonEventHandler(const Keys& keys);
|
||||
CycleKeyButtonEventHandler(CycleKeySequencePtr sequence, Direction direction, bool send_press);
|
||||
|
||||
public:
|
||||
void init(UInput& uinput, int slot, bool extra_devices);
|
||||
void send(UInput& uinput, bool value);
|
||||
void send_only(UInput& uinput, bool value);
|
||||
void update(UInput& uinput, int msec_delta);
|
||||
|
||||
void next_key();
|
||||
void prev_key();
|
||||
|
||||
std::string str() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "buttonevent/cycle_key_ref_button_event_handler.hpp"
|
||||
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#include "buttonevent/cycle_key_button_event_handler.hpp"
|
||||
#include "raise_exception.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
CycleKeyRefButtonEventHandler::Direction
|
||||
direction_from_string(const std::string& value)
|
||||
{
|
||||
if (value == "forward")
|
||||
{
|
||||
return CycleKeyRefButtonEventHandler::kForward;
|
||||
}
|
||||
else if (value == "backward")
|
||||
{
|
||||
return CycleKeyRefButtonEventHandler::kBackward;
|
||||
}
|
||||
else if (value == "none")
|
||||
{
|
||||
return CycleKeyRefButtonEventHandler::kNone;
|
||||
}
|
||||
else
|
||||
{
|
||||
raise_exception(std::runtime_error, "allowed values are 'forward', 'backward' and 'none'");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CycleKeyRefButtonEventHandler*
|
||||
CycleKeyRefButtonEventHandler::from_string(const std::string& value)
|
||||
{
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
tokenizer tokens(value, boost::char_separator<char>(":", "", boost::keep_empty_tokens));
|
||||
std::vector<std::string> args(tokens.begin(), tokens.end());
|
||||
|
||||
if (args.size() > 0)
|
||||
{
|
||||
std::string name = args[0];
|
||||
Direction direction = (args.size() > 1) ? direction_from_string(args[1]) : kBackward;
|
||||
bool press = (args.size() > 2) ? boost::lexical_cast<bool>(args[2]) : true;
|
||||
|
||||
CycleKeyButtonEventHandler* cycle = CycleKeyButtonEventHandler::lookup(name);
|
||||
if (!cycle)
|
||||
{
|
||||
raise_exception(std::runtime_error, "need at least one arguments");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CycleKeyRefButtonEventHandler(cycle, direction, press);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
raise_exception(std::runtime_error, "need at least one arguments");
|
||||
}
|
||||
}
|
||||
|
||||
CycleKeyRefButtonEventHandler::CycleKeyRefButtonEventHandler(CycleKeyButtonEventHandler* button_handler,
|
||||
Direction direction,
|
||||
bool press) :
|
||||
m_button_handler(button_handler),
|
||||
m_direction(direction),
|
||||
m_send_press(press)
|
||||
{
|
||||
// FIXME: m_button_handler is just a raw pointer without a well
|
||||
// defined scope, bad idea, should use a boost::weak_ref<> instead
|
||||
// or something like that
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyRefButtonEventHandler::init(UInput& uinput, int slot, bool extra_devices)
|
||||
{
|
||||
// nothing to do, as m_button_handler is doing all the work
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyRefButtonEventHandler::send(UInput& uinput, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
switch(m_direction)
|
||||
{
|
||||
case kBackward:
|
||||
m_button_handler->prev_key();
|
||||
break;
|
||||
|
||||
case kForward:
|
||||
m_button_handler->next_key();
|
||||
break;
|
||||
|
||||
case kNone:
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_send_press)
|
||||
{
|
||||
m_button_handler->send_only(uinput, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_send_press)
|
||||
{
|
||||
m_button_handler->send_only(uinput, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CycleKeyRefButtonEventHandler::update(UInput& uinput, int msec_delta)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
CycleKeyRefButtonEventHandler::str() const
|
||||
{
|
||||
return "cycle-key-ref";
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 Ingo Ruhnke <grumbel@gmx.de>
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_XBOXDRV_BUTTONEVENT_CYCLE_KEY_REF_BUTTON_EVENT_HANDLER_HPP
|
||||
#define HEADER_XBOXDRV_BUTTONEVENT_CYCLE_KEY_REF_BUTTON_EVENT_HANDLER_HPP
|
||||
|
||||
#include "button_event.hpp"
|
||||
|
||||
class CycleKeyButtonEventHandler;
|
||||
|
||||
class CycleKeyRefButtonEventHandler : public ButtonEventHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Syntax: "{direction}:{press}"
|
||||
|
||||
direction: can either be 'forward', 'backward', 'none' or an
|
||||
integer, in the case of an integer, the pointer is moved to that key
|
||||
|
||||
press: a bool, true if a keypress is send,
|
||||
false when only the current key should change
|
||||
*/
|
||||
static CycleKeyRefButtonEventHandler* from_string(const std::string& value);
|
||||
|
||||
public:
|
||||
enum Direction { kForward, kBackward, kNone };
|
||||
|
||||
public:
|
||||
CycleKeyRefButtonEventHandler(CycleKeyButtonEventHandler* button_handler,
|
||||
Direction direction,
|
||||
bool press);
|
||||
|
||||
void init(UInput& uinput, int slot, bool extra_devices);
|
||||
void send(UInput& uinput, bool value);
|
||||
void update(UInput& uinput, int msec_delta);
|
||||
|
||||
std::string str() const;
|
||||
|
||||
private:
|
||||
CycleKeyButtonEventHandler* m_button_handler;
|
||||
Direction m_direction;
|
||||
bool m_send_press;
|
||||
|
||||
private:
|
||||
CycleKeyRefButtonEventHandler(const CycleKeyRefButtonEventHandler&);
|
||||
CycleKeyRefButtonEventHandler& operator=(const CycleKeyRefButtonEventHandler&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Reference in a new issue