Split window from main event handler

Two globals can be removed.
This commit is contained in:
phosit 2025-04-16 19:49:51 +02:00
parent 701ce73df9
commit 0a1d1821da
No known key found for this signature in database
GPG key ID: C9430B600671C268
4 changed files with 63 additions and 67 deletions

View file

@ -168,14 +168,6 @@ enum ShutdownType
static ShutdownType g_Shutdown = ShutdownType::None;
static int g_ExitStatus{EXIT_SUCCESS};
// to avoid redundant and/or recursive resizing, we save the new
// size after VIDEORESIZE messages and only update the video mode
// once per frame.
// these values are the latest resize message, and reset to 0 once we've
// updated the video mode
static int g_ResizedW;
static int g_ResizedH;
static std::chrono::high_resolution_clock::time_point lastFrameTime;
bool IsQuitRequested()
@ -199,18 +191,6 @@ static Input::Reaction MainInputHandler(const SDL_Event& ev)
{
switch(ev.type)
{
case SDL_WINDOWEVENT:
switch(ev.window.event)
{
case SDL_WINDOWEVENT_RESIZED:
g_ResizedW = ev.window.data1;
g_ResizedH = ev.window.data2;
break;
case SDL_WINDOWEVENT_MOVED:
g_VideoMode.UpdatePosition(ev.window.data1, ev.window.data2);
}
break;
case SDL_QUIT:
QuitEngine(EXIT_SUCCESS);
break;
@ -261,12 +241,6 @@ static Input::Reaction MainInputHandler(const SDL_Event& ev)
g_Profiler2.Toggle();
return Input::Reaction::HANDLED;
}
else if (hotkey == "mousegrabtoggle")
{
SDL_Window* const window{g_VideoMode.GetWindow()};
const SDL_bool willGrabMouse{SDL_GetWindowGrab(window) ? SDL_FALSE : SDL_TRUE};
SDL_SetWindowGrab(window, willGrabMouse);
}
break;
}
@ -449,12 +423,7 @@ static void Frame(RL::Interface* rlInterface, const int fixedFrameFrequency)
if (g_Shutdown != ShutdownType::None)
return;
// respond to pumped resize events
if (g_ResizedW || g_ResizedH)
{
g_VideoMode.ResizeWindow(g_ResizedW, g_ResizedH);
g_ResizedW = g_ResizedH = 0;
}
g_VideoMode.OnceAFrameWork();
if (g_NetClient)
g_NetClient->Poll();

View file

