Extract Win32 runtime flow orchestration

This commit is contained in:
2026-06-17 11:47:07 +02:00
parent a1031b3af1
commit b35fa36584
6 changed files with 165 additions and 116 deletions

View File

@@ -247,6 +247,8 @@ set(PP_WINDOWS_PLATFORM_SOURCES
src/platform_windows/windows_platform_services.h
src/platform_windows/windows_runtime_shell.cpp
src/platform_windows/windows_runtime_shell.h
src/platform_windows/windows_runtime_flow.cpp
src/platform_windows/windows_runtime_flow.h
src/platform_windows/windows_runtime_state.cpp
src/platform_windows/windows_runtime_state.h
src/platform_windows/windows_splash.cpp

View File

@@ -70,6 +70,11 @@ What is already real:
- `pp_app_core`
Latest slice:
- `src/platform_windows/windows_runtime_flow.*` now owns the Win32 bound-app
startup/message-loop/shutdown orchestration that used to live in
`windows_runtime_shell.cpp`.
- `src/platform_windows/windows_runtime_shell.cpp` is thinner again and now
delegates the main runtime flow through that Windows-owned helper.
- `src/platform_windows/windows_runtime_shell.cpp` and
`src/platform_windows/windows_lifecycle_shell.cpp` now drive thread
start/stop through the explicit Windows runtime binding instead of routing

View File

@@ -78,6 +78,10 @@ Completed, blocked, and superseded task history moved to
the queue is now ordered by code movement instead.
Current slice:
- `src/platform_windows/windows_runtime_flow.*` now owns the Win32 bound-app
startup/message-loop/shutdown orchestration.
- `src/platform_windows/windows_runtime_shell.cpp` now delegates that runtime
flow instead of carrying the whole orchestration pocket inline.
- `src/platform_windows/windows_runtime_shell.cpp` and
`src/platform_windows/windows_lifecycle_shell.cpp` now use the explicit
Windows runtime binding for thread start/stop control.

View File

@@ -0,0 +1,138 @@
#include "pch.h"
#include "platform_windows/windows_runtime_flow.h"
#include "app.h"
#include "log.h"
#include "platform_windows/windows_lifecycle_state.h"
#include "platform_windows/windows_main_window_session.h"
#include "platform_windows/windows_platform_services.h"
#include "platform_windows/windows_runtime_state.h"
#include "platform_windows/windows_stylus_input.h"
#include "platform_windows/windows_runtime_shell.h"
#include "wacom.h"
#include "../resource.h"
namespace pp::platform::windows {
namespace {
void register_touch_window(HWND hWnd)
{
if (RegisterTouchWindow(hWnd, 0) == 0)
LOG("RegisterTouchWindow error: %s", GetLastErrorAsString().c_str());
}
void initialize_runtime_threads()
{
auto* app = bound_app();
auto* runtime = retained_bound_runtime();
assert(runtime);
mark_lifecycle_running();
runtime->render_thread_start(*app);
runtime->ui_thread_start(*app);
}
void install_debug_gl_callbacks()
{
#ifdef _DEBUG
glad_set_pre_callback(_pre_call_callback);
glad_set_post_callback(_post_call_callback);
#endif
}
void initialize_wintab(HWND hWnd, bool sandboxed)
{
auto* tablet = bound_wacom_tablet();
if (!sandboxed)
{
LOG("init WinTab");
tablet->init(hWnd);
}
else
{
LOG("SKIP init WinTab");
}
}
void set_main_window_icon(HWND hWnd)
{
LOG("change icon");
SendMessage(
hWnd,
WM_SETICON,
ICON_SMALL,
(LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1)));
}
void restore_window_placement(HWND hWnd, int show_command)
{
WINDOWPLACEMENT wp;
GetWindowPlacement(hWnd, &wp);
wp.showCmd = show_command;
SetWindowPlacement(hWnd, &wp);
}
void run_main_message_loop()
{
MSG msg;
auto* app = bound_app();
LOG("start main loop");
while (lifecycle_is_running())
{
auto present = app->animate || app->redraw ?
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
if (msg.message == WM_QUIT)
mark_lifecycle_stopped();
if (present)
{
DispatchMessage(&msg);
TranslateMessage(&msg);
}
drain_main_thread_tasks();
}
}
void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTANCE hInst)
{
retained_wacom_tablet().terminate();
UnregisterClass(startup.window_class.lpszClassName, hInst);
LogRemote::I.stop();
}
}
void run_bound_main_window_runtime(
const MainWindowStartupState& startup,
bool start_in_vr,
HINSTANCE instance,
SplashScreen& splash)
{
auto* app = bound_app();
register_touch_window(retained_main_window_handle_ref());
wglMakeCurrent(NULL, NULL);
initialize_runtime_threads();
install_debug_gl_callbacks();
initialize_wintab(retained_main_window_handle_ref(), retained_main_window_sandboxed());
set_main_window_icon(retained_main_window_handle_ref());
app->ui_sync();
restore_window_placement(retained_main_window_handle_ref(), startup.show_command);
if (start_in_vr)
app->vr_start();
LOG("show main window");
SetForegroundWindow(retained_main_window_handle_ref());
splash.dismiss();
run_main_message_loop();
shutdown_main_window_runtime(startup, instance);
}
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "platform_windows/windows_bootstrap_helpers.h"
#include "platform_windows/windows_splash.h"
namespace pp::platform::windows {
void run_bound_main_window_runtime(
const MainWindowStartupState& startup,
bool start_in_vr,
HINSTANCE instance,
SplashScreen& splash);
}

