Split Application into Project + Application to support multiple windows under one project #2

Open
opened 2026-09-14 20:42:14 -07:00 by burkkyy · 1 comment
Owner

Problem

Application currently does two unrelated jobs: it owns the runtime (Window, Device, RenderContext, AssetRegistry — see Application::Impl in application.cpp) and it's the base class users subclass for lifecycle hooks (onCreate/onUpdate/onRender/onDestroy). Because of this, every Application gets its own Device and AssetRegistry, so there's no way to run multiple windows (e.g. an editor window + a game preview window) that share loaded assets and GPU resources.

Proposal

  • Project owns the shared runtime: Device and AssetRegistry. This is the thing a user would import/construct first.
  • Application becomes a lighter-weight, subclassable window: owns a Window + RenderContext, exposes the onCreate/onUpdate/onRender/onDestroy hooks, and references its parent Project for assets/device access.
  • A Project can own multiple Applications at once.

Blocker / required refactor

Device currently takes a Window* directly (device.hpp:40) and owns that window's vk::SurfaceKHR. That means device creation is 1:1 with a single window today. To make this work, Device needs to split into:

  1. A shared piece (VkInstance, physical/logical device, queues) — owned by Project.
  2. A per-window piece (surface, swapchain) — owned by each Application's RenderContext.

This is the bulk of the actual work; the Project/Application class split itself is comparatively small.

### Problem `Application` currently does two unrelated jobs: it owns the runtime (Window, Device, RenderContext, AssetRegistry — see `Application::Impl` in [application.cpp](engine/src/application.cpp#L46)) *and* it's the base class users subclass for lifecycle hooks (`onCreate`/`onUpdate`/`onRender`/`onDestroy`). Because of this, every `Application` gets its own `Device` and `AssetRegistry`, so there's no way to run multiple windows (e.g. an editor window + a game preview window) that share loaded assets and GPU resources. ### Proposal - **`Project`** owns the shared runtime: `Device` and `AssetRegistry`. This is the thing a user would import/construct first. - **`Application`** becomes a lighter-weight, subclassable window: owns a `Window` + `RenderContext`, exposes the `onCreate`/`onUpdate`/`onRender`/`onDestroy` hooks, and references its parent `Project` for assets/device access. - A `Project` can own multiple `Application`s at once. ### Blocker / required refactor `Device` currently takes a `Window*` directly (`device.hpp:40`) and owns that window's `vk::SurfaceKHR`. That means device creation is 1:1 with a single window today. To make this work, `Device` needs to split into: 1. A shared piece (VkInstance, physical/logical device, queues) — owned by `Project`. 2. A per-window piece (surface, swapchain) — owned by each `Application`'s `RenderContext`. This is the bulk of the actual work; the `Project`/`Application` class split itself is comparatively small.
burkkyy added this to the sophia project 2026-09-19 19:39:50 -07:00
burkkyy moved this to Blocked / Discussion in sophia on 2026-10-04 01:04:20 -07:00
Author
Owner

Moving to Blocked since no project requires multiple windows yet

Moving to Blocked since no project requires multiple windows yet
Sign in to join this conversation.