This commit is contained in:
Lendemor 2016-03-08 20:03:57 +01:00
commit da406827b1
8 changed files with 439 additions and 448 deletions

View File

@ -1,53 +1,15 @@
project(SparrowInput)
cmake_minimum_required(VERSION 2.8)
if(WIN32)
set(SYSTEM_LIB_PATH "win32")
else(WIN32)
set(SYSTEM_LIB_PATH "linux")
endif(WIN32)
# choose source file
file(GLOB LIB_SRC_LIST src/*.cpp)
file(GLOB LIB_HEAD_LIST src/*.h)
list(REMOVE_ITEM LIB_SRC_LIST src/main.cpp)
set(EXEC_SRC_LIST src/main.cpp)
set(LIB_SRC_LIST input.cpp keybindings.cpp textbuffer.cpp)
#set compilation option
set(IS_LIBRARY True)
set(USE_OPENGL True)
set(USE_SFML True)
set(EXECUTABLE_NAME "test${PROJECT_NAME}")
set(LIBRARY_NAME ${PROJECT_NAME})
set(DEPENDENCIES_ROOT ${PROJECT_SOURCE_DIR}/../cpp_dependencies)
set(INCLUDE_ROOT ${DEPENDENCIES_ROOT}/include)
set(LIB_ROOT ${DEPENDENCIES_ROOT}/lib/${SYSTEM_LIB_PATH})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_ROOT}) #for SHARED
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_ROOT}) #for STATIC
add_library(${LIBRARY_NAME} STATIC ${LIB_SRC_LIST})
add_executable(${EXECUTABLE_NAME} main.cpp)
add_definitions(-std=c++11)
include_directories(
${INCLUDE_ROOT}
)
find_library(SFML_LIBRARY_WINDOW
NAMES
sfml-window
PATHS
${LIB_ROOT}
)
find_library(SFML_LIBRARY_SYSTEM
NAMES
sfml-system
PATHS
${LIB_ROOT}
)
target_link_libraries(
${LIBRARY_NAME}
${SFML_LIBRARY_WINDOW}
${SFML_LIBRARY_SYSTEM}
)
target_link_libraries(
${EXECUTABLE_NAME}
${LIBRARY_NAME}
)
include(../cmaketemplate/template.cmake)

View File

@ -1,167 +1,167 @@
/**
* @author: Thomas Brandého
*/
#include "input.h"
#include <iostream>
#include <SFML/Window.hpp>
#include <list>
Input::Input(sf::Window *w): window(w)
{
heldkeys = std::vector<sf::Keyboard::Key>();
action_file = std::queue<int>();
window->setKeyRepeatEnabled(false);
}
void Input::setKeysMap(IKeysMap km){
keysmap = km;
}
void Input::updateEvents(){
sf::Event event;
KeyBindings kb;
char c;
/* reset variables */
closeRequested = false;
hasBeenResized = false;
delta_vertical_scroll = 0;
/* global affectation */
kb = keybindings[current_context];
/* event-parsing loop */
while(window->pollEvent(event)){
switch(event.type){
case sf::Event::Closed:
closeRequested = true;
break;
case sf::Event::TextEntered:
c = (char) event.text.unicode;
buffer.append(&c);
break;
case sf::Event::KeyPressed:
action_file.push(kb.getPressedAction(event.key.code));
heldkeys.push_back(event.key.code);
break;
case sf::Event::KeyReleased:
action_file.push(kb.getReleasedAction(event.key.code));
releaseHeldKeys(event.key.code);
break;
case sf::Event::MouseButtonPressed:
action_file.push(kb.getPressedAction(sf::Keyboard::KeyCount + event.mouseButton.button));
heldkeys.push_back((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button));
break;
case sf::Event::MouseButtonReleased:
action_file.push(kb.getReleasedAction(sf::Keyboard::KeyCount + event.mouseButton.button));
releaseHeldKeys((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button));
break;
case sf::Event::MouseWheelScrolled:
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
delta_vertical_scroll = event.mouseWheelScroll.delta;
break;
case sf::Event::MouseMoved:
last_mouse_position = mouse_position;
mouse_position = sf::Mouse::getPosition();
break;
case sf::Event::MouseEntered:
// action MouseEntered
break;
case sf::Event::MouseLeft:
//action MouseLeft
break;
case sf::Event::Resized:
hasBeenResized = true;
break;
}
}
for (auto key: heldkeys){
action_file.push(kb.getHoldAction(key));
}
}
int Input::getAction()
{
if (action_file.empty())
return -1;
int val = action_file.front();
action_file.pop();
return val;
}
/* context-related functions */
void Input::addContext(Context context)
{
contexts.push_back(context);
}
void Input::setCurrentContext(std::string context_name){
current_context = context_name;
}
void Input::updateKeyBindings(){
keybindings.clear();
for (auto iter= contexts.begin(); iter != contexts.end(); ++iter)
keybindings[iter->getName()]= KeyBindings(*iter,keysmap);
}
/* window-related function */
bool Input::isCloseRequested() const
{
return closeRequested;
}
bool Input::isResized() const
{
return hasBeenResized;
}
/* keyboard-related functions */
bool Input::isKeyPressed(int key) const
{
return sf::Keyboard::isKeyPressed((sf::Keyboard::Key) key);
}
void Input::releaseHeldKeys(sf::Keyboard::Key keycode){
auto iter = heldkeys.begin();
while(*iter != keycode) ++iter;
heldkeys.erase(iter);
}
/* mouse-related functions */
sf::Vector2i Input::getPosition() const
{
return mouse_position;
}
sf::Vector2i Input::getDeltaPosition() const
{
return mouse_position - last_mouse_position;
}
float Input::getDeltaVerticalScroll() const
{
return delta_vertical_scroll;
}
/* ------ */
void Input::test()
{
KeyBindings kb = keybindings[current_context];
int action;
action = kb.getPressedAction(sf::Keyboard::I);
if (action != NO_ACTION)
std::cerr << action << std::endl;
action = kb.getPressedAction(sf::Keyboard::O);
if (action != NO_ACTION)
std::cerr << action << std::endl;
}
/**
* @author: Thomas Brandého
*/
#include "input.h"
#include <iostream>
#include <SFML/Window.hpp>
#include <list>
Input::Input(sf::Window *w): window(w)
{
heldkeys = std::vector<sf::Keyboard::Key>();
action_file = std::queue<int>();
window->setKeyRepeatEnabled(false);
}
void Input::setKeysMap(IKeysMap km){
keysmap = km;
}
void Input::updateEvents(){
sf::Event event;
KeyBindings kb;
char c;
/* reset variables */
closeRequested = false;
hasBeenResized = false;
delta_vertical_scroll = 0;
/* global affectation */
kb = keybindings[current_context];
/* event-parsing loop */
while(window->pollEvent(event)){
switch(event.type){
case sf::Event::Closed:
closeRequested = true;
break;
case sf::Event::TextEntered:
c = (char) event.text.unicode;
buffer.append(&c);
break;
case sf::Event::KeyPressed:
action_file.push(kb.getPressedAction(event.key.code));
heldkeys.push_back(event.key.code);
break;
case sf::Event::KeyReleased:
action_file.push(kb.getReleasedAction(event.key.code));
releaseHeldKeys(event.key.code);
break;
case sf::Event::MouseButtonPressed:
action_file.push(kb.getPressedAction(sf::Keyboard::KeyCount + event.mouseButton.button));
heldkeys.push_back((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button));
break;
case sf::Event::MouseButtonReleased:
action_file.push(kb.getReleasedAction(sf::Keyboard::KeyCount + event.mouseButton.button));
releaseHeldKeys((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button));
break;
case sf::Event::MouseWheelScrolled:
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
delta_vertical_scroll = event.mouseWheelScroll.delta;
break;
case sf::Event::MouseMoved:
last_mouse_position = mouse_position;
mouse_position = sf::Mouse::getPosition();
break;
case sf::Event::MouseEntered:
// action MouseEntered
break;
case sf::Event::MouseLeft:
//action MouseLeft
break;
case sf::Event::Resized:
hasBeenResized = true;
break;
}
}
for (auto key: heldkeys){
action_file.push(kb.getHoldAction(key));
}
}
int Input::getAction()
{
if (action_file.empty())
return -1;
int val = action_file.front();
action_file.pop();
return val;
}
/* context-related functions */
void Input::addContext(Context context)
{
contexts.push_back(context);
}
void Input::setCurrentContext(std::string context_name){
current_context = context_name;
}
void Input::updateKeyBindings(){
keybindings.clear();
for (auto iter= contexts.begin(); iter != contexts.end(); ++iter)
keybindings[iter->getName()]= KeyBindings(*iter,keysmap);
}
/* window-related function */
bool Input::isCloseRequested() const
{
return closeRequested;
}
bool Input::isResized() const
{
return hasBeenResized;
}
/* keyboard-related functions */
bool Input::isKeyPressed(int key) const
{
return sf::Keyboard::isKeyPressed((sf::Keyboard::Key) key);
}
void Input::releaseHeldKeys(sf::Keyboard::Key keycode){
auto iter = heldkeys.begin();
while(*iter != keycode) ++iter;
heldkeys.erase(iter);
}
/* mouse-related functions */
sf::Vector2i Input::getPosition() const
{
return mouse_position;
}
sf::Vector2i Input::getDeltaPosition() const
{
return mouse_position - last_mouse_position;
}
float Input::getDeltaVerticalScroll() const
{
return delta_vertical_scroll;
}
/* ------ */
void Input::test()
{
KeyBindings kb = keybindings[current_context];
int action;
action = kb.getPressedAction(sf::Keyboard::I);
if (action != NO_ACTION)
std::cerr << action << std::endl;
action = kb.getPressedAction(sf::Keyboard::O);
if (action != NO_ACTION)
std::cerr << action << std::endl;
}

View File

@ -1,75 +1,75 @@
/**
* @author: Thomas Brandého
*/
#ifndef INPUT_H
#define INPUT_H
#include "keybindings.h"
#include <queue>
#include <vector>
#include <unordered_map>
#include "textbuffer.h"
class Input{
public:
/* Constructors */
Input(sf::Window *w);
/* general action-mapping functions */
void setKeysMap(IKeysMap km);
void updateEvents();
int getAction();
/* context-related functions */
void addContext(Context context);
void setCurrentContext(std::string context_name);
void updateKeyBindings();
/* window-related function */
bool isCloseRequested() const;
bool isResized() const;
/* keyboard-related functions */
bool isKeyPressed(int key) const;
/* mouse-related function */
sf::Vector2i getPosition() const;
sf::Vector2i getDeltaPosition() const;
float getDeltaVerticalScroll() const;
/* text-related function */
std::string getText();
void test();
private:
/* window-related variables */
sf::Window* window;
bool closeRequested;
bool hasBeenResized;
/* general action-mapping variables */
IKeysMap keysmap;
std::queue<int> action_file;
int nb_actions;
/* context-related variables */
std::string current_context;
//std::unordered_map<std::string, std::vector<int>> contexts;
std::vector<Context> contexts;
std::unordered_map<std::string,KeyBindings> keybindings;
/* keyboard-related variables */
std::vector<sf::Keyboard::Key> heldkeys;
void releaseHeldKeys(sf::Keyboard::Key keycode);
/* mouse-related variables */
sf::Vector2i mouse_position;
sf::Vector2i last_mouse_position;
float delta_vertical_scroll;
/* text-related variable */
std::string buffer;
};
#endif //INPUT_H
/**
* @author: Thomas Brandého
*/
#ifndef INPUT_H
#define INPUT_H
#include "keybindings.h"
#include <queue>
#include <vector>
#include <unordered_map>
#include "textbuffer.h"
class Input{
public:
/* Constructors */
Input(sf::Window *w);
/* general action-mapping functions */
void setKeysMap(IKeysMap km);
void updateEvents();
int getAction();
/* context-related functions */
void addContext(Context context);
void setCurrentContext(std::string context_name);
void updateKeyBindings();
/* window-related function */
bool isCloseRequested() const;
bool isResized() const;
/* keyboard-related functions */
bool isKeyPressed(int key) const;
/* mouse-related function */
sf::Vector2i getPosition() const;
sf::Vector2i getDeltaPosition() const;
float getDeltaVerticalScroll() const;
/* text-related function */
std::string getText();
void test();
private:
/* window-related variables */
sf::Window* window;
bool closeRequested;
bool hasBeenResized;
/* general action-mapping variables */
IKeysMap keysmap;
std::queue<int> action_file;
int nb_actions;
/* context-related variables */
std::string current_context;
//std::unordered_map<std::string, std::vector<int>> contexts;
std::vector<Context> contexts;
std::unordered_map<std::string,KeyBindings> keybindings;
/* keyboard-related variables */
std::vector<sf::Keyboard::Key> heldkeys;
void releaseHeldKeys(sf::Keyboard::Key keycode);
/* mouse-related variables */
sf::Vector2i mouse_position;
sf::Vector2i last_mouse_position;
float delta_vertical_scroll;
/* text-related variable */
std::string buffer;
};
#endif //INPUT_H

View File

@ -1,101 +1,130 @@
/**
* @author: Thomas Brandého
*/
#include "keybindings.h"
#include <iostream>
/* Implementation of IKeysMap class
* @author: Thomas Brandého
* @info: This class register all the association between key and action.
*/
IKeysMap::IKeysMap()
{
}
std::vector<Binding> IKeysMap::getBindings(int action) const {
std::vector<Binding> bindings;
for (auto binding : keys)
if (binding.action == action) bindings.push_back(binding);
return bindings;
}
/* Implementation of KeyBindings class
* @author: Thomas Brandého
* @info: This class map a list of action with the associated keys, for a quick access in-game.
* The map is read-only, so if you want to add of remove action from the map, you have to create a new instance of KeyBindings
*/
KeyBindings::KeyBindings()
{
}
KeyBindings::KeyBindings(const Context &context, const IKeysMap &keysmap)
{
std::vector<int> actions = context.getActions();
for (int action : actions){
for (Binding binding : keysmap.getBindings(action)){
switch(binding.type){
case IKeysMap::PRESSED:
setPressedAction(binding.key,binding.action);
break;
case IKeysMap::RELEASED:
setReleasedAction(binding.key,binding.action);
break;
case IKeysMap::HOLD:
setHoldAction(binding.key,binding.action);
break;
default:
//raiseError;
break;
}
}
}
}
int KeyBindings::getPressedAction(int key) const
{
return bindings_pressed.count(key) == 1? bindings_pressed.at(key) : -1;
}
int KeyBindings::getReleasedAction(int key) const
{
return bindings_released.count(key) == 1? bindings_released.at(key) : -1;
}
int KeyBindings::getHoldAction(int key) const
{
return bindings_hold.count(key) == 1? bindings_hold.at(key) : -1;
}
void KeyBindings::setPressedAction(int key, int action)
{
bindings_pressed[key]=action;
}
void KeyBindings::setReleasedAction(int key, int action)
{
bindings_released[key]=action;
}
void KeyBindings::setHoldAction(int key, int action)
{
bindings_hold[key]=action;
}
/* Implementation of Context class
* @author: Thomas Brandého
* @info: This class contains a list of actions available in a given situation (context).
*/
Context::Context(std::string _name, std::vector<int> _actions): name(_name), actions(_actions)
{
}
std::string Context::getName()
{
return name;
}
std::vector<int> Context::getActions() const
{
return actions;
}
/**
* @author: Thomas Brandého
*/
#include "keybindings.h"
#include <iostream>
/* Implementation of IKeysMap class
* @author: Thomas Brandého
* @info: This class register all the association between key and action.
*/
IKeysMap::IKeysMap()
{
}
std::vector<Binding> IKeysMap::getBindings(int action) const {
std::vector<Binding> bindings;
for (auto binding : keys)
if (binding.action == action) bindings.push_back(binding);
return bindings;
}
/* Implementation of KeyBindings class
* @author: Thomas Brandého
* @info: This class map a list of action with the associated keys, for a quick access in-game.
* The map is read-only, so if you want to add of remove action from the map, you have to create a new instance of KeyBindings
*/
KeyBindings::KeyBindings()
{
}
KeyBindings::KeyBindings(const Context &context, const IKeysMap &keysmap)
{
std::vector<int> actions = context.getActions();
for (int action : actions){
for (Binding binding : keysmap.getBindings(action)){
switch(binding.type){
case IKeysMap::PRESSED:
setPressedAction(binding.key,binding.action);
break;
case IKeysMap::RELEASED:
setReleasedAction(binding.key,binding.action);
break;
case IKeysMap::HOLD:
setHoldAction(binding.key,binding.action);
break;
default:
//raiseError;
break;
}
}
}
}
int KeyBindings::getPressedAction(int key) const
{
return bindings_pressed.count(key) == 1? bindings_pressed.at(key) : -1;
}
int KeyBindings::getReleasedAction(int key) const
{
return bindings_released.count(key) == 1? bindings_released.at(key) : -1;
}
int KeyBindings::getHoldAction(int key) const
{
return bindings_hold.count(key) == 1? bindings_hold.at(key) : -1;
}
void KeyBindings::setPressedAction(int key, int action)
{
bindings_pressed[key]=action;
}
void KeyBindings::setReleasedAction(int key, int action)
{
bindings_released[key]=action;
}
void KeyBindings::setHoldAction(int key, int action)
{
bindings_hold[key]=action;
}
/* Implementation of Context class
* @author: Thomas Brandého
* @info: This class contains a list of actions available in a given situation (context).
*/
Context::Context(std::string _name, std::vector<int> _actions): name(_name), actions(_actions)
{
}
std::string Context::getName()
{
return name;
}
std::vector<int> Context::getActions() const
{
return actions;
}

View File

@ -1,57 +1,57 @@
/**
* @author: Thomas Brandého
*/
#ifndef KEYBINDINGS_H
#define KEYBINDINGS_H
#include <SFML/Window.hpp>
#include <unordered_map>
#define NO_KEY -1
#define NO_ACTION -1
struct Binding{
int action;
int key;
int type;
};
class IKeysMap{
public:
enum {PRESSED, RELEASED, HOLD};
IKeysMap();
std::vector<Binding> getBindings(int action) const;
protected:
std::vector<Binding> keys;
};
class Context {
public:
Context(std::string name, std::vector<int> actions);
std::string getName();
std::vector<int> getActions() const;
private:
std::string name;
std::vector<int> actions;
};
class KeyBindings {
public:
KeyBindings();
KeyBindings(const Context &context, const IKeysMap &keysmap);
int getPressedAction(int key) const;
int getReleasedAction(int key) const;
int getHoldAction(int key) const;
private:
std::unordered_map<int,int> bindings_pressed;
std::unordered_map<int,int> bindings_released;
std::unordered_map<int,int> bindings_hold;
void setPressedAction(int key, int action);
void setReleasedAction(int key, int action);
void setHoldAction(int key, int action);
};
#endif
/**
* @author: Thomas Brandého
*/
#ifndef KEYBINDINGS_H
#define KEYBINDINGS_H
#include <SFML/Window.hpp>
#include <unordered_map>
#define NO_KEY -1
#define NO_ACTION -1
struct Binding{
int action;
int key;
int type;
};
class IKeysMap{
public:
enum {PRESSED, RELEASED, HOLD};
IKeysMap();
std::vector<Binding> getBindings(int action) const;
protected:
std::vector<Binding> keys;
};
class Context {
public:
Context(std::string name, std::vector<int> actions);
std::string getName();
std::vector<int> getActions() const;
private:
std::string name;
std::vector<int> actions;
};
class KeyBindings {
public:
KeyBindings();
KeyBindings(const Context &context, const IKeysMap &keysmap);
int getPressedAction(int key) const;
int getReleasedAction(int key) const;
int getHoldAction(int key) const;
private:
std::unordered_map<int,int> bindings_pressed;
std::unordered_map<int,int> bindings_released;
std::unordered_map<int,int> bindings_hold;
void setPressedAction(int key, int action);
void setReleasedAction(int key, int action);
void setHoldAction(int key, int action);
};
#endif