Thin Windows entry, preview shell, and platform legacy state

This commit is contained in:
2026-06-17 00:42:50 +02:00
parent 9b1e593477
commit 5fdc9a9dd6
17 changed files with 368 additions and 216 deletions

View File

@@ -166,6 +166,8 @@ set(PP_PANOPAINTER_APP_SOURCES
src/legacy_document_session_services.h
src/platform_legacy/legacy_platform_services.cpp
src/platform_legacy/legacy_platform_services.h
src/platform_legacy/legacy_platform_state.cpp
src/platform_legacy/legacy_platform_state.h
src/version.cpp
)

View File

@@ -1,7 +1,7 @@
# PanoPainter Modernization Roadmap
Status: live
Last updated: 2026-06-16
Last updated: 2026-06-17
This roadmap is now architecture-first.
The active execution queue lives in `docs/modernization/tasks.md`.
@@ -80,18 +80,34 @@ What is still carrying too much live ownership:
Current hotspot files:
- `src/canvas.cpp`: 17 lines
- `src/app_layout.cpp`: 125 lines
- `src/app_layout.cpp`: 109 lines
- `src/canvas_modes.cpp`: 1 line
- `src/node.cpp`: 12 lines
- `src/main.cpp`: 87 lines
- `src/main.cpp`: 10 lines
- `src/node_panel_brush.cpp`: 2 lines
- `src/node_stroke_preview.cpp`: 160 lines
- `src/node_canvas.cpp`: 85 lines
- `src/node_stroke_preview.cpp`: 76 lines
- `src/node_canvas.cpp`: 69 lines
- `src/app.cpp`: 94 lines
- `src/app_dialogs.cpp`: 95 lines
Latest slice:
- The live Windows entry shell now routes through
`run_main_application(...)` in
`src/platform_windows/windows_runtime_shell.*`, leaving `src/main.cpp` as a
minimal entry wrapper around `main(...)` and `WinMain(...)`.
- Retained legacy storage-path state now lives in
`src/platform_legacy/legacy_platform_state.*` instead of staying inline in
`src/platform_legacy/legacy_platform_services.cpp`, which trims another
process-global platform-state pocket out of the legacy platform shell.
- The remaining `NodeStrokePreview` clone-init, stroke-frame planning,
mix-pass adapter wiring, sample-pass adapter wiring, and immediate-draw
request construction now route through
`src/legacy_node_stroke_preview_runtime_services.*`,
`src/legacy_node_stroke_preview_draw_services.*`, and
`src/legacy_node_stroke_preview_sample_services.*`, leaving
`src/node_stroke_preview.cpp` as a thinner live adapter.
- `NodeCanvas::handle_event()` now routes through
`handle_legacy_node_canvas_event(...)` in
`src/legacy_canvas_tool_services.*`, leaving `src/node_canvas.cpp` as a much

View File