@ -49,28 +49,29 @@ enum class Reaction
namespace Slot
{
constexpr std::integral_constant<size_t, 0> PRIMARY;
constexpr std::integral_constant<size_t, 1> WINDOW;
// These two must be called first `globalsInput` deals with some important global state, such as which
// scancodes are being pressed, mouse buttons pressed, etc. while hotkeyStateChange updates the map of
// active hotkeys.
constexpr std::integral_constant<size_t, 1> HOTKEY_STATE_CHANGE;
constexpr std::integral_constant<size_t, 2> GLOBAL;
constexpr std::integral_constant<size_t, 2> HOTKEY_STATE_CHANGE;
constexpr std::integral_constant<size_t, 3> GLOBAL;
// Should be called after scancode map update (i.e. after the global input, but before UI). This never
// blocks the event, but it does some processing necessary for hotkeys, which are triggered later down the
// input chain. (by calling this before the UI, we can use `EventWouldTriggerHotkey` in the UI).
constexpr std::integral_constant<size_t, 3> HOTKEY_INPUT_PREPARATION;
constexpr std::integral_constant<size_t, 4> HOTKEY_INPUT_PREPARATION;
constexpr std::integral_constant<size_t, 4> TOUCH_INPUT;
constexpr std::integral_constant<size_t, 5> TOUCH_INPUT;
// The console handler needs to be called before the hotkey handler so that text can be typed in without
// setting off hotkeys.
constexpr std::integral_constant<size_t, 5> CONSOLE;
constexpr std::integral_constant<size_t, 6> CONSOLE;
// Likewise for gui.
constexpr std::integral_constant<size_t, 6> GUI;
constexpr std::integral_constant<size_t, 7> HOTKEY_INPUT;
constexpr std::integral_constant<size_t, 8> PROFILE_VIEWER;
constexpr std::integral_constant<size_t, 9> GAME_VIEW;
constexpr std::integral_constant<size_t, 7> GUI;
constexpr std::integral_constant<size_t, 8> HOTKEY_INPUT;
constexpr std::integral_constant<size_t, 9> PROFILE_VIEWER;
constexpr std::integral_constant<size_t, 10> GAME_VIEW;
}
/**
@ -137,7 +138,7 @@ public:
PollEventsResult PollEvents();
private:
std::array<HandlerBase*, 10> m_Handlers{{}};
std::array<HandlerBase*, 11> m_Handlers{{}};
const std::unique_ptr<std::queue<SDL_Event>> m_PriorityEvents;
};

View file

@ -39,6 +39,7 @@
#include "ps/Filesystem.h"
#include "ps/Game.h"
#include "ps/GameSetup/Config.h"
#include "ps/Hotkey.h"
#include "ps/Pyrogenesis.h"
#include "renderer/Renderer.h"
#include "renderer/backend/IDevice.h"
@ -280,6 +281,36 @@ void CVideoMode::CCursor::ResetCursor()
SetCursor(DEFAULT_CURSOR_NAME);
}
Input::Reaction CVideoMode::InputHandler::operator()(const SDL_Event& ev)
{
if (ev.type == SDL_HOTKEYPRESS)
{
if (static_cast<const char*>(ev.user.data1) == "mousegrabtoggle"sv)
{
SDL_Window* const window{videoMode.GetWindow()};
const SDL_bool willGrabMouse{SDL_GetWindowGrab(window) ? SDL_FALSE : SDL_TRUE};
SDL_SetWindowGrab(window, willGrabMouse);
return Input::Reaction::HANDLED;
}
}
if (ev.type == SDL_WINDOWEVENT && videoMode.m_IsFullscreen)
{
switch (ev.window.event)
{
case SDL_WINDOWEVENT_RESIZED:
videoMode.m_ResizedW = ev.window.data1;
videoMode.m_ResizedH = ev.window.data2;
break;
case SDL_WINDOWEVENT_MOVED:
videoMode.m_WindowedX = ev.window.data1;
videoMode.m_WindowedY = ev.window.data2;
break;
}
}
return Input::Reaction::PASS;
}
CVideoMode::CVideoMode() :
m_WindowedW(DEFAULT_WINDOW_W), m_WindowedH(DEFAULT_WINDOW_H), m_WindowedX(0), m_WindowedY(0)
{
@ -736,27 +767,23 @@ Renderer::Backend::ISwapChain* CVideoMode::GetOrCreateSwapChain()
return m_SwapChain.get();
}
bool CVideoMode::ResizeWindow(int w, int h)
bool CVideoMode::OnceAFrameWork()
{
ENSURE(m_IsInitialised);
// Ignore if not windowed
if (m_IsFullscreen)
return true;
// Ignore if the size hasn't changed
if (w == m_WindowedW && h == m_WindowedH)
if ((m_ResizedH == 0 && m_ResizedW == 0) || (m_ResizedW == m_WindowedW && m_ResizedH == m_WindowedH))
return true;
int bpp = GetBestBPP();
if (!SetVideoMode(w, h, bpp, false))
if (!SetVideoMode(m_ResizedW, m_ResizedH, bpp, false))
return false;
m_WindowedW = w;
m_WindowedH = h;
m_WindowedW = m_ResizedW;
m_WindowedH = m_ResizedH;
UpdateRenderer(w, h);
UpdateRenderer(m_ResizedW, m_ResizedH);
return true;
}
@ -844,15 +871,6 @@ bool CVideoMode::IsInFullscreen() const
return m_IsFullscreen;
}
void CVideoMode::UpdatePosition(int x, int y)
{
if (!m_IsFullscreen)
{
m_WindowedX = x;
m_WindowedY = y;
}
}
void CVideoMode::UpdateRenderer(int w, int h)
{
if (w < 2) w = 2; // avoid GL errors caused by invalid sizes

View file

@ -61,7 +61,7 @@ public:
/**
* Resize the SDL window and associated graphics stuff to the new size.
*/
bool ResizeWindow(int w, int h);
bool OnceAFrameWork();
/**
* Set scale and tell dependent compoenent to recompute sizes.
@ -83,11 +83,6 @@ public:
*/
bool ToggleFullscreen();
/**
* Update window position, to restore later if necessary (SDL2 only).
*/
void UpdatePosition(int x, int y);
/**
* Update the graphics code to start drawing to the new size.
* This should be called after the GL context has been resized.
@ -193,6 +188,19 @@ private:
std::unique_ptr<Renderer::Backend::IDevice> m_BackendDevice;
// SwapChain for the corresponding device.
std::unique_ptr<Renderer::Backend::ISwapChain> m_SwapChain;
// To avoid redundant and/or recursive resizing, we save the new size after VIDEORESIZE messages and
// only update the video mode once per frame.
// These values are the values of the latest resize message.
int m_ResizedW{0};
int m_ResizedH{0};
struct InputHandler
{
CVideoMode& videoMode;
Input::Reaction operator()(const SDL_Event& ev);
};
Input::Handler<InputHandler> m_InputHandler{m_InputManager, Input::Slot::WINDOW, {*this}};
};
extern CVideoMode g_VideoMode;