From 0e1e9af37c8310564294641a7f764bd74bc6729a Mon Sep 17 00:00:00 2001 From: MitchellHansen Date: Sat, 14 Jan 2017 13:49:56 -0800 Subject: [PATCH] More work on the event system, sf::Events are completely wrapped now. --- CMakeLists.txt | 6 +- include/Camera.h | 6 +- include/Event.hpp | 14 ++-- include/Input.h | 7 +- include/Pub_Sub.h | 32 ++++++++ include/Pub_Sub.hpp | 139 -------------------------------- src/Camera.cpp | 9 +-- src/Input.cpp | 190 ++++++++++++++++++++++---------------------- src/Pub_Sub.cpp | 41 ++++++++++ src/main.cpp | 6 +- 10 files changed, 195 insertions(+), 255 deletions(-) create mode 100644 include/Pub_Sub.h delete mode 100644 include/Pub_Sub.hpp create mode 100644 src/Pub_Sub.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a8b1548..eedb759 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,11 @@ target_link_libraries (${PNAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES}) target_link_libraries (${PNAME} ${OpenCL_LIBRARY}) target_link_libraries (${PNAME} ${OPENGL_LIBRARIES}) target_link_libraries (${PNAME} ${GLEW_LIBRARIES}) -target_link_libraries (${PNAME} -lpthread) + +if (NOT WIN32) + target_link_libraries (${PNAME} -lpthread) +endif() + #target_link_libraries (${PNAME} ${Vulkan_LIBRARIES}) # Setup to use C++11 diff --git a/include/Camera.h b/include/Camera.h index ae8d166..f712b4d 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -2,9 +2,9 @@ #include #include #include "util.hpp" -#include "Pub_Sub.hpp" +#include "Pub_Sub.h" -class Camera : public SfEventSubscriber{ +class Camera : public VrEventSubscriber{ public: enum DIRECTION { FORWARD, REARWARD, LEFT, RIGHT, UP, DOWN }; @@ -35,7 +35,7 @@ public: sf::Vector2f get_direction(); - virtual void update(SfEventPublisher* p, sf::Event e) override; + void update(VrEventPublisher* p, vr::Event e) override; private: diff --git a/include/Event.hpp b/include/Event.hpp index 0f7d0fa..3ad1f2e 100644 --- a/include/Event.hpp +++ b/include/Event.hpp @@ -4,7 +4,7 @@ #include #include #include -#include + namespace vr { @@ -125,7 +125,7 @@ namespace vr { class MouseWheelScrolled : public Event { public: - MouseWheelScrolled(sf::Mouse::Wheel wheel, bool delta, bool x, bool y) : + MouseWheelScrolled(sf::Mouse::Wheel wheel, float delta, int x, int y) : wheel(wheel), delta(delta), x(x), y(y), Event(vr::Event::EventType::MouseWheelScrolled) {}; sf::Mouse::Wheel wheel; @@ -136,7 +136,7 @@ namespace vr { class MouseButtonPressed : public Event { public: - MouseButtonPressed(sf::Mouse::Button button, bool x, bool y) : + MouseButtonPressed(sf::Mouse::Button button, int x, int y) : button(button), x(x), y(y), Event(vr::Event::EventType::MouseButtonPressed) {}; sf::Mouse::Button button; @@ -146,7 +146,7 @@ namespace vr { class MouseButtonReleased : public Event { public: - MouseButtonReleased(sf::Mouse::Button button, bool x, bool y) : + MouseButtonReleased(sf::Mouse::Button button, int x, int y) : button(button), x(x), y(y), Event(vr::Event::EventType::MouseButtonReleased) {}; sf::Mouse::Button button; @@ -156,7 +156,7 @@ namespace vr { class MouseMoved : public Event { public: - MouseMoved(bool x, bool y) : + MouseMoved(int x, int y) : x(x), y(y), Event(vr::Event::EventType::MouseMoved) {}; int x; @@ -165,7 +165,7 @@ namespace vr { class MouseEntered : public Event { public: - MouseEntered(bool x, bool y) : + MouseEntered(int x, int y) : x(x), y(y), Event(vr::Event::EventType::MouseEntered) {}; int x; @@ -174,7 +174,7 @@ namespace vr { class MouseLeft : public Event { public: - MouseLeft(bool x, bool y) : + MouseLeft(int x, int y) : x(x), y(y), Event(vr::Event::EventType::MouseLeft) {}; int x; diff --git a/include/Input.h b/include/Input.h index 49d6d53..db78179 100644 --- a/include/Input.h +++ b/include/Input.h @@ -1,11 +1,12 @@ #pragma once #include #include -#include "Pub_Sub.hpp" #include "Event.hpp" +#include +#include "Pub_Sub.h" -class Input : public SfEventPublisher { +class Input : public VrEventPublisher { public: Input(); @@ -34,6 +35,6 @@ private: private: - std::list event_queue; + std::list> event_queue; }; diff --git a/include/Pub_Sub.h b/include/Pub_Sub.h new file mode 100644 index 0000000..58c9a73 --- /dev/null +++ b/include/Pub_Sub.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include +#include "Event.hpp" + + +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); +protected: + std::vector subscribed_event_types; +}; + + +class VrEventPublisher { +public: + + virtual ~VrEventPublisher() {}; + 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); +private: + std::map> subscribers; + +}; + diff --git a/include/Pub_Sub.hpp b/include/Pub_Sub.hpp deleted file mode 100644 index 654a076..0000000 --- a/include/Pub_Sub.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#pragma once -#include - - -class SfEventPublisher; - -class SfEventSubscriber { -public: - virtual ~SfEventSubscriber() {}; - virtual void update(SfEventPublisher* p, sf::Event e) = 0; -}; - -class SfEventPublisher { -public: - - // Allows the subscription to classes of events - enum Event_Class { - JoystickButtonEvent, - JoystickConnectEvent, - JoystickMoveEvent, - KeyEvent, - MouseButtonEvent, - MouseMoveEvent, - MouseWheelEvent, - MouseWheelScrollEvent, - SensorEvent, - SizeEvent, - TextEvent, - TouchEvent, - WindowEvent - }; - - virtual ~SfEventPublisher() {}; - virtual void subscribe(SfEventSubscriber *s, Event_Class c) { - subscribers[c].push_back(s); - }; - virtual void unsubscribe(SfEventSubscriber *s, Event_Class c) { - std::remove(subscribers[c].begin(), subscribers[c].end(), s); - }; - virtual void notify(sf::Event e) { - - // I don't quite like that some event classes contained multiple types of events: - // KeyPressed, and KeyReleased under KeyEvent for example. - // While others are not represented by classes: - // Closed, LostFocus, and GainedFocus have no representing class. - // So, we'll add another "class", WindowEvent which contains those previously mentioned, - // and use those new identifiers to group our events - - // This will also make it a bit easier when subscribing to certain events - - Event_Class event_class; - - if (e.type == sf::Event::Closed || - e.type == sf::Event::LostFocus || - e.type == sf::Event::GainedFocus ){ - - event_class = Event_Class::WindowEvent; - } - - // Preserve a little of sfml's default behavior and separate resized event - else if (e.type == sf::Event::Resized) { - event_class = Event_Class::SizeEvent; - } - - else if (e.type == sf::Event::TextEntered) { - event_class = Event_Class::TextEvent; - } - - else if (e.type == sf::Event::KeyPressed || - e.type == sf::Event::KeyReleased ){ - - event_class = Event_Class::KeyEvent; - } - - else if (e.type == sf::Event::MouseWheelMoved || - e.type == sf::Event::MouseWheelScrolled ){ - - event_class = Event_Class::MouseWheelScrollEvent; - } - - else if (e.type == sf::Event::MouseButtonPressed || - e.type == sf::Event::MouseButtonReleased ){ - - event_class = Event_Class::MouseButtonEvent; - } - - // Is this a good idea, mixing events that contain data, and don't contain data? - else if (e.type == sf::Event::MouseMoved || - e.type == sf::Event::MouseEntered || - e.type == sf::Event::MouseLeft ){ - - event_class = Event_Class::MouseMoveEvent; - } - - else if (e.type == sf::Event::JoystickButtonPressed || - e.type == sf::Event::JoystickButtonReleased ){ - - event_class = Event_Class::JoystickButtonEvent; - } - - else if (e.type == sf::Event::JoystickMoved) { - event_class = Event_Class::JoystickMoveEvent; - } - - else if (e.type == sf::Event::JoystickConnected || - e.type == sf::Event::JoystickDisconnected ){ - - event_class = Event_Class::JoystickConnectEvent; - } - - else if (e.type == sf::Event::TouchBegan || - e.type == sf::Event::TouchEnded || - e.type == sf::Event::TouchMoved ){ - - event_class = Event_Class::TouchEvent; - } - - else if (e.type == sf::Event::SensorChanged) { - event_class = Event_Class::SensorEvent; - } - - else { - std::cout << "Unable to classify sf::Event into Event_Class"; - abort(); - } - - // get the bucket containing subscribers to that Event_Class - std::vector *event_type_bucket = &subscribers[event_class]; - - // Send them the event - for (auto s : *event_type_bucket) { - s->update(this, e); - } - }; -private: - std::map> subscribers; - -}; - diff --git a/src/Camera.cpp b/src/Camera.cpp index 9a04e24..e33ea91 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -1,5 +1,6 @@ +#pragma once #include "Camera.h" - +#include "Pub_Sub.h" Camera::Camera() { @@ -86,18 +87,16 @@ int Camera::update(double delta_time) { return 1; } -void Camera::update(SfEventPublisher* p, sf::Event e) -{ +void Camera::update(VrEventPublisher* p, vr::Event e) { + std::cout << "Cam event" << std::endl; } void Camera::look_at_center() { direction = CartToNormalizedSphere(sf::Vector3f(75, 75, 75) - position); - } - sf::Vector2f* Camera::get_direction_pointer() { return &direction; } diff --git a/src/Input.cpp b/src/Input.cpp index 4adab27..aeded8a 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -1,4 +1,6 @@ #include "Input.h" +#include +#include Input::Input() : @@ -24,6 +26,7 @@ void Input::consume_sf_events(sf::RenderWindow *window) { transpose_sf_events(sf_event_queue); + sf_event_queue.clear(); } void Input::consume_vr_events() { @@ -32,134 +35,131 @@ void Input::consume_vr_events() { void Input::set_flags() { - for (auto e: event_queue) { - if (e.type == sf::Event::KeyPressed) { - held_keys.push_back(e.key.code); - } - else if (e.type == sf::Event::KeyReleased) { - std::remove(held_keys.begin(), held_keys.end(), e.key.code); - } - } + //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::dispatch_events() { while (event_queue.size() != 0) { - notify(event_queue.front()); + notify(*event_queue.front().get()); event_queue.pop_front(); } + } void Input::transpose_sf_events(std::list sf_event_queue) { for (auto sf_event: sf_event_queue) { - vr::Event vr_event; - switch(sf_event.type) { case sf::Event::Closed : { - event_queue.push_back(vr::Closed()); + event_queue.push_back(std::make_unique(vr::Closed())); + break; }; case sf::Event::Resized: { - event_queue.push_back(vr::Resized()); + event_queue.push_back(std::make_unique(vr::Resized(sf_event.size.width, sf_event.size.height))); + break; }; case sf::Event::LostFocus: { - vr_event = vr::Closed(); + event_queue.push_back(std::make_unique(vr::LostFocus())); + break; }; case sf::Event::GainedFocus: { - vr_event = vr::Closed(); + event_queue.push_back(std::make_unique(vr::GainedFocus())); + break; }; - case sf::Event::TextEntered: { - vr_event = vr::Closed(); + event_queue.push_back(std::make_unique(vr::TextEntered(sf_event.text.unicode))); + break; }; case sf::Event::KeyPressed: { - vr_event = vr::Closed(); + event_queue.push_back(std::make_unique(vr::KeyPressed(sf_event.key.code, sf_event.key.alt, sf_event.key.control, sf_event.key.shift, sf_event.key.system))); + break; }; case sf::Event::KeyReleased: { - vr_event = vr::Closed(); + event_queue.push_back(std::make_unique(vr::KeyReleased(sf_event.key.code, sf_event.key.alt, sf_event.key.control, sf_event.key.shift, sf_event.key.system))); + break; }; + + // Mouse wheel moved will generate a MouseWheelScrolled event with the defaul vertical wheel case sf::Event::MouseWheelMoved: { - vr_event = vr::Closed(); + event_queue.push_back(std::make_unique(vr::MouseWheelScrolled(sf::Mouse::VerticalWheel, sf_event.mouseWheelScroll.delta, sf_event.mouseWheelScroll.x, sf_event.mouseWheelScroll.y))); + break; }; - case sf::Event::Closed: { - vr_event = vr::Closed(); + case sf::Event::MouseWheelScrolled: { + event_queue.push_back(std::make_unique(vr::MouseWheelScrolled(sf_event.mouseWheelScroll.wheel, sf_event.mouseWheelScroll.delta, sf_event.mouseWheelScroll.x, sf_event.mouseWheelScroll.y))); + break; }; - case sf::Event::Closed: { - vr_event = vr::Closed(); + case sf::Event::MouseButtonPressed: { + event_queue.push_back(std::make_unique(vr::MouseButtonPressed(sf_event.mouseButton.button, sf_event.mouseButton.x, sf_event.mouseButton.y))); + break; }; - - } - if (e.type == sf::Event::Closed || - e.type == sf::Event::LostFocus || - e.type == sf::Event::GainedFocus) { - - event_class = Event_Class::WindowEvent; - } - - // Preserve a little of sfml's default behavior and separate resized event - else if (e.type == sf::Event::Resized) { - event_class = Event_Class::SizeEvent; - } - - else if (e.type == sf::Event::TextEntered) { - event_class = Event_Class::TextEvent; - } - - else if (e.type == sf::Event::KeyPressed || - e.type == sf::Event::KeyReleased) { - - event_class = Event_Class::KeyEvent; - } - - else if (e.type == sf::Event::MouseWheelMoved || - e.type == sf::Event::MouseWheelScrolled) { - - event_class = Event_Class::MouseWheelScrollEvent; - } - - else if (e.type == sf::Event::MouseButtonPressed || - e.type == sf::Event::MouseButtonReleased) { - - event_class = Event_Class::MouseButtonEvent; - } - - // Is this a good idea, mixing events that contain data, and don't contain data? - else if (e.type == sf::Event::MouseMoved || - e.type == sf::Event::MouseEntered || - e.type == sf::Event::MouseLeft) { - - event_class = Event_Class::MouseMoveEvent; - } - - else if (e.type == sf::Event::JoystickButtonPressed || - e.type == sf::Event::JoystickButtonReleased) { - - event_class = Event_Class::JoystickButtonEvent; - } - - else if (e.type == sf::Event::JoystickMoved) { - event_class = Event_Class::JoystickMoveEvent; - } - - else if (e.type == sf::Event::JoystickConnected || - e.type == sf::Event::JoystickDisconnected) { - - event_class = Event_Class::JoystickConnectEvent; - } - - else if (e.type == sf::Event::TouchBegan || - e.type == sf::Event::TouchEnded || - e.type == sf::Event::TouchMoved) { - - event_class = Event_Class::TouchEvent; - } - - else if (e.type == sf::Event::SensorChanged) { - event_class = Event_Class::SensorEvent; + case sf::Event::MouseButtonReleased: { + event_queue.push_back(std::make_unique(vr::MouseButtonReleased(sf_event.mouseButton.button, sf_event.mouseButton.x, sf_event.mouseButton.y))); + break; + }; + case sf::Event::MouseMoved: { + event_queue.push_back(std::make_unique(vr::MouseMoved(sf_event.mouseMove.x, sf_event.mouseMove.y))); + break; + }; + case sf::Event::MouseEntered: { + event_queue.push_back(std::make_unique(vr::MouseEntered(sf_event.mouseMove.x, sf_event.mouseMove.y))); + break; + }; + case sf::Event::MouseLeft: { + event_queue.push_back(std::make_unique(vr::MouseLeft(sf_event.mouseMove.x, sf_event.mouseMove.x))); + break; + }; + case sf::Event::JoystickButtonPressed: { + event_queue.push_back(std::make_unique(vr::JoystickButtonPressed(sf_event.joystickButton.joystickId, sf_event.joystickButton.button))); + break; + }; + case sf::Event::JoystickButtonReleased: { + event_queue.push_back(std::make_unique(vr::JoystickButtonReleased(sf_event.joystickButton.joystickId, sf_event.joystickButton.button))); + break; + }; + case sf::Event::JoystickMoved: { + event_queue.push_back(std::make_unique(vr::JoystickMoved(sf_event.joystickMove.axis, sf_event.joystickMove.joystickId, sf_event.joystickMove.position))); + break; + }; + case sf::Event::JoystickConnected: { + event_queue.push_back(std::make_unique(vr::JoystickConnected(sf_event.joystickConnect.joystickId))); + break; + }; + case sf::Event::JoystickDisconnected: { + event_queue.push_back(std::make_unique(vr::JoystickDisconnected(sf_event.joystickConnect.joystickId))); + break; + }; + case sf::Event::TouchBegan: { + event_queue.push_back(std::make_unique(vr::TouchBegan(sf_event.touch.finger, sf_event.touch.x, sf_event.touch.y))); + break; + }; + case sf::Event::TouchMoved: { + event_queue.push_back(std::make_unique(vr::TouchMoved(sf_event.touch.finger, sf_event.touch.x, sf_event.touch.y))); + break; + }; + case sf::Event::TouchEnded: { + event_queue.push_back(std::make_unique(vr::TouchEnded(sf_event.touch.finger, sf_event.touch.x, sf_event.touch.y))); + break; + }; + case sf::Event::SensorChanged: { + event_queue.push_back(std::make_unique(vr::SensorChanged(sf_event.sensor.type, sf_event.sensor.x, sf_event.sensor.y, sf_event.sensor.z))); + break; + }; + default: { + std::cout << "Event not recognized"; + abort(); + break; + } } } - - } diff --git a/src/Pub_Sub.cpp b/src/Pub_Sub.cpp new file mode 100644 index 0000000..2375ac2 --- /dev/null +++ b/src/Pub_Sub.cpp @@ -0,0 +1,41 @@ +#pragma once +#include +#include "Event.hpp" +#include "Pub_Sub.h" + +void VrEventSubscriber::subscribe(VrEventPublisher* publisher, vr::Event::EventType type) { + + publisher->subscribe(this, type); +} + +void VrEventSubscriber::subscribe(VrEventPublisher* publisher, std::vector type) { + + publisher->subscribe(this, type); +} + +void VrEventPublisher::subscribe(VrEventSubscriber *subscriber, vr::Event::EventType type) { + + subscribers[type].push_back(subscriber); +} + +void VrEventPublisher::subscribe(VrEventSubscriber *subscriber, std::vector type) { + + for (auto t : type) + subscribers[t].push_back(subscriber); +} + +void VrEventPublisher::unsubscribe(VrEventSubscriber *s, vr::Event::EventType type) { + + std::remove(subscribers[type].begin(), subscribers[type].end(), s); +} + +void VrEventPublisher::notify(vr::Event event) { + + // get the bucket containing subscribers to that Event_Class + std::vector *event_type_bucket = &subscribers[event.type]; + + // Send them the event + for (auto s : *event_type_bucket) { + s->update(this, event); + } +} diff --git a/src/main.cpp b/src/main.cpp index 6bfc42e..222a867 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include #include "Software_Caster.h" #include "Input.h" +#include "Pub_Sub.h" const int WINDOW_X = 1920; @@ -147,12 +148,13 @@ int main() { Input input_handler; - input_handler.subscribe(camera, SfEventPublisher::Event_Class::KeyEvent); + input_handler.subscribe(camera, vr::Event::EventType::KeyPressed); + window.setKeyRepeatEnabled(false); while (window.isOpen()) { - input_handler.consume_events(&window); + input_handler.consume_sf_events(&window); input_handler.set_flags(); // Poll for events from the user sf::Event event;