From 7ca3fc15ea518c8f8a6a017eb24f11c1d854681e Mon Sep 17 00:00:00 2001 From: Lendemor Date: Tue, 10 Apr 2018 00:26:33 +0200 Subject: [PATCH] input doesn't produce action when imgui has focus (may cause crash; will be fixed soon) --- CMakeLists.txt | 1 + src/input.cpp | 95 ++++++++++++++++++++++++++++++--------------- src/keybindings.cpp | 44 ++++++++++++++++++++- src/keybindings.h | 58 +++++++++++++++++++++++---- src/main.cpp | 18 ++++++--- 5 files changed, 170 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3ee115..c23990f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ set(EXEC_SRC_LIST src/main.cpp) #set compilation option set(IS_LIBRARY True) set(USE_IMGUI True) +set(USE_CEREAL True) set(SFML_MODULES window system) set(CMAKE_TEMPLATE_PATH "../CMakeTemplate") diff --git a/src/input.cpp b/src/input.cpp index 66d1492..a211f50 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -72,6 +72,11 @@ void Input::updateEvents(){ Action action; + + bool focus_on_imgui = ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow); + if(focus_on_imgui) + std::cout << "focused" << std::endl; + /* event-parsing loop */ while(m_window->pollEvent(event)) { @@ -90,52 +95,78 @@ void Input::updateEvents(){ m_mouseGrabbed = m_mouseWasGrabbed; break; case sf::Event::TextEntered: - c = (char) event.text.unicode; - sf::Utf32::encodeAnsi(event.text.unicode,std::back_inserter(m_buffer)); - io.AddInputCharacter(static_cast(event.text.unicode)); + if (focus_on_imgui) + io.AddInputCharacter(static_cast(event.text.unicode)); + else + sf::Utf32::encodeAnsi(event.text.unicode,std::back_inserter(m_buffer)); break; case sf::Event::KeyPressed: - action = kb.getPressedAction(input::KEYBOARD,event.key.code); - if(!action.isNull()) - m_actions.push_back(action); - m_heldKeys.push_back(event.key.code); - io.KeysDown[event.key.code] = true; - io.KeyCtrl = event.key.control; - io.KeyShift = event.key.shift; - io.KeyAlt = event.key.alt; + if(focus_on_imgui) + { + io.KeysDown[event.key.code] = true; + io.KeyCtrl = event.key.control; + io.KeyShift = event.key.shift; + io.KeyAlt = event.key.alt; + } + else + { + action = kb.getPressedAction(input::KEYBOARD,event.key.code); + if(!action.isNull()) + m_actions.push_back(action); + m_heldKeys.push_back(event.key.code); + } break; case sf::Event::KeyReleased: - action = kb.getReleasedAction(input::KEYBOARD,event.key.code); - if(!action.isNull()) - m_actions.push_back(action); - releaseHeldKeys(event.key.code); - io.KeysDown[event.key.code] = false; - io.KeyCtrl = event.key.control; - io.KeyShift = event.key.shift; - io.KeyAlt = event.key.alt; + if (focus_on_imgui) + { + io.KeysDown[event.key.code] = false; + io.KeyCtrl = event.key.control; + io.KeyShift = event.key.shift; + io.KeyAlt = event.key.alt; + } + else + { + action = kb.getReleasedAction(input::KEYBOARD,event.key.code); + if(!action.isNull()) + m_actions.push_back(action); + releaseHeldKeys(event.key.code); + } break; case sf::Event::MouseWheelScrolled: - if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) - m_delta_vertical_scroll = event.mouseWheelScroll.delta; + if (!focus_on_imgui) + { + if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) + m_delta_vertical_scroll = event.mouseWheelScroll.delta; + } break; - case sf::Event::MouseWheelMoved: - io.MouseWheel += static_cast(event.mouseWheel.delta); + case sf::Event::MouseWheelMoved: + if (focus_on_imgui) + io.MouseWheel += static_cast(event.mouseWheel.delta); break; case sf::Event::MouseButtonPressed: - action = kb.getPressedAction(input::MOUSE,event.mouseButton.button); - if(!action.isNull()) - m_actions.push_back(action); - m_heldMouseButtons.push_back(event.mouseButton.button); + if (!focus_on_imgui) + { + action = kb.getPressedAction(input::MOUSE,event.mouseButton.button); + if(!action.isNull()) + m_actions.push_back(action); + m_heldMouseButtons.push_back(event.mouseButton.button); + } break; case sf::Event::MouseButtonReleased: - action = kb.getReleasedAction(input::MOUSE,event.mouseButton.button); - if(!action.isNull()) - m_actions.push_back(action); - releaseHeldMouseButton(event.mouseButton.button); + if(!focus_on_imgui) + { + action = kb.getReleasedAction(input::MOUSE,event.mouseButton.button); + if(!action.isNull()) + m_actions.push_back(action); + releaseHeldMouseButton(event.mouseButton.button); + } break; case sf::Event::MouseMoved: m_mouse_position = sf::Mouse::getPosition(*m_window); - io.MousePos = ImVec2(m_mouse_position.x, m_mouse_position.y); + if (focus_on_imgui) + { + io.MousePos = ImVec2(m_mouse_position.x, m_mouse_position.y); + } break; case sf::Event::MouseEntered: // action MouseEntered diff --git a/src/keybindings.cpp b/src/keybindings.cpp index 9821065..7b25e85 100644 --- a/src/keybindings.cpp +++ b/src/keybindings.cpp @@ -5,6 +5,27 @@ #include "keybindings.h" #include +//#define ACTION_PROPERTY_CODE AbstractProperty::NB_PROPERTY_TYPES + 1000 + +/* Function used for serialization of Action + * + */ +/* +template <> std::ostream& Property::saveBinary(std::ostream& os) +{ + return os.write((char*)&m_value.action, sizeof(Action)); +// return os.write((char*)&m_value.source, sizeof(int)); +// return os.write((char*)&m_value.controller_id, sizeof(int)); +} +template <> std::ostream& Property::saveAscii(std::ostream& os) { return os;}// << m_value; } +template <> std::istream& Property::loadBinary(std::istream& is) { return is.read((char*)&m_value, sizeof(Action)); } +template <> std::istream& Property::loadAscii(std::istream& is) { return is;}// >> m_value; } +template <> AbstractProperty::PropertyType Property::getStaticPropertyType() { return AbstractProperty::REFERENCE; } + +*/ +//INIT_SERIALIZABLE(Action) +//INIT_SERIALIZABLE(Binding) + /* Implementation of IKeysMap class * @author: Thomas Brandého * @info: This class register all the association between key and action. @@ -22,10 +43,29 @@ std::vector IKeysMap::getBindings(Action action) const { return bindings; } -Action Action::getNull(){ - return {NO_ACTION,input::NONE}; +Action Action::getNull() +{ + Action a; + a.action = NO_ACTION; + a.source = input::NONE; + return a; } +Action& Action::operator=(const Action& newAction) +{ + action = newAction.action; + source = newAction.source; + controller_id = newAction.controller_id; +} + +Binding& Binding::operator=(const Binding newBinding) +{ + action = newBinding.action; + key = newBinding.key; + type = newBinding.type; +} + + /* 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. diff --git a/src/keybindings.h b/src/keybindings.h index 65e0f57..732506c 100644 --- a/src/keybindings.h +++ b/src/keybindings.h @@ -7,6 +7,9 @@ #include +#include "SparrowSerializer/serializable.h" +#include + #include #define NO_KEY -1 @@ -18,9 +21,10 @@ enum Controller{BUTTON_A,BUTTON_B,BUTTON_X,BUTTON_Y,BUTTON_LB,BUTTON_RB,BUTTON_S enum Axis{LEFT_JOYSTICK_HORIZONTAL,LEFT_JOYSTICK_VERTICAL,LT_RT,RIGHT_JOYSTICK_VERTICAL,RIGHT_JOYSTICK_HORIZONTAL,DPAD_HORIZONTAL=6,DPAD_VERTICAL}; } -struct Action { +struct Action +{ int action; - input::Source source; + int source; int controller_id; static Action getNull(); bool isNull(){ @@ -29,22 +33,62 @@ struct Action { friend bool operator ==(const Action& action1, const Action& action2){ return (action1.action == action2.action) && (action1.source == action2.source); } + Action& operator=(const Action& newAction); + Action(){} + Action(std::initializer_list c){ + assert(c.size() <= 3); + int array[3]; + std::copy(c.begin(),c.end(),array); + switch (c.size()) { + case 3: + controller_id = array[2]; + case 2: + source = array[1]; + case 1: + action = array[0]; + break; + default: + break; + } + } + + template + void serialize(Archive & archive) + { + archive(action,source,controller_id); + } + + template + void load(Archive & archive) + { + archive >> action >> source >> controller_id; + } }; -struct Binding{ +struct Binding// : public Serializable +{ Action action; - int key; - int type; +// PROPERTY(Action,action) + int key; +// P_INT(key) + int type; +// P_INT(type) + Binding& operator=(const Binding newBinding); + + //SERIALIZABLE(Binding,CAST(action),CAST(key),CAST(type)) }; -class IKeysMap{ +class IKeysMap// : public Serializable +{ public: enum {PRESSED, RELEASED, HOLD}; IKeysMap(); std::vector getBindings(Action action) const; std::vector& data(){return keys;} protected: - std::vector keys; + std::vector keys; +// P_VECTOR_(Binding, keys) +// SERIALIZABLE(IKeysMap,CAST(keys)) }; class Context { diff --git a/src/main.cpp b/src/main.cpp index 9d0caaa..22e3ef3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,7 @@ public: TestKeysMap(){ keys.push_back ({{LEFT_CLICK,input::MOUSE},sf::Mouse::Left,PRESSED} ); keys.push_back ({{RIGHT_CLICK,input::MOUSE},sf::Mouse::Right,PRESSED} ); - keys.push_back ({{ACTION,input::CONTROLLER},sf::Joystick::X,PRESSED} ); + keys.push_back ({{ACTION,input::CONTROLLER},input::Controller::BUTTON_X,PRESSED} ); } static std::vector getTestContext() @@ -36,19 +36,27 @@ int main() myInput.addContext(context); myInput.setCurrentContext("test"); + cereal::JSONOutputArchive output(std::cout); + while(!myInput.isCloseRequested()) { myInput.updateEvents(); for (Action action : myInput.getActions()) { - if (action.action == TestKeysMap::ACTION && action.source == input::CONTROLLER && action.controller_id == 0){ - std::cout << "Controllers connected: " << myInput.getControllersConnected().size(); -// for(auto controller : myInput.getControllersConnected()) - // std::cout << controller << " "; +// if (action.action == TestKeysMap::ACTION && action.source == input::CONTROLLER && action.controller_id == 0){ +// std::cout << "Controllers connected: " << myInput.getControllersConnected().size(); + if(action.action != NO_ACTION){ + output( cereal::make_nvp("data", action) ); std::cout << std::endl; } + // for(auto controller : myInput.getControllersConnected()) + // std::cout << controller << " "; +// + // } } } + + /* IKeysMap* keymap = new IKeysMap("test", 1); // keymap->setKeyBinding(ACTION_2,0,sf::Keyboard::Z);