From 10e3ba43fa30747c7fed3e10bd6083436837f52b Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Sat, 14 Jan 2017 15:15:59 -0800 Subject: [PATCH] Events are now passing correctly, small bug with held keys that needs fixing --- include/Camera.h | 2 +- include/Event.hpp | 105 +++++++++++++++++++++++++++++++++------------- include/Input.h | 18 +++++++- include/Pub_Sub.h | 9 ++-- src/Camera.cpp | 39 ++++++++++++++++- src/Input.cpp | 82 ++++++++++++++++++++++++++++++------ src/Pub_Sub.cpp | 11 ++--- src/main.cpp | 38 +++-------------- 8 files changed, 217 insertions(+), 87 deletions(-) diff --git a/include/Camera.h b/include/Camera.h index f712b4d..da6f6e1 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -35,7 +35,7 @@ public: sf::Vector2f get_direction(); - void update(VrEventPublisher* p, vr::Event e) override; + void recieve_event(VrEventPublisher* p, std::unique_ptr event) override; private: diff --git a/include/Event.hpp b/include/Event.hpp index 3ad1f2e..a21ff53 100644 --- a/include/Event.hpp +++ b/include/Event.hpp @@ -16,8 +16,9 @@ namespace vr { // A result of getting rid of the union and extracting // event types into individual classes is the fact that - // there is going to be a lot of repeat code i.e the - // difference between KeyPressed and KeyReleased + // there is going to be a lot of repeat code i.e + // KeyPressed, KeyHeld, and KeyReleased all hold the same + // data, it's just their names that are different class Event { public: @@ -30,15 +31,18 @@ namespace vr { GainedFocus, TextEntered, KeyPressed, + KeyHeld, KeyReleased, MouseWheelMoved, MouseWheelScrolled, MouseButtonPressed, + MouseButtonHeld, MouseButtonReleased, MouseMoved, MouseEntered, MouseLeft, JoystickButtonPressed, + JoystickButtonHeld, JoystickButtonReleased, JoystickMoved, JoystickConnected, @@ -48,6 +52,7 @@ namespace vr { TouchEnded, SensorChanged, NetworkJoystickButtonPressed, + NetworkJoystickButtonHeld, NetworkJoystickButtonReleased, NetworkJoystickMoved, NetworkJoystickConnected, @@ -72,8 +77,8 @@ namespace vr { public: Resized(unsigned int width, unsigned int height) : width(width), height(height), Event(vr::Event::EventType::Resized) {}; - unsigned int width; - unsigned int height; + unsigned int width; + unsigned int height; }; class LostFocus : public Event { @@ -105,6 +110,18 @@ namespace vr { bool system; }; + class KeyHeld : public Event { + public: + KeyHeld(sf::Keyboard::Key code, bool alt, bool control, bool shift, bool system) : + code(code), alt(alt), control(control), shift(shift), system(system), Event(vr::Event::EventType::KeyHeld) {}; + + sf::Keyboard::Key code; + bool alt; + bool control; + bool shift; + bool system; + }; + class KeyReleased : public Event { public: KeyReleased(sf::Keyboard::Key code, bool alt, bool control, bool shift, bool system) : @@ -144,6 +161,16 @@ namespace vr { int y; }; + class MouseButtonHeld : public Event { + public: + MouseButtonHeld(sf::Mouse::Button button, int x, int y) : + button(button), x(x), y(y), Event(vr::Event::EventType::MouseButtonHeld) {}; + + sf::Mouse::Button button; + int x; + int y; + }; + class MouseButtonReleased : public Event { public: MouseButtonReleased(sf::Mouse::Button button, int x, int y) : @@ -159,8 +186,8 @@ namespace vr { MouseMoved(int x, int y) : x(x), y(y), Event(vr::Event::EventType::MouseMoved) {}; - int x; - int y; + int x; + int y; }; class MouseEntered : public Event { @@ -168,8 +195,8 @@ namespace vr { MouseEntered(int x, int y) : x(x), y(y), Event(vr::Event::EventType::MouseEntered) {}; - int x; - int y; + int x; + int y; }; class MouseLeft : public Event { @@ -177,8 +204,8 @@ namespace vr { MouseLeft(int x, int y) : x(x), y(y), Event(vr::Event::EventType::MouseLeft) {}; - int x; - int y; + int x; + int y; }; class JoystickButtonPressed : public Event { @@ -186,8 +213,17 @@ namespace vr { JoystickButtonPressed(unsigned int joystickId, unsigned int button) : joystickId(joystickId), button(button), Event(vr::Event::EventType::JoystickButtonPressed) {}; - unsigned int joystickId; - unsigned int button; + unsigned int joystickId; + unsigned int button; + }; + + class JoystickButtonHeld : public Event { + public: + JoystickButtonHeld(unsigned int joystickId, unsigned int button) : + joystickId(joystickId), button(button), Event(vr::Event::EventType::JoystickButtonHeld) {}; + + unsigned int joystickId; + unsigned int button; }; class JoystickButtonReleased : public Event { @@ -195,8 +231,8 @@ namespace vr { JoystickButtonReleased(unsigned int joystickId, unsigned int button) : joystickId(joystickId), button(button), Event(vr::Event::EventType::JoystickButtonReleased) {}; - unsigned int joystickId; - unsigned int button; + unsigned int joystickId; + unsigned int button; }; class JoystickMoved : public Event { @@ -214,7 +250,7 @@ namespace vr { JoystickConnected(unsigned int joystickId) : joystickId(joystickId), Event(vr::Event::EventType::JoystickConnected) {}; - unsigned int joystickId; + unsigned int joystickId; }; class JoystickDisconnected : public Event { @@ -222,17 +258,17 @@ namespace vr { JoystickDisconnected(unsigned int joystickId) : joystickId(joystickId), Event(vr::Event::EventType::JoystickDisconnected) {}; - unsigned int joystickId; + unsigned int joystickId; }; class TouchBegan : public Event { public: TouchBegan(unsigned int finger, int x, int y) : finger(finger), x(x), y(y), Event(vr::Event::EventType::TouchBegan) {}; - - unsigned int finger; - int x; - int y; + + unsigned int finger; + int x; + int y; }; class TouchMoved : public Event { @@ -240,9 +276,9 @@ namespace vr { TouchMoved(unsigned int finger, int x, int y) : finger(finger), x(x), y(y), Event(vr::Event::EventType::TouchMoved) {}; - unsigned int finger; - int x; - int y; + unsigned int finger; + int x; + int y; }; class TouchEnded : public Event { @@ -250,9 +286,9 @@ namespace vr { TouchEnded(unsigned int finger, int x, int y) : finger(finger), x(x), y(y), Event(vr::Event::EventType::TouchEnded) {}; - unsigned int finger; - int x; - int y; + unsigned int finger; + int x; + int y; }; class SensorChanged : public Event { @@ -260,10 +296,10 @@ namespace vr { SensorChanged(sf::Sensor::Type type, float x, float y, float z) : type(type), x(x), y(y), z(z), Event(vr::Event::EventType::SensorChanged) {}; - sf::Sensor::Type type; - float x; - float y; - float z; + sf::Sensor::Type type; + float x; + float y; + float z; }; // I'm moving this to it's own event type because @@ -280,6 +316,15 @@ namespace vr { unsigned int button; }; + class NetworkJoystickButtonHeld : public Event { + public: + NetworkJoystickButtonHeld(unsigned int joystickId, unsigned int button) : + joystickId(joystickId), button(button), Event(vr::Event::EventType::NetworkJoystickButtonHeld) {}; + + unsigned int joystickId; + unsigned int button; + }; + class NetworkJoystickButtonReleased : public Event { public: NetworkJoystickButtonReleased(unsigned int joystickId, unsigned int button) : diff --git a/include/Input.h b/include/Input.h index db78179..0ef4249 100644 --- a/include/Input.h +++ b/include/Input.h @@ -18,7 +18,7 @@ public: void consume_sf_events(sf::RenderWindow *window); void consume_vr_events(); - void set_flags(); + void handle_held_keys(); void dispatch_events(); private: @@ -38,3 +38,19 @@ private: std::list> event_queue; }; + +class WindowHandler : public VrEventSubscriber { + +public: + WindowHandler(sf::RenderWindow *window) : window_ref(window) { }; + + virtual void recieve_event(VrEventPublisher* p, std::unique_ptr event) override { + if (event.get()->type == vr::Event::Closed) { + window_ref->close(); + } + }; + +private: + sf::RenderWindow* window_ref; + +}; \ No newline at end of file diff --git a/include/Pub_Sub.h b/include/Pub_Sub.h index 58c9a73..7ea3aaf 100644 --- a/include/Pub_Sub.h +++ b/include/Pub_Sub.h @@ -2,6 +2,7 @@ #include #include #include "Event.hpp" +#include class VrEventPublisher; @@ -9,9 +10,9 @@ class VrEventPublisher; class VrEventSubscriber { public: virtual ~VrEventSubscriber() {}; - virtual void update(VrEventPublisher* p, vr::Event e) = 0; - void subscribe(VrEventPublisher* publisher, vr::Event::EventType type); - void subscribe(VrEventPublisher* publisher, std::vector type); + virtual void recieve_event(VrEventPublisher* publisher, std::unique_ptr event) = 0; + void subscribe_to_publisher(VrEventPublisher* publisher, vr::Event::EventType type); + void subscribe_to_publisher(VrEventPublisher* publisher, std::vector type); protected: std::vector subscribed_event_types; }; @@ -24,7 +25,7 @@ public: virtual void subscribe(VrEventSubscriber *subscriber, vr::Event::EventType type); virtual void subscribe(VrEventSubscriber *subscriber, std::vector type); virtual void unsubscribe(VrEventSubscriber *s, vr::Event::EventType c); - virtual void notify(vr::Event e); + virtual void notify_subscribers(std::unique_ptr event); private: std::map> subscribers; diff --git a/src/Camera.cpp b/src/Camera.cpp index e33ea91..0b938a0 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -87,9 +87,44 @@ int Camera::update(double delta_time) { return 1; } -void Camera::update(VrEventPublisher* p, vr::Event e) { +void Camera::recieve_event(VrEventPublisher* publisher, std::unique_ptr event) { + + if (event.get()->type == vr::Event::KeyHeld) { + + vr::KeyHeld *held_event = static_cast(event.get()); + + float speed = 1.0f; + + if (held_event->code == sf::Keyboard::LShift) { + speed = 0.2f; + } + else if (held_event->code == sf::Keyboard::C) { + look_at_center(); + } + else if (held_event->code == sf::Keyboard::Q) { + add_relative_impulse(Camera::DIRECTION::DOWN, speed); + } + else if (held_event->code == sf::Keyboard::E) { + add_relative_impulse(Camera::DIRECTION::UP, speed); + } + else if (held_event->code == sf::Keyboard::W) { + add_relative_impulse(Camera::DIRECTION::FORWARD, speed); + } + else if (held_event->code == sf::Keyboard::S) { + add_relative_impulse(Camera::DIRECTION::REARWARD, speed); + } + else if (held_event->code == sf::Keyboard::A) { + add_relative_impulse(Camera::DIRECTION::LEFT, speed); + } + else if (held_event->code == sf::Keyboard::D) { + add_relative_impulse(Camera::DIRECTION::RIGHT, speed); + } + else if (held_event->code == sf::Keyboard::T) { + set_position(sf::Vector3f(50, 50, 50)); + } + } + - std::cout << "Cam event" << std::endl; } void Camera::look_at_center() { diff --git a/src/Input.cpp b/src/Input.cpp index aeded8a..dbafc28 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -27,29 +27,86 @@ void Input::consume_sf_events(sf::RenderWindow *window) { transpose_sf_events(sf_event_queue); sf_event_queue.clear(); + } void Input::consume_vr_events() { } -void Input::set_flags() { - - //for (auto e: event_queue) { - // if (e.type == vr::Event::KeyPressed) { - // vr::KeyPressed e = static_cast(e); - // - // } - // else if (e.type == sf::Event::KeyReleased) { - // //std::remove(held_keys.begin(), held_keys.end(), e.key.code); - // } - //} +void Input::handle_held_keys() { + + // When keys and buttons are pressed, add them to the held list. + // When they are depressed, remove them + + for (auto&& event: event_queue) { + if (event->type == vr::Event::KeyPressed) { + vr::KeyPressed *e = static_cast(event.get()); + held_keys.push_back(e->code); + } + else if (event->type == vr::Event::KeyReleased) { + vr::KeyReleased *e = static_cast(event.get()); + std::remove(held_keys.begin(), held_keys.end(), e->code); + } + else if (event->type == vr::Event::MouseButtonPressed) { + vr::MouseButtonPressed *e = static_cast(event.get()); + held_mouse_buttons.push_back(e->button); + } + else if (event->type == vr::Event::MouseButtonReleased) { + vr::MouseButtonReleased *e = static_cast(event.get()); + std::remove(held_mouse_buttons.begin(), held_mouse_buttons.end(), e->button); + } + } + + // Generate Held events for each of the held buttons and keys + + for (auto key : held_keys) { + + // Not sure if this is a good idea, but I'm going to grab + // the real-time values of the mod keys and add them to the event + + bool alt = false; + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt) || sf::Keyboard::isKeyPressed(sf::Keyboard::RAlt)) { + alt = true; + } + + bool control = false; + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl)) { + control = true; + } + + bool shift = false; + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift) || sf::Keyboard::isKeyPressed(sf::Keyboard::RShift)) { + shift = true; + } + + bool system = false; + if (sf::Keyboard::isKeyPressed(sf::Keyboard::LSystem) || sf::Keyboard::isKeyPressed(sf::Keyboard::RSystem)) { + system = true; + } + + event_queue.push_back(std::make_unique(vr::KeyHeld(key, alt, control, shift, system))); + } + + + for (auto mouse_button : held_mouse_buttons) { + + // Again, I'm going to poll the real-time status of this event + // to fill in the X and Y values. I can do this either with screen + // co-ords or with viewport co-ords. I don't have access to the window + // from here so for now I'm going to do screen co-ords + + sf::Vector2i mouse_pos = sf::Mouse::getPosition(); + + event_queue.push_back(std::make_unique(vr::MouseButtonHeld(mouse_button, mouse_pos.x, mouse_pos.y))); + } + } void Input::dispatch_events() { while (event_queue.size() != 0) { - notify(*event_queue.front().get()); + notify_subscribers(std::move(event_queue.front())); event_queue.pop_front(); } @@ -163,3 +220,4 @@ void Input::transpose_sf_events(std::list sf_event_queue) { } } } + diff --git a/src/Pub_Sub.cpp b/src/Pub_Sub.cpp index 2375ac2..4b0f356 100644 --- a/src/Pub_Sub.cpp +++ b/src/Pub_Sub.cpp @@ -3,12 +3,13 @@ #include "Event.hpp" #include "Pub_Sub.h" -void VrEventSubscriber::subscribe(VrEventPublisher* publisher, vr::Event::EventType type) { + +void VrEventSubscriber::subscribe_to_publisher(VrEventPublisher* publisher, vr::Event::EventType type) { publisher->subscribe(this, type); } -void VrEventSubscriber::subscribe(VrEventPublisher* publisher, std::vector type) { +void VrEventSubscriber::subscribe_to_publisher(VrEventPublisher* publisher, std::vector type) { publisher->subscribe(this, type); } @@ -29,13 +30,13 @@ void VrEventPublisher::unsubscribe(VrEventSubscriber *s, vr::Event::EventType ty std::remove(subscribers[type].begin(), subscribers[type].end(), s); } -void VrEventPublisher::notify(vr::Event event) { +void VrEventPublisher::notify_subscribers(std::unique_ptr event) { // get the bucket containing subscribers to that Event_Class - std::vector *event_type_bucket = &subscribers[event.type]; + std::vector *event_type_bucket = &subscribers[event.get()->type]; // Send them the event for (auto s : *event_type_bucket) { - s->update(this, event); + s->recieve_event(this, std::move(event)); } } diff --git a/src/main.cpp b/src/main.cpp index 222a867..aa1e2d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -148,14 +148,18 @@ int main() { Input input_handler; - input_handler.subscribe(camera, vr::Event::EventType::KeyPressed); + input_handler.subscribe(camera, vr::Event::EventType::KeyHeld); + + WindowHandler win_hand(&window); + win_hand.subscribe_to_publisher(&input_handler, vr::Event::EventType::Closed); window.setKeyRepeatEnabled(false); while (window.isOpen()) { input_handler.consume_sf_events(&window); - input_handler.set_flags(); + input_handler.handle_held_keys(); + input_handler.dispatch_events(); // Poll for events from the user sf::Event event; while (window.pollEvent(event)) { @@ -190,36 +194,6 @@ int main() { } } - float speed = 1.0f; - - if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { - speed = 0.2f; - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::L)) { - camera->look_at_center(); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) { - camera->add_relative_impulse(Camera::DIRECTION::DOWN, speed); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) { - camera->add_relative_impulse(Camera::DIRECTION::UP, speed); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - camera->add_relative_impulse(Camera::DIRECTION::FORWARD, speed); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - camera->add_relative_impulse(Camera::DIRECTION::REARWARD, speed); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - camera->add_relative_impulse(Camera::DIRECTION::LEFT, speed); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - camera->add_relative_impulse(Camera::DIRECTION::RIGHT, speed); - } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { - camera->set_position(sf::Vector3f(50, 50, 50)); - } - if (mouse_enabled) { if (reset) { reset = false;