Inject GLFW shell and move Win32 key map

This commit is contained in:
2026-06-17 10:53:51 +02:00
parent 59a9074109
commit 0a7961d8b3
10 changed files with 95 additions and 60 deletions

View File

@@ -70,6 +70,17 @@ What is already real:
- `pp_app_core` - `pp_app_core`
Latest slice: Latest slice:
- `src/platform_legacy/legacy_platform_services.*` now accepts an injected
`LegacyGlfwPlatformShell` for Linux/WebGL `acquire_render_context`,
`present_render_context`, and app-close callbacks.
- `linux/src/main.cpp` and `webgl/src/main.cpp` now provide that GLFW shell
directly from the entrypoint-owned window state instead of relying on legacy
free helpers for those operations.
- `src/platform_legacy/legacy_platform_state.*` no longer exports the old GLFW
`acquire/present/request_close` helper trio.
- `src/platform_windows/windows_platform_services.cpp` now owns the Win32
virtual-key map and `initialize_retained_input_state()` path, so
`windows_window_shell.cpp` no longer carries that retained input setup.
- `src/platform_windows/windows_window_shell.*` no longer carries the dead - `src/platform_windows/windows_window_shell.*` no longer carries the dead
retained raw key-state array or its accessor; Win32 key synchronization now retained raw key-state array or its accessor; Win32 key synchronization now
relies only on the virtual-key map plus `App` key state. relies only on the virtual-key map plus `App` key state.

View File

@@ -78,6 +78,16 @@ Completed, blocked, and superseded task history moved to
the queue is now ordered by code movement instead. the queue is now ordered by code movement instead.
Current slice: Current slice:
- `src/platform_legacy/legacy_platform_services.*` now uses an injected
`LegacyGlfwPlatformShell` for the remaining Linux/WebGL
acquire/present/request-close path.
- `linux/src/main.cpp` and `webgl/src/main.cpp` now bind those GLFW operations
directly from entrypoint-owned window state.
- `src/platform_legacy/legacy_platform_state.*` no longer carries the old GLFW
acquire/present/request-close helper trio.
- `src/platform_windows/windows_platform_services.cpp` now owns the Win32
virtual-key map initialization path, so `windows_window_shell.cpp` no longer
carries that retained input setup.
- `src/platform_windows/windows_window_shell.*` no longer keeps the dead - `src/platform_windows/windows_window_shell.*` no longer keeps the dead
retained raw key-state array. retained raw key-state array.
- `linux/src/main.cpp` now owns the Linux FPS-title callback lifecycle - `linux/src/main.cpp` now owns the Linux FPS-title callback lifecycle

View File

