From 326db9fa30898c5b3461c6303db62b67874546c5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 28 Aug 2016 01:08:38 +0200 Subject: [PATCH] Utility/Window: Add new event system, based on signals Old pooling-based system remains for now but is now deprecated Former-commit-id: 9482b37fb19041399b7c26181319e1c00e7678fd [formerly 516aa322ca7f656e3e7c66010248b63068eec723] [formerly 6fdb81e8d59fef7d6e10e58898878d3e1a796188 [formerly c999fe23b149e14bdeeefed5436839fe44e1ebc3]] Former-commit-id: fb35c9017bc2c7d15e31ccadb3f943ca2f0332df [formerly 005fa120540dc1a2d09e30c2de9611c4cb98aecf] Former-commit-id: d51482384fffb5d1b339f3ce39df1a1ed6018228 --- SDK/src/NDK/Application.cpp | 2 + examples/Tut01/main.cpp | 8 +-- include/Nazara/Utility/EventHandler.hpp | 47 ++++++++++++++ include/Nazara/Utility/EventHandler.inl | 82 +++++++++++++++++++++++++ include/Nazara/Utility/Window.hpp | 13 ++-- include/Nazara/Utility/Window.inl | 58 +++++++++-------- src/Nazara/Utility/Window.cpp | 9 +++ 7 files changed, 181 insertions(+), 38 deletions(-) create mode 100644 include/Nazara/Utility/EventHandler.hpp create mode 100644 include/Nazara/Utility/EventHandler.inl diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 5e3331d73..63e834bd0 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -26,6 +26,8 @@ namespace Ndk { Nz::Window& window = **it; + window.ProcessEvents(); + if (!window.IsOpen(true)) { it = m_windows.erase(it); diff --git a/examples/Tut01/main.cpp b/examples/Tut01/main.cpp index d1ebcd5d4..f5fca94a0 100644 --- a/examples/Tut01/main.cpp +++ b/examples/Tut01/main.cpp @@ -16,6 +16,7 @@ int main() Nz::RenderWindow& mainWindow = application.AddWindow(); mainWindow.Create(Nz::VideoMode(800, 600, 32), "Test"); + Ndk::World& world = application.AddWorld(); world.GetSystem().SetGlobalUp(Nz::Vector3f::Down()); world.GetSystem().SetDefaultBackground(Nz::ColorBackground::New(Nz::Color(192, 100, 100))); @@ -43,13 +44,6 @@ int main() while (application.Run()) { - Nz::WindowEvent event; - while (mainWindow.PollEvent(&event)) - { - if (event.type == Nz::WindowEventType_Quit) - application.Quit(); - } - mainWindow.Display(); } diff --git a/include/Nazara/Utility/EventHandler.hpp b/include/Nazara/Utility/EventHandler.hpp new file mode 100644 index 000000000..b35ef96cf --- /dev/null +++ b/include/Nazara/Utility/EventHandler.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_EVENTHANDLER_HPP +#define NAZARA_EVENTHANDLER_HPP + +#include +#include +#include +#include + +namespace Nz +{ + class EventHandler + { + public: + EventHandler() = default; + EventHandler(const EventHandler&); + EventHandler(EventHandler&&) = default; + ~EventHandler() = default; + + inline void Dispatch(const WindowEvent& event); + + NazaraSignal(OnGainedFocus, const EventHandler* /*eventHandler*/); + NazaraSignal(OnLostFocus, const EventHandler* /*eventHandler*/); + NazaraSignal(OnKeyPressed, const EventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/); + NazaraSignal(OnKeyReleased, const EventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/); + NazaraSignal(OnMouseButtonDoubleClicked, const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/); + NazaraSignal(OnMouseButtonPressed, const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/); + NazaraSignal(OnMouseButtonReleased, const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/); + NazaraSignal(OnMouseEntered, const EventHandler* /*eventHandler*/); + NazaraSignal(OnMouseLeft, const EventHandler* /*eventHandler*/); + NazaraSignal(OnMouseMoved, const EventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& /*event*/); + NazaraSignal(OnMouseWheelMoved, const EventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& /*event*/); + NazaraSignal(OnMoved, const EventHandler* /*eventHandler*/, const WindowEvent::PositionEvent& /*event*/); + NazaraSignal(OnQuit, const EventHandler* /*eventHandler*/); + NazaraSignal(OnResized, const EventHandler* /*eventHandler*/, const WindowEvent::SizeEvent& /*event*/); + NazaraSignal(OnTextEntered, const EventHandler* /*eventHandler*/, const WindowEvent::TextEvent& /*event*/); + }; +} + +#include + +#endif // NAZARA_EVENTHANDLER_HPP diff --git a/include/Nazara/Utility/EventHandler.inl b/include/Nazara/Utility/EventHandler.inl new file mode 100644 index 000000000..4fadf6b43 --- /dev/null +++ b/include/Nazara/Utility/EventHandler.inl @@ -0,0 +1,82 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + inline EventHandler::EventHandler(const EventHandler&) + { + } + + inline void EventHandler::Dispatch(const WindowEvent& event) + { + switch (event.type) + { + case WindowEventType_GainedFocus: + OnGainedFocus(this); + break; + + case WindowEventType_KeyPressed: + OnKeyPressed(this, event.key); + break; + + case WindowEventType_KeyReleased: + OnKeyReleased(this, event.key); + break; + + case WindowEventType_LostFocus: + OnLostFocus(this); + break; + + case WindowEventType_MouseButtonDoubleClicked: + OnMouseButtonDoubleClicked(this, event.mouseButton); + break; + + case WindowEventType_MouseButtonPressed: + OnMouseButtonPressed(this, event.mouseButton); + break; + + case WindowEventType_MouseButtonReleased: + OnMouseButtonPressed(this, event.mouseButton); + break; + + case WindowEventType_MouseEntered: + OnMouseEntered(this); + break; + + case WindowEventType_MouseLeft: + OnMouseLeft(this); + break; + + case WindowEventType_MouseMoved: + OnMouseMoved(this, event.mouseMove); + break; + + case WindowEventType_MouseWheelMoved: + OnMouseWheelMoved(this, event.mouseWheel); + break; + + case WindowEventType_Moved: + OnMoved(this, event.position); + break; + + case WindowEventType_Quit: + OnQuit(this); + break; + + case WindowEventType_Resized: + OnResized(this, event.size); + break; + + case WindowEventType_TextEntered: + OnTextEntered(this, event.text); + break; + } + } +} + +#include diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index af23be7f1..ba67c17cb 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -52,9 +52,11 @@ namespace Nz void Destroy(); + NAZARA_DEPRECATED("Event pooling/waiting is deprecated, please use the EventHandler system") inline void EnableEventPolling(bool enable); void EnableKeyRepeat(bool enable); void EnableSmoothScrolling(bool enable); + EventHandler& GetEventHandler(); WindowHandle GetHandle() const; unsigned int GetHeight() const; Vector2i GetPosition() const; @@ -71,7 +73,9 @@ namespace Nz inline bool IsValid() const; bool IsVisible() const; - bool PollEvent(WindowEvent* event); + NAZARA_DEPRECATED("Event pooling/waiting is deprecated, please use the EventHandler system") bool PollEvent(WindowEvent* event); + + void ProcessEvents(bool block = false); void SetCursor(WindowCursor cursor); void SetCursor(const Cursor& cursor); @@ -90,7 +94,7 @@ namespace Nz void SetTitle(const String& title); void SetVisible(bool visible); - bool WaitEvent(WindowEvent* event); + NAZARA_DEPRECATED("Event pooling/waiting is deprecated, please use the EventHandler system")bool WaitEvent(WindowEvent* event); Window& operator=(const Window&) = delete; inline Window& operator=(Window&& window); @@ -114,10 +118,11 @@ namespace Nz ConditionVariable m_eventCondition; Mutex m_eventMutex; Mutex m_eventConditionMutex; - bool m_eventListener; bool m_waitForEvent; #endif + EventHandler m_eventHandler; bool m_closed; + bool m_eventPolling; bool m_ownsWindow; }; } diff --git a/include/Nazara/Utility/Window.inl b/include/Nazara/Utility/Window.inl index ebf5dfbee..349328e55 100644 --- a/include/Nazara/Utility/Window.inl +++ b/include/Nazara/Utility/Window.inl @@ -11,39 +11,24 @@ namespace Nz /*! * \class Nz::Window */ - inline Window::Window() : - #if NAZARA_UTILITY_THREADED_WINDOW m_impl(nullptr), - m_eventListener(true), - m_waitForEvent(false) - #else - m_impl(nullptr) + #if NAZARA_UTILITY_THREADED_WINDOW + m_waitForEvent(false), #endif + m_eventPolling(false) { } inline Window::Window(VideoMode mode, const String& title, UInt32 style) : - #if NAZARA_UTILITY_THREADED_WINDOW - m_impl(nullptr), - m_eventListener(true), - m_waitForEvent(false) - #else - m_impl(nullptr) - #endif + Window() { ErrorFlags flags(ErrorFlag_ThrowException, true); Create(mode, title, style); } inline Window::Window(WindowHandle handle) : - #if NAZARA_UTILITY_THREADED_WINDOW - m_impl(nullptr), - m_eventListener(true), - m_waitForEvent(false) - #else - m_impl(nullptr) - #endif + Window() { ErrorFlags flags(ErrorFlag_ThrowException, true); Create(handle); @@ -59,7 +44,7 @@ namespace Nz m_eventCondition(std::move(window.m_eventCondition)), m_eventMutex(std::move(window.m_eventMutex)), m_eventConditionMutex(std::move(window.m_eventConditionMutex)), - m_eventListener(window.m_eventListener), + m_eventPolling(window.m_eventPolling), m_waitForEvent(window.m_waitForEvent), #endif m_closed(window.m_closed), @@ -78,6 +63,21 @@ namespace Nz m_closed = true; // The window will be closed at the next non-const IsOpen() call } + inline void Window::EnableEventPolling(bool enable) + { + m_eventPolling = enable; + if (!m_eventPolling) + { + while (!m_events.empty()) + m_events.pop(); + } + } + + inline EventHandler& Nz::Window::GetEventHandler() + { + return m_eventHandler; + } + inline bool Window::IsOpen(bool checkClosed) { if (!m_impl) @@ -108,7 +108,11 @@ namespace Nz m_eventMutex.Lock(); #endif - m_events.push(event); + if (m_eventPolling) + m_events.push(event); + + m_eventHandler.Dispatch(event); + if (event.type == WindowEventType_Resized) OnWindowResized(); @@ -132,10 +136,11 @@ namespace Nz { Destroy(); - m_closed = window.m_closed; - m_impl = window.m_impl; - m_events = std::move(window.m_events); - m_ownsWindow = window.m_ownsWindow; + m_closed = window.m_closed; + m_eventPolling = window.m_eventPolling; + m_impl = window.m_impl; + m_events = std::move(window.m_events); + m_ownsWindow = window.m_ownsWindow; window.m_impl = nullptr; @@ -143,7 +148,6 @@ namespace Nz m_eventCondition = std::move(window.m_eventCondition); m_eventMutex = std::move(window.m_eventMutex); m_eventConditionMutex = std::move(window.m_eventConditionMutex); - m_eventListener = window.m_eventListener; m_waitForEvent = window.m_waitForEvent; #endif diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index e246144d2..02ed0f40a 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -325,6 +325,15 @@ namespace Nz return false; } + void Window::ProcessEvents(bool block) + { + NazaraAssert(m_impl, "Window not created"); + + #if !NAZARA_UTILITY_THREADED_WINDOW + m_impl->ProcessEvents(block); + #endif + } + void Window::SetCursor(WindowCursor cursor) { #if NAZARA_UTILITY_SAFE