View File

@@ -8,6 +8,7 @@
#include "platform_windows/windows_lifecycle_state.h"
#include "platform_windows/windows_main_window_session.h"
#include "platform_windows/windows_platform_services.h"
#include "platform_windows/windows_runtime_flow.h"
#include "platform_windows/windows_runtime_state.h"
#include "platform_windows/windows_stylus_input.h"
#include "platform_windows/windows_window_shell.h"
@@ -16,99 +17,6 @@
namespace pp::platform::windows {
namespace {
void register_touch_window(HWND hWnd)
{
// link: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registertouchwindow
if (RegisterTouchWindow(hWnd, 0) == 0)
{
LOG("RegisterTouchWindow error: %s", GetLastErrorAsString().c_str());
}
}
void initialize_runtime_threads()
{
auto* app = bound_app();
auto* runtime = retained_bound_runtime();
assert(runtime);
mark_lifecycle_running();
runtime->render_thread_start(*app);
runtime->ui_thread_start(*app);
}
void install_debug_gl_callbacks()
{
#ifdef _DEBUG
glad_set_pre_callback(_pre_call_callback);
glad_set_post_callback(_post_call_callback);
#endif
}
void initialize_wintab(HWND hWnd, bool sandboxed)
{
auto* tablet = bound_wacom_tablet();
if (!sandboxed)
{
LOG("init WinTab");
tablet->init(hWnd);
}
else
{
LOG("SKIP init WinTab");
}
}
void set_main_window_icon(HWND hWnd)
{
LOG("change icon");
SendMessage(
hWnd,
WM_SETICON,
ICON_SMALL,
(LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1)));
}
void restore_window_placement(HWND hWnd, int show_command)
{
WINDOWPLACEMENT wp;
GetWindowPlacement(hWnd, &wp);
wp.showCmd = show_command;
SetWindowPlacement(hWnd, &wp);
}
void run_main_message_loop()
{
MSG msg;
auto* app = bound_app();
LOG("start main loop");
while (lifecycle_is_running())
{
auto present = app->animate || app->redraw ?
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
if (msg.message == WM_QUIT)
mark_lifecycle_stopped();
if (present)
{
DispatchMessage(&msg);
TranslateMessage(&msg);
}
drain_main_thread_tasks();
}
}
void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTANCE hInst)
{
retained_wacom_tablet().terminate();
UnregisterClass(startup.window_class.lpszClassName, hInst);
LogRemote::I.stop();
}
}
void bind_app(App* app) noexcept
{
App::I = app;
@@ -207,29 +115,7 @@ int run_main_application(int argc, char** argv)
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, HINSTANCE instance, SplashScreen& splash)
{
auto* app = bound_app();
register_touch_window(retained_main_window_handle_ref());
wglMakeCurrent(NULL, NULL);
initialize_runtime_threads();
install_debug_gl_callbacks();
initialize_wintab(retained_main_window_handle_ref(), retained_main_window_sandboxed());
set_main_window_icon(retained_main_window_handle_ref());
app->ui_sync();
restore_window_placement(retained_main_window_handle_ref(), startup.show_command);
if (start_in_vr)
app->vr_start();
LOG("show main window");
SetForegroundWindow(retained_main_window_handle_ref());
splash.dismiss();
run_main_message_loop();
shutdown_main_window_runtime(startup, instance);
run_bound_main_window_runtime(startup, start_in_vr, instance, splash);
}
}