@@ -46,7 +46,6 @@ void error_log(int code, const char * s)
int main(int argc, char** args) int main(int argc, char** args)
{ {
auto platform_services = pp::platform::legacy::create_platform_services();
GLFWwindow* wnd = nullptr; GLFWwindow* wnd = nullptr;
glfwSetErrorCallback(error_log); glfwSetErrorCallback(error_log);
if (!glfwInit()) if (!glfwInit())
@@ -69,6 +68,11 @@ int main(int argc, char** args)
pp::platform::linux_desktop::set_fps_title_callback([wnd](std::string title) { pp::platform::linux_desktop::set_fps_title_callback([wnd](std::string title) {
glfwSetWindowTitle(wnd, title.c_str()); glfwSetWindowTitle(wnd, title.c_str());
}); });
auto platform_services = pp::platform::legacy::create_platform_services({
.acquire_render_context = [wnd] { glfwMakeContextCurrent(wnd); },
.present_render_context = [wnd] { glfwSwapBuffers(wnd); },
.request_app_close = [wnd] { glfwSetWindowShouldClose(wnd, GLFW_TRUE); },
});
glfwSetCursorPosCallback(wnd, [](GLFWwindow* wnd, double x, double y){ glfwSetCursorPosCallback(wnd, [](GLFWwindow* wnd, double x, double y){
g_cursor_pos = glm::vec2(x, y); g_cursor_pos = glm::vec2(x, y);
@@ -101,7 +105,7 @@ int main(int argc, char** args)
}, true); }, true);
}); });
pp::platform::legacy::acquire_legacy_glfw_render_context(); glfwMakeContextCurrent(wnd);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{ {
printf("Failed to initialize OpenGL context\n"); printf("Failed to initialize OpenGL context\n");

View File

@@ -48,6 +48,11 @@ namespace {
// DEBT-0017: fallback for platforms that do not inject PlatformServices yet. // DEBT-0017: fallback for platforms that do not inject PlatformServices yet.
class LegacyPlatformServices final : public pp::platform::PlatformServices { class LegacyPlatformServices final : public pp::platform::PlatformServices {
public: public:
explicit LegacyPlatformServices(pp::platform::legacy::LegacyGlfwPlatformShell glfw_shell = {})
: glfw_shell_(std::move(glfw_shell))
{
}
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_storage_paths() override [[nodiscard]] pp::platform::PlatformStoragePaths prepare_storage_paths() override
{ {
#if defined(__IOS__) #if defined(__IOS__)
@@ -181,7 +186,7 @@ public:
#elif __ANDROID__ #elif __ANDROID__
android_async_lock(); android_async_lock();
#elif __LINUX__ || __WEB__ #elif __LINUX__ || __WEB__
pp::platform::legacy::acquire_legacy_glfw_render_context(); invoke_legacy_glfw_shell_callback(glfw_shell_.acquire_render_context);
#endif #endif
} }
@@ -201,7 +206,7 @@ public:
#elif __ANDROID__ #elif __ANDROID__
android_async_swap(); android_async_swap();
#elif __LINUX__ || __WEB__ #elif __LINUX__ || __WEB__
pp::platform::legacy::present_legacy_glfw_render_context(); invoke_legacy_glfw_shell_callback(glfw_shell_.present_render_context);
#endif #endif
} }
@@ -507,7 +512,7 @@ public:
#ifdef __OSX__ #ifdef __OSX__
pp::platform::apple::active_legacy_apple_document_platform_services().request_app_close(); pp::platform::apple::active_legacy_apple_document_platform_services().request_app_close();
#elif __LINUX__ #elif __LINUX__
pp::platform::legacy::request_legacy_glfw_app_close(); invoke_legacy_glfw_shell_callback(glfw_shell_.request_app_close);
#endif #endif
} }
@@ -545,6 +550,15 @@ public:
callback(value, false); callback(value, false);
#endif #endif
} }
private:
static void invoke_legacy_glfw_shell_callback(const std::function<void()>& callback)
{
if (callback)
callback();
}
pp::platform::legacy::LegacyGlfwPlatformShell glfw_shell_;
}; };
} }
@@ -557,8 +571,9 @@ PlatformServices& platform_services()
return services; return services;
} }
std::unique_ptr<PlatformServices> create_platform_services() std::unique_ptr<PlatformServices> create_platform_services(
LegacyGlfwPlatformShell glfw_shell)
{ {
return std::make_unique<LegacyPlatformServices>(); return std::make_unique<LegacyPlatformServices>(std::move(glfw_shell));
} }
} }

View File

@@ -1,12 +1,20 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <functional>
#include "platform_api/platform_services.h" #include "platform_api/platform_services.h"
namespace pp::platform::legacy { namespace pp::platform::legacy {
struct LegacyGlfwPlatformShell {
std::function<void()> acquire_render_context;
std::function<void()> present_render_context;
std::function<void()> request_app_close;
};
[[nodiscard]] PlatformServices& platform_services(); [[nodiscard]] PlatformServices& platform_services();
[[nodiscard]] std::unique_ptr<PlatformServices> create_platform_services(); [[nodiscard]] std::unique_ptr<PlatformServices> create_platform_services(
LegacyGlfwPlatformShell glfw_shell = {});
} }

View File