@@ -1,7 +1,7 @@
# Modernization Task Tracker
Status: live
Last updated: 2026-06-16
Last updated: 2026-06-17
This file now tracks only active architecture work.
Completed, blocked, and superseded task history moved to
@@ -36,10 +36,10 @@ Completed, blocked, and superseded task history moved to
- `pp_legacy_paint_document`: 7 files, about 5709 lines
- `pp_legacy_app`: 20 files, about 4368 lines
- `pp_legacy_ui_core`: 20 files, about 3770 lines
- The biggest single-file choke points are still `src/canvas_modes.cpp`,
`src/node.cpp`,
`src/main.cpp`, `src/node_panel_brush.cpp`, `src/node_stroke_preview.cpp`,
`src/node_canvas.cpp`, `src/app.cpp`, and `src/app_dialogs.cpp`.
- The biggest remaining single-file pressure is no longer the old entrypoint
shell files; it now sits mostly in retained legacy service layers behind
`src/node_stroke_preview.cpp`, `src/app.cpp`, `src/app_dialogs.cpp`, and the
extracted canvas/platform containment files.
- The platform boundary is not finished:
- `pp_platform_api` still compiles Apple implementation files
- `platform_apple` no longer reaches `App::I` directly, and Linux FPS title
@@ -391,6 +391,13 @@ Current slice:
render-target validation, viewport/clear-color save-restore, and immediate
runtime request assembly out of the live node file and leaves
`src/node_stroke_preview.cpp` at 160 lines.
- `NodeStrokePreview` clone-finalize setup, stroke-frame planning, mix-pass
adapter wiring, sample-pass adapter wiring, and the remaining
immediate-draw request construction now also route through
`src/legacy_node_stroke_preview_runtime_services.*`,
`src/legacy_node_stroke_preview_draw_services.*`, and
`src/legacy_node_stroke_preview_sample_services.*`, which leaves
`src/node_stroke_preview.cpp` at 76 lines.
- `CanvasModeGrid` plus `ActionModeGrid` undo/redo now also live in
`src/legacy_canvas_mode_helpers.cpp` instead of staying inline in
`src/canvas_modes.cpp`, which leaves the live canvas-modes file as a
@@ -759,6 +766,9 @@ Current slice:
loop, and shutdown cleanup now also lives in
`src/platform_windows/windows_runtime_shell.*` instead of `src/main.cpp`,
which reduces the entry TU to a much smaller composition root
- the remaining Windows app shell in `main(...)` now also routes through
`run_main_application(...)` in `src/platform_windows/windows_runtime_shell.*`,
which reduces `src/main.cpp` to a minimal `main`/`WinMain` wrapper
- prepared-file background work now runs through an `AppRuntime`-owned worker
queue instead of a retained static worker in `src/app_events.cpp`
- canvas async import/export/save/open background work now also runs through an
@@ -1115,6 +1125,9 @@ Current slice:
- retained GLFW window hooks and the non-Linux fallback storage-path return now
also route through retained local state helpers instead of reading `App::I`
directly in those method bodies
- retained storage-path state now also lives in
`src/platform_legacy/legacy_platform_state.*` instead of staying inline in
`src/platform_legacy/legacy_platform_services.cpp`
- retained Apple callback injection and broader `platform_legacy` singleton
reach are still open
- The remaining Win32 shell wrappers for close, async lock/swap,

View File

@@ -187,6 +187,33 @@ bool execute_legacy_node_stroke_preview_mix_pass(
return mix_result.ok;
}
bool execute_legacy_node_stroke_preview_mix_pass(
const Brush& brush,
glm::vec2 preview_size,
RTT& mixer_rtt,
glm::vec2 bb_min,
glm::vec2 bb_sz,
Sampler& linear_sampler,
Texture2D& background_texture,
Texture2D& stroke_texture,
Texture2D& dual_texture,
std::function<void()> draw_mix)
{
return execute_legacy_node_stroke_preview_mix_pass(
LegacyNodeStrokePreviewMixPassExecutionRequest {
.brush = brush,
.preview_size = preview_size,
.mixer_rtt = mixer_rtt,
.bb_min = bb_min,
.bb_sz = bb_sz,
.linear_sampler = linear_sampler,
.background_texture = background_texture,
.stroke_texture = stroke_texture,
.dual_texture = dual_texture,
.draw_mix = std::move(draw_mix),
});
}
bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequest& request)
{
return request.bind_dual_pass_textures &&

View File

@@ -61,6 +61,18 @@ struct LegacyNodeStrokePreviewMixPassExecutionRequest {
[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass(
const LegacyNodeStrokePreviewMixPassExecutionRequest& request);
[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass(
const Brush& brush,
glm::vec2 preview_size,
RTT& mixer_rtt,
glm::vec2 bb_min,
glm::vec2 bb_sz,
Sampler& linear_sampler,
Texture2D& background_texture,
Texture2D& stroke_texture,
Texture2D& dual_texture,
std::function<void()> draw_mix);
[[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes(
const LegacyNodeStrokePreviewLiveRenderRequest& request);

View File

@@ -14,6 +14,7 @@
#include "legacy_canvas_stroke_shader_services.h"
#include "legacy_canvas_stroke_services.h"
#include "legacy_node_stroke_preview_execution_services.h"
#include "legacy_node_stroke_preview_sample_services.h"
#include "legacy_ui_gl_dispatch.h"
#include "paint_renderer/compositor.h"
#include "renderer_gl/opengl_capabilities.h"
@@ -299,6 +300,19 @@ std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke
});
}
std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
const Stroke& stroke,
float zoom,
glm::vec2 mixer_size)
{
return plan_legacy_node_stroke_preview_stroke_frames(
LegacyNodeStrokePreviewStrokeComputeRequest {
.stroke = stroke,
.zoom = zoom,
.mixer_size = mixer_size,
});
}
bool execute_legacy_node_stroke_preview_immediate_runtime(
const LegacyNodeStrokePreviewImmediateRuntimeRequest& request)
{
@@ -375,6 +389,92 @@ bool execute_legacy_node_stroke_preview_immediate_runtime(
return sequence_ok;
}
void initialize_legacy_node_stroke_preview_clone(Node* dest)
{
static_cast<NodeStrokePreview*>(dest)->init_controls();
}
bool execute_legacy_node_stroke_preview_immediate_draw(NodeStrokePreview& preview)
{
if (preview.m_size.x == 0 || preview.m_size.y == 0) {
return false;
}
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(
pp::panopainter::LegacyNodeStrokePreviewImmediateDrawRequest {
.brush = preview.m_brush,
.preview_size = preview.m_size,
.zoom = preview.root()->m_zoom,
.min_flow = preview.m_min_flow,
.stroke_max_size_override = preview.m_max_size,
.pad_override = preview.m_pad_override,
.camera_fov = Canvas::I->m_cam_fov,
.camera_rot = Canvas::I->m_cam_rot,
.render_device_features = pp::panopainter::stroke_preview_render_device_features(),
.preview_rtt = preview.m_rtt,
.preview_rtt_mixer = preview.m_rtt_mixer,
.preview_stroke_texture = preview.m_tex,
.preview_dual_texture = preview.m_tex_dual,
.preview_background_texture = preview.m_tex_background,
.preview_image_texture = preview.m_tex_preview,
.linear_sampler = preview.m_sampler_linear,
.repeat_sampler = preview.m_sampler_linear_repeat,
.prepare_render_target = [&] {
pp::panopainter::apply_legacy_node_stroke_preview_viewport(
0,
0,
preview.m_rtt.getWidth(),
preview.m_rtt.getHeight());
preview.m_rtt.bindFramebuffer();
preview.m_rtt.clear();
pp::panopainter::bind_legacy_node_stroke_preview_live_samplers(
preview.m_sampler_mipmap,
preview.m_sampler_linear,
preview.m_sampler_linear_repeat);
},
.finish_render_target = [&] {
preview.m_rtt.unbindFramebuffer();
},
.compute_frames = [&](const Stroke& stroke, float frame_zoom) {
return plan_legacy_node_stroke_preview_stroke_frames(
stroke,
frame_zoom,
glm::vec2(preview.m_rtt.getWidth(), preview.m_rtt.getHeight()));
},
.draw_samples = [&](std::array<vertex_t, 4>& shapes, Texture2D& texture, bool copy_stroke_destination) {
return pp::panopainter::execute_legacy_node_stroke_preview_sample_pass(
preview.m_rtt,
shapes,
preview.m_brush_shape,
texture,
copy_stroke_destination);
},
.draw_mix = [&](const glm::vec2& bb_min, const glm::vec2& bb_sz) {
pp::panopainter::execute_legacy_node_stroke_preview_mix_pass(
*preview.m_brush,
preview.m_size,
preview.m_rtt_mixer,
bb_min,
bb_sz,
preview.m_sampler_linear,
preview.m_tex_background,
preview.m_tex,
preview.m_tex_dual,
[&] {
preview.m_plane.draw_fill();
});
},
.draw_checkerboard = [&] {
preview.m_plane.draw_fill();
},
.draw_composite = [&] {
preview.m_plane.draw_fill();
},
});
assert(sequence_ok);
return sequence_ok;
}
} // namespace pp::panopainter
std::atomic_int NodeStrokePreview::s_instances{ 0 };

View File

@@ -16,6 +16,9 @@
#include <memory>
#include <vector>
class Node;
class NodeStrokePreview;
namespace pp::panopainter {
[[nodiscard]] pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexcept;
@@ -63,6 +66,11 @@ struct LegacyNodeStrokePreviewStrokeComputeRequest {
[[nodiscard]] std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
const LegacyNodeStrokePreviewStrokeComputeRequest& request);
[[nodiscard]] std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
const Stroke& stroke,
float zoom,
glm::vec2 mixer_size);
struct LegacyNodeStrokePreviewImmediateRuntimeRequest {
const std::shared_ptr<Brush>& brush;
glm::vec2 preview_size {};
@@ -128,4 +136,7 @@ struct LegacyNodeStrokePreviewImmediateDrawRequest {
[[nodiscard]] bool execute_legacy_node_stroke_preview_immediate_runtime(
const LegacyNodeStrokePreviewImmediateRuntimeRequest& request);
void initialize_legacy_node_stroke_preview_clone(Node* dest);
[[nodiscard]] bool execute_legacy_node_stroke_preview_immediate_draw(NodeStrokePreview& preview);
} // namespace pp::panopainter

View File

@@ -1,6 +1,7 @@
#include "pch.h"
#include "legacy_node_stroke_preview_sample_services.h"
#include "legacy_node_stroke_preview_runtime_services.h"
namespace pp::panopainter {
@@ -57,4 +58,41 @@ glm::vec4 execute_legacy_node_stroke_preview_sample_pass(
return result.dirty_bounds;
}
glm::vec4 execute_legacy_node_stroke_preview_sample_pass(
RTT& preview_rtt,
std::array<vertex_t, 4>& vertices,
DynamicShape& brush_shape,
Texture2D& blend_tex,
bool copy_stroke_destination)
{
return execute_legacy_node_stroke_preview_sample_pass(
LegacyNodeStrokePreviewSamplePassRequest {
.target_size = { static_cast<float>(preview_rtt.getWidth()), static_cast<float>(preview_rtt.getHeight()) },
.vertices = vertices,
.brush_shape = brush_shape,
.copy_stroke_destination = copy_stroke_destination,
.bind_destination_texture = [&] {
bind_legacy_node_stroke_preview_destination_texture(blend_tex);
},
.copy_framebuffer_to_destination_texture = [](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
copy_legacy_node_stroke_preview_destination_texture_region(
src_x,
src_y,
dst_x,
dst_y,
width,
height);
},
.unbind_destination_texture = [&] {
unbind_legacy_node_stroke_preview_destination_texture(blend_tex);
},
});
}
} // namespace pp::panopainter

View File

@@ -25,4 +25,11 @@ struct LegacyNodeStrokePreviewSamplePassRequest {
[[nodiscard]] glm::vec4 execute_legacy_node_stroke_preview_sample_pass(
const LegacyNodeStrokePreviewSamplePassRequest& request);
[[nodiscard]] glm::vec4 execute_legacy_node_stroke_preview_sample_pass(
RTT& preview_rtt,
std::array<vertex_t, 4>& vertices,
DynamicShape& brush_shape,
Texture2D& blend_tex,
bool copy_stroke_destination);
} // namespace pp::panopainter

View File

@@ -1,84 +1,10 @@
#include "pch.h"
#include "log.h"
#include "shader.h"
#include "shape.h"
#include "texture.h"
#include "image.h"
#include "app.h"
#include "canvas.h"
#include "platform_windows/windows_bootstrap_helpers.h"
#include "platform_windows/windows_platform_services.h"
#include "platform_windows/windows_lifecycle_shell.h"
#include "platform_windows/windows_runtime_shell.h"
#include "platform_windows/windows_splash.h"
#include "platform_windows/windows_stylus_input.h"
#include "platform_windows/windows_window_shell.h"
#include "platform_windows/windows_vr_shell.h"
#include "../resource.h"
#include "wacom.h"
#include "abr.h"
using pp::platform::windows::retained_state;
int main(int argc, char** argv)
{
auto& state = retained_state();
state.hInst = GetModuleHandle(NULL);
App::I = new App();
App::I->set_platform_services(&pp::platform::windows::platform_services());
App::I->initLog();
pp::platform::windows::init_shcore_API();
pp::platform::windows::initialize_stylus_input();
if (pp::platform::windows::SetProcessDpiAwareness_fn)
pp::platform::windows::SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE);
pp::platform::windows::ensure_runtime_data_directory();
pp::platform::windows::SplashScreen splash(GetModuleHandle(NULL));
pp::platform::windows::initialize_retained_input_state();
pp::platform::windows::setup_exception_handler();
pp::platform::windows::read_WMI_info();
App::I->create();
auto startup = pp::platform::windows::initialize_main_window_startup_state();
auto context = pp::platform::windows::OpenGlWindowContext {};
switch (pp::platform::windows::initialize_main_window_and_gl(startup, state.hWnd, state.hInst, state.window_title, context))
{
case pp::platform::windows::MainStartupResult::Ok:
break;
case pp::platform::windows::MainStartupResult::GladLoadFailure:
return 0;
case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
return -1;
}
//wglSwapIntervalEXT(1);
bool start_in_vr = false;
if (argc > 1)
{
switch (const_hash(argv[1]))
{
case const_hash("convert"):
App::I->initShaders();
App::I->cmd_convert(argv[2], argv[3]);
return 0;
case const_hash("-vrmode"):
start_in_vr = true;
break;
default:
break;
}
}
pp::platform::windows::run_main_window_runtime(startup, start_in_vr, splash);
return pp::platform::windows::run_main_application(argc, argv);
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

View File

@@ -28,8 +28,7 @@ void NodeStrokePreview::clone_children(Node* dest) const
void NodeStrokePreview::clone_finalize(Node* dest) const
{
NodeStrokePreview* n = (NodeStrokePreview*)dest;
n->init_controls();
pp::panopainter::initialize_legacy_node_stroke_preview_clone(dest);
}
void NodeStrokePreview::init_controls()
@@ -40,21 +39,18 @@ void NodeStrokePreview::init_controls()
void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
{
const auto& b = m_brush;
const bool mix_ok = pp::panopainter::execute_legacy_node_stroke_preview_mix_pass(
pp::panopainter::LegacyNodeStrokePreviewMixPassExecutionRequest {
.brush = *b,
.preview_size = m_size,
.mixer_rtt = m_rtt_mixer,
.bb_min = bb_min,
.bb_sz = bb_sz,
.linear_sampler = m_sampler_linear,
.background_texture = m_tex_background,
.stroke_texture = m_tex,
.dual_texture = m_tex_dual,
.draw_mix = [this] {
*m_brush,
m_size,
m_rtt_mixer,
bb_min,
bb_sz,
m_sampler_linear,
m_tex_background,
m_tex,
m_tex_dual,
[this] {
m_plane.draw_fill();
},
});
assert(mix_ok);
}
@@ -64,97 +60,26 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(
Texture2D& blend_tex,
bool copy_stroke_destination)
{
const glm::vec2 size = { m_rtt.getWidth(), m_rtt.getHeight() };
return pp::panopainter::execute_legacy_node_stroke_preview_sample_pass(
pp::panopainter::LegacyNodeStrokePreviewSamplePassRequest {
.target_size = size,
.vertices = P,
.brush_shape = m_brush_shape,
.copy_stroke_destination = copy_stroke_destination,
.bind_destination_texture = [&] {
pp::panopainter::bind_legacy_node_stroke_preview_destination_texture(blend_tex);
},
.copy_framebuffer_to_destination_texture = [](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
pp::panopainter::copy_legacy_node_stroke_preview_destination_texture_region(
src_x,
src_y,
dst_x,
dst_y,
width,
height);
},
.unbind_destination_texture = [&] {
pp::panopainter::unbind_legacy_node_stroke_preview_destination_texture(blend_tex);
},
});
m_rtt,
P,
m_brush_shape,
blend_tex,
copy_stroke_destination);
}
std::vector<NodeStrokePreview::StrokeFrame> NodeStrokePreview::stroke_draw_compute(const Stroke& stroke, float zoom) const
{
return pp::panopainter::plan_legacy_node_stroke_preview_stroke_frames(
pp::panopainter::LegacyNodeStrokePreviewStrokeComputeRequest {
.stroke = stroke,
.zoom = zoom,
.mixer_size = glm::vec2(m_rtt.getWidth(), m_rtt.getHeight()),
});
stroke,
zoom,
glm::vec2(m_rtt.getWidth(), m_rtt.getHeight()));
}
void NodeStrokePreview::draw_stroke_immediate()
{
if (m_size.x == 0 || m_size.y == 0)
return;
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(
pp::panopainter::LegacyNodeStrokePreviewImmediateDrawRequest {
.brush = m_brush,
.preview_size = m_size,
.zoom = root()->m_zoom,
.min_flow = m_min_flow,
.stroke_max_size_override = m_max_size,
.pad_override = m_pad_override,
.camera_fov = Canvas::I->m_cam_fov,
.camera_rot = Canvas::I->m_cam_rot,
.render_device_features = pp::panopainter::stroke_preview_render_device_features(),
.preview_rtt = m_rtt,
.preview_rtt_mixer = m_rtt_mixer,
.preview_stroke_texture = m_tex,
.preview_dual_texture = m_tex_dual,
.preview_background_texture = m_tex_background,
.preview_image_texture = m_tex_preview,
.linear_sampler = m_sampler_linear,
.repeat_sampler = m_sampler_linear_repeat,
.prepare_render_target = [&] {
pp::panopainter::apply_legacy_node_stroke_preview_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
m_rtt.bindFramebuffer();
m_rtt.clear();
pp::panopainter::bind_legacy_node_stroke_preview_live_samplers(
m_sampler_mipmap,
m_sampler_linear,
m_sampler_linear_repeat);
},
.finish_render_target = [&] {
m_rtt.unbindFramebuffer();
},
.compute_frames = [&](const Stroke& stroke, float frame_zoom) {
return stroke_draw_compute(stroke, frame_zoom);
},
.draw_samples = [&](std::array<vertex_t, 4>& shapes, Texture2D& texture, bool copy_stroke_destination) {
return stroke_draw_samples(shapes, texture, copy_stroke_destination);
},
.draw_mix = [&](const glm::vec2& bb_min, const glm::vec2& bb_sz) {
stroke_draw_mix(bb_min, bb_sz);
},
.draw_checkerboard = [&] {
m_plane.draw_fill();
},
.draw_composite = [&] {
m_plane.draw_fill();
},
});
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(*this);
assert(sequence_ok);
}

View File

@@ -7,11 +7,14 @@
#include "texture.h"
#include "legacy_node_stroke_preview_draw_services.h"
#include "legacy_node_stroke_preview_execution_services.h"
#include "legacy_node_stroke_preview_runtime_services.h"
class NodeStrokePreview : public NodeBorder
{
using StrokeFrame = pp::panopainter::LegacyNodeStrokePreviewFrame;
friend bool pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(NodeStrokePreview& preview);
static RTT m_rtt;
static RTT m_rtt_mixer;
static Texture2D m_tex; // blending tmp texture

View File

@@ -1,5 +1,6 @@
#include "pch.h"
#include "platform_legacy/legacy_platform_services.h"
#include "platform_legacy/legacy_platform_state.h"
#include "app.h"
#include "legacy_ui_gl_dispatch.h"
@@ -131,25 +132,6 @@ struct RetainedLegacyGlfwWindowState final {
}
#endif
struct RetainedLegacyStoragePaths final {
pp::platform::PlatformStoragePaths storage_paths;
};
[[nodiscard]] RetainedLegacyStoragePaths& active_legacy_storage_paths()
{
static RetainedLegacyStoragePaths state = [] {
RetainedLegacyStoragePaths retained;
retained.storage_paths = {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
return retained;
}();
return state;
}
#if defined(__IOS__) || defined(__OSX__)
[[nodiscard]] NSMutableArray<NSString*>* apple_file_types_array(const std::vector<std::string>& file_types)
{
@@ -169,7 +151,6 @@ struct RetainedLegacyAppleState final {
decltype(App::I->osx_view) osx_view = nullptr;
decltype(App::I->osx_app) osx_app = nullptr;
#endif
pp::platform::PlatformStoragePaths storage_paths;
};
[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state()
@@ -179,21 +160,9 @@ struct RetainedLegacyAppleState final {
#ifdef __IOS__
retained.ios_view = App::I->ios_view;
retained.ios_app = App::I->ios_app;
retained.storage_paths = {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
#elif defined(__OSX__)
retained.osx_view = App::I->osx_view;
retained.osx_app = App::I->osx_app;
retained.storage_paths = {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
#endif
return retained;
}();
@@ -208,7 +177,7 @@ struct RetainedLegacyAppleState final {
#elif defined(__OSX__)
[apple_state.osx_app init_dirs];
#endif
return apple_state.storage_paths;
return active_legacy_storage_paths();
}
[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& active_apple_document_platform_services()
@@ -406,7 +375,7 @@ public:
{},
};
#else
return active_legacy_storage_paths().storage_paths;
return pp::platform::legacy::active_legacy_storage_paths();
#endif
}

View File

@@ -0,0 +1,30 @@
#include "pch.h"
#include "platform_legacy/legacy_platform_state.h"
#include "app.h"
namespace pp::platform::legacy {
namespace {
struct RetainedLegacyStoragePaths final {
pp::platform::PlatformStoragePaths storage_paths;
};
}
[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths()
{
static RetainedLegacyStoragePaths state = [] {
RetainedLegacyStoragePaths retained;
retained.storage_paths = {
App::I->data_path,
App::I->work_path,
App::I->rec_path,
App::I->tmp_path,
};
return retained;
}();
return state.storage_paths;
}
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "platform_api/platform_services.h"
namespace pp::platform::legacy {
[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths();
}

View File

@@ -7,6 +7,7 @@
#include "platform_windows/windows_bootstrap_helpers.h"
#include "platform_windows/windows_lifecycle_shell.h"
#include "platform_windows/windows_platform_services.h"
#include "platform_windows/windows_stylus_input.h"
#include "platform_windows/windows_window_shell.h"
#include "wacom.h"
#include "../resource.h"
@@ -101,6 +102,68 @@ void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTAN
}
int run_main_application(int argc, char** argv)
{
auto& state = retained_state();
state.hInst = GetModuleHandle(NULL);
App::I = new App();
App::I->set_platform_services(&pp::platform::windows::platform_services());
App::I->initLog();
pp::platform::windows::init_shcore_API();
pp::platform::windows::initialize_stylus_input();
if (pp::platform::windows::SetProcessDpiAwareness_fn)
pp::platform::windows::SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE);
pp::platform::windows::ensure_runtime_data_directory();
pp::platform::windows::SplashScreen splash(state.hInst);
pp::platform::windows::initialize_retained_input_state();
pp::platform::windows::setup_exception_handler();
pp::platform::windows::read_WMI_info();
App::I->create();
auto startup = pp::platform::windows::initialize_main_window_startup_state();
auto context = pp::platform::windows::OpenGlWindowContext {};
switch (pp::platform::windows::initialize_main_window_and_gl(startup, state.hWnd, state.hInst, state.window_title, context))
{
case pp::platform::windows::MainStartupResult::Ok:
break;
case pp::platform::windows::MainStartupResult::GladLoadFailure:
return 0;
case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
return -1;
}
//wglSwapIntervalEXT(1);
bool start_in_vr = false;
if (argc > 1)
{
switch (const_hash(argv[1]))
{
case const_hash("convert"):
App::I->initShaders();
App::I->cmd_convert(argv[2], argv[3]);
return 0;
case const_hash("-vrmode"):
start_in_vr = true;
break;
default:
break;
}
}
pp::platform::windows::run_main_window_runtime(startup, start_in_vr, splash);
return 0;
}
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash)
{
auto& state = retained_state();

View File

@@ -5,6 +5,7 @@
namespace pp::platform::windows {
int run_main_application(int argc, char** argv);
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash);
}