@@ -107,21 +107,6 @@ void set_legacy_glfw_window_title(std::string_view title)
const std::string title_value(title); const std::string title_value(title);
glfwSetWindowTitle(window, title_value.c_str()); glfwSetWindowTitle(window, title_value.c_str());
} }
void acquire_legacy_glfw_render_context()
{
glfwMakeContextCurrent(retained_legacy_glfw_platform_state().window);
}
void present_legacy_glfw_render_context()
{
glfwSwapBuffers(retained_legacy_glfw_platform_state().window);
}
void request_legacy_glfw_app_close()
{
glfwSetWindowShouldClose(retained_legacy_glfw_platform_state().window, GLFW_TRUE);
}
#endif #endif
[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services() [[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services()

View File

@@ -14,9 +14,6 @@ namespace pp::platform::legacy {
#if defined(__LINUX__) || defined(__WEB__) #if defined(__LINUX__) || defined(__WEB__)
void set_legacy_glfw_window(GLFWwindow* window); void set_legacy_glfw_window(GLFWwindow* window);
void set_legacy_glfw_window_title(std::string_view title); void set_legacy_glfw_window_title(std::string_view title);
void acquire_legacy_glfw_render_context();
void present_legacy_glfw_render_context();
void request_legacy_glfw_app_close();
#endif #endif
[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services(); [[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services();

View File

@@ -3,6 +3,7 @@
#include "platform_windows/windows_lifecycle_shell.h" #include "platform_windows/windows_lifecycle_shell.h"
#include "platform_windows/windows_platform_services.h" #include "platform_windows/windows_platform_services.h"
#include "platform_windows/windows_runtime_shell.h" #include "platform_windows/windows_runtime_shell.h"
#include "keymap.h"
#include "platform_windows/windows_stylus_input.h" #include "platform_windows/windows_stylus_input.h"
#include "platform_windows/windows_window_shell.h" #include "platform_windows/windows_window_shell.h"
@@ -104,6 +105,36 @@ void win32_save_window_state()
namespace pp::platform::windows { namespace pp::platform::windows {
[[nodiscard]] std::map<kKey, int>& retained_virtual_key_map()
{
static std::map<kKey, int> vkey_map;
return vkey_map;
}
void initialize_retained_input_state()
{
auto& vkey_map = retained_virtual_key_map();
for (int k = 1; k < 256; ++k) // ignore kKey::Unknown = 0
{
for (int vk = 0; vk < 256; ++vk)
{
if (k != (int)convert_key(vk))
continue;
auto key = (kKey)k;
if (vkey_map.find(key) == vkey_map.end())
{
vkey_map.insert({ key, vk });
}
else
{
LOG("KEY MAP COLLISION %d and %d maps to %d",
vk, vkey_map[key], k);
}
}
}
}
VrShellState& platform_vr_state() noexcept VrShellState& platform_vr_state() noexcept
{ {
return retained_vr_shell_state(); return retained_vr_shell_state();

View File

@@ -14,6 +14,8 @@ void destroy_window();
namespace pp::platform::windows { namespace pp::platform::windows {
[[nodiscard]] std::map<kKey, int>& retained_virtual_key_map();
namespace { namespace {
[[nodiscard]] WacomTablet& active_wacom_tablet() [[nodiscard]] WacomTablet& active_wacom_tablet()
@@ -34,12 +36,6 @@ namespace {
return pointer_source; return pointer_source;
} }
[[nodiscard]] std::map<kKey, int>& retained_virtual_key_map()
{
static std::map<kKey, int> vkey_map;
return vkey_map;
}
void synchronize_app_key_state_from_keyboard(App& app) void synchronize_app_key_state_from_keyboard(App& app)
{ {
BYTE keys[256]; BYTE keys[256];
@@ -62,30 +58,6 @@ void synchronize_app_key_state_from_keyboard(App& app)
} }
void initialize_retained_input_state()
{
auto& vkey_map = retained_virtual_key_map();
for (int k = 1; k < 256; ++k) // ignore kKey::Unknown = 0
{
for (int vk = 0; vk < 256; ++vk)
{
if (k != (int)convert_key(vk))
continue;
auto key = (kKey)k;
if (vkey_map.find(key) == vkey_map.end())
{
vkey_map.insert({ key, vk });
}
else
{
LOG("KEY MAP COLLISION %d and %d maps to %d",
vk, vkey_map[key], k);
}
}
}
}
pp::platform::windows::VrShellState& pp::platform::windows::retained_vr_shell_state() noexcept pp::platform::windows::VrShellState& pp::platform::windows::retained_vr_shell_state() noexcept
{ {
static pp::platform::windows::VrShellState state; static pp::platform::windows::VrShellState state;

View File

@@ -199,14 +199,16 @@ void main_loop()
int main() int main()
{ {
g_platform_services = pp::platform::legacy::create_platform_services();
g_web_platform_services = pp::platform::legacy::create_legacy_web_platform_services();
if (glfwInit() != GL_TRUE) if (glfwInit() != GL_TRUE)
printf("Failed to init GLFW"); printf("Failed to init GLFW");
wnd = glfwCreateWindow(1024, 768, "PanoPainter", nullptr, nullptr); wnd = glfwCreateWindow(1024, 768, "PanoPainter", nullptr, nullptr);
pp::platform::legacy::set_legacy_glfw_window(wnd); pp::platform::legacy::set_legacy_glfw_window(wnd);
pp::platform::legacy::acquire_legacy_glfw_render_context(); g_platform_services = pp::platform::legacy::create_platform_services({
.acquire_render_context = [wnd] { glfwMakeContextCurrent(wnd); },
.present_render_context = [wnd] { glfwSwapBuffers(wnd); },
});
g_web_platform_services = pp::platform::legacy::create_legacy_web_platform_services();
glfwMakeContextCurrent(wnd);
/* /*
glfwSetCursorPosCallback(wnd, [](GLFWwindow* wnd, double x, double y){ glfwSetCursorPosCallback(wnd, [](GLFWwindow* wnd, double x, double y){