From 4236529a437ea738a2f8004b20dcb6f9f863445b Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Wed, 3 Jun 2026 23:19:41 +0800 Subject: [PATCH 1/4] Add Tier-0 imgui.app facade and app_minimal example imgui.app owns the full GLFW/OpenGL3 lifecycle; consumers supply only a per-frame UI callback. run() is an inline header-style template (UI as a template parameter, no dependency) and export imports imgui.core. Register src/app.cppm in mcpp.toml sources and add the examples/app_minimal Tier-0 consumer. --- examples/app_minimal/mcpp.toml | 8 +++ examples/app_minimal/src/main.cpp | 11 ++++ mcpp.toml | 1 + src/app.cppm | 98 +++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 examples/app_minimal/mcpp.toml create mode 100644 examples/app_minimal/src/main.cpp create mode 100644 src/app.cppm diff --git a/examples/app_minimal/mcpp.toml b/examples/app_minimal/mcpp.toml new file mode 100644 index 0000000..137de97 --- /dev/null +++ b/examples/app_minimal/mcpp.toml @@ -0,0 +1,8 @@ +[package] +name = "imgui-app-minimal" +version = "0.1.0" +description = "Tier-0 imgui.app facade consumer" +license = "MIT" + +[dependencies] +imgui = { path = "../.." } diff --git a/examples/app_minimal/src/main.cpp b/examples/app_minimal/src/main.cpp new file mode 100644 index 0000000..1f7c1a5 --- /dev/null +++ b/examples/app_minimal/src/main.cpp @@ -0,0 +1,11 @@ +import imgui.core; +import imgui.app; + +// Tier-0: imgui.app owns the whole lifecycle; we only supply the per-frame UI. +int main() { + return ImGui::App::run([] { + ImGui::Begin("hi"); + ImGui::TextUnformatted("imgui.app facade"); + ImGui::End(); + }); +} diff --git a/mcpp.toml b/mcpp.toml index 56b3cb1..77109cc 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -12,6 +12,7 @@ path = "src/core.cppm" [build] sources = [ "src/core.cppm", + "src/app.cppm", "src/backends/backend.cppm", "src/backends/platform_glfw.cppm", "src/backends/renderer_opengl3.cppm", diff --git a/src/app.cppm b/src/app.cppm new file mode 100644 index 0000000..c4100b6 --- /dev/null +++ b/src/app.cppm @@ -0,0 +1,98 @@ +export module imgui.app; + +import std; // private: std::println for init diagnostics +export import imgui.core; // consumers get the ImGui::* surface for free +import imgui.backend.glfw_opengl3; // private: the default concrete backend + +// Tier-0 convenience facade. +// +// `imgui.app` owns the entire window/context lifecycle so a consumer only has to +// supply a per-frame UI callback. It is deliberately a header-style inline +// template in the module interface: the UI callback type is a template +// parameter, so no dependency is needed and the call is fully +// inlined. For more control, drop down to the Tier-1 `imgui.backend` contract or +// the Tier-2 explicit `imgui.backend.` module. +export namespace ImGui::App { + struct Options { + int width = 1280; + int height = 720; + const char* title = "mcpp imgui app"; + }; + + // Runs the full GLFW/OpenGL3 lifecycle, calling `ui()` once per frame. + // Returns 0 on a clean exit, nonzero on an initialization failure (the + // backend's last error is printed in that case). + template + int run(Options opts, Ui&& ui) { + using Backend = ImGui::Backend::GlfwOpenGL3; + + if (!Backend::InitGlfw()) { + const auto error = Backend::LastError(); + std::println( + "imgui.app: glfwInit failed: GLFW error {} ({})", + error.code, + error.description != nullptr ? error.description : "no description" + ); + return 1; + } + + auto* window = Backend::CreateWindow(opts.width, opts.height, opts.title); + if (window == nullptr) { + const auto error = Backend::LastError(); + std::println( + "imgui.app: window creation failed: GLFW error {} ({})", + error.code, + error.description != nullptr ? error.description : "no description" + ); + Backend::TerminateGlfw(); + return 2; + } + + Backend::MakeContextCurrent(window); + Backend::SwapInterval(1); + + ImGuiContext* context = ImGui::CreateContext(); + ImGui::SetCurrentContext(context); + + if (!Backend::Init(window)) { + const auto error = Backend::LastError(); + std::println( + "imgui.app: backend init failed: GLFW error {} ({})", + error.code, + error.description != nullptr ? error.description : "no description" + ); + ImGui::DestroyContext(context); + Backend::DestroyWindow(window); + Backend::TerminateGlfw(); + return 3; + } + + while (!Backend::WindowShouldClose(window)) { + Backend::PollEvents(); + Backend::NewFrame(); + + ImGui::NewFrame(); + ui(); + ImGui::Render(); + + const auto framebuffer = Backend::FramebufferSize(window); + Backend::Viewport(0, 0, framebuffer.width, framebuffer.height); + Backend::ClearColor(0.10f, 0.10f, 0.12f, 1.0f); + Backend::ClearColorBuffer(); + Backend::RenderDrawData(ImGui::GetDrawData()); + Backend::SwapBuffers(window); + } + + Backend::Shutdown(); + ImGui::DestroyContext(context); + Backend::DestroyWindow(window); + Backend::TerminateGlfw(); + return 0; + } + + // Convenience overload using default Options. + template + int run(Ui&& ui) { + return run(Options{}, static_cast(ui)); + } +} From 08fddc76b7fdddd2f534289b9e8605b99d1adfe6 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Wed, 3 Jun 2026 23:19:52 +0800 Subject: [PATCH 2/4] CI: set Linux default toolchain as unpinned-model transition step A fresh mcpp bootstrap defaults to a musl-static toolchain that cannot link the host X11/GL runtime on Linux. The package does not pin a toolchain in mcpp.toml; set an explicit environment default in CI on Linux only instead. Remove once mcpp bootstrap defaults to glibc. --- .github/workflows/ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 682d775..91f1d5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,6 +61,16 @@ jobs: xlings update xlings install + # Transition step: a fresh mcpp bootstrap currently defaults to a + # musl-static toolchain, which cannot link the host X11/GL runtime on + # Linux. The package intentionally does not pin a toolchain in mcpp.toml; + # we set an explicit environment default here instead. Remove this once + # mcpp's bootstrap default becomes a glibc toolchain. + - name: Set default toolchain (env) + if: runner.os == 'Linux' + shell: bash + run: mcpp toolchain default gcc@16.1.0 + - name: Show mcpp version shell: bash run: mcpp --version From 77e6e8c2df2416a8171f543c303e42763f44e101 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Wed, 3 Jun 2026 23:19:52 +0800 Subject: [PATCH 3/4] Docs: unpinned-toolchain model, three-tier UX, and lock policy Document that the package pins no toolchain (mcpp resolves the environment/default) and that the GL runtime is closed by mcpp/mcpp-index (compat.glx-runtime), not bundled. Add imgui.app to the README modules list as Tier-0 (Tier-1 auto via imgui.backend contract, Tier-2 explicit imgui.backend.). Rewrite design doc 8.1 to the unpinned model and add the consumer-UX-and-lock sub-design doc. --- .../docs/2026-06-03-consumer-ux-and-lock.md | 187 ++++++++++++++++++ ...-06-03-imgui-backend-abstraction-design.md | 20 +- README.md | 39 +++- docs/architecture.md | 19 ++ 4 files changed, 254 insertions(+), 11 deletions(-) create mode 100644 .agents/docs/2026-06-03-consumer-ux-and-lock.md diff --git a/.agents/docs/2026-06-03-consumer-ux-and-lock.md b/.agents/docs/2026-06-03-consumer-ux-and-lock.md new file mode 100644 index 0000000..97125cc --- /dev/null +++ b/.agents/docs/2026-06-03-consumer-ux-and-lock.md @@ -0,0 +1,187 @@ +# imgui-m: Consumer UX, Unpinned Toolchain, and Lock Policy + +> 创建: 2026-06-03 · Owner: sunrisepeak · 仓库: mcpplibs/imgui-m +> 关联 Master Plan: `/home/speak/workspace/github/agentdocs/2026-06-03-mcpp-ecosystem-architecture-plan.md` +> (本文是该计划工作流 **W3 (imgui-m)** 的子设计文档,见 Master Plan §3.3 / §6) + +本文记录 imgui-m 侧的三件事:不锁定工具链(unpinned)的决定与理由、三档递进式 +消费者 UX(默认 `imgui.app` / 自动契约 / 显式后端模块)、以及 lockfile 策略 +(GL 运行时闭合需要 `compat.glx-runtime`)。所有决定都对齐 Master Plan 的 +「Capability → Resolution Plan,两平面 + 三档收敛」统一模型,不为单次验收做特殊设计。 + +--- + +## 1. 不锁定工具链(unpinned) + +### 决定 + +本包**不在任何 `mcpp.toml` 中声明 `[toolchain]`**(根包与所有 examples 均不 pin)。 +mcpp 解析环境/默认工具链;GL 运行时由 mcpp/mcpp-index 闭合 +(`compat.glx-runtime`,Linux 上由 `compat.glfw` 传递依赖引入),**不由本包打包**。 + +### 理由 + +- **关注点分离 / 两平面**(Master Plan §2.1–2.2)。工具链与 GL 主机运行时属于 + *环境/主机平面*,不是包的内容。包在 `mcpp.toml` 里 pin 工具链会把环境决定 + 硬编码进可移植的包元数据,破坏「同一包在不同环境用合适工具链」的能力。 +- **三档模型的"默认档"**:零配置可达,意图而非机制。包不写工具链 = 让 mcpp 用 + 环境默认;需要时由消费者/CI 在*环境层*显式叠加(见 §4),而不是在包里固化。 +- **可移植**:macOS / Windows runner 不需要也不应继承 Linux 的工具链选择;不 pin + 让每个平台各自解析本地最优工具链。 + +--- + +## 2. 三档递进式消费者 UX + +对齐 Master Plan §2.3「默认(零配置) → 自动匹配(意图驱动) → 显式指定(局部叠加)」。 + +### Tier-0 — 默认 / `imgui.app` facade(最少代码) + +`imgui.app` 拥有完整的窗口/上下文生命周期,消费者只提供每帧 UI 回调。 +模块接口里以 inline header-style 模板提供 `run`,UI 回调为模板参数,**无 `` +依赖**。`export import imgui.core;`,因此消费者免费拿到 `ImGui::*` 表面。 + +```cpp +import imgui.core; +import imgui.app; + +int main() { + return ImGui::App::run([] { + ImGui::Begin("hi"); + ImGui::TextUnformatted("imgui.app facade"); + ImGui::End(); + }); +} +``` + +API: + +```cpp +export namespace ImGui::App { + struct Options { int width = 1280; int height = 720; const char* title = "mcpp imgui app"; }; + template int run(Options opts, Ui&& ui); // 完整生命周期 + template int run(Ui&& ui); // 用默认 Options +} +``` + +`run()` 流程:InitGlfw → CreateWindow(RecommendedGlConfig) → MakeContextCurrent → +SwapInterval(1) → CreateContext/SetCurrentContext → Backend::Init → 循环 +(PollEvents / Backend::NewFrame / ImGui::NewFrame / `ui()` / ImGui::Render / +FramebufferSize+Viewport+ClearColor(0.10,0.10,0.12,1)+ClearColorBuffer+ +RenderDrawData(GetDrawData)+SwapBuffers)→ 退出时 Shutdown / DestroyContext / +DestroyWindow / TerminateGlfw。成功返回 0,初始化失败返回非 0(并打印 +`Backend::LastError`)。 + +### Tier-1 — 自动 / `imgui.backend` 契约(意图驱动) + +针对 `BackendApi` 概念与共享类型写**后端无关**代码;具体后端是哪个由上层选择。 +任何满足契约的后端都能代入,消费者代码不变。 + +```cpp +import imgui.core; +import imgui.backend; // BackendApi 概念 + GlConfig/Error/FbSize + RecommendedGlConfig() + +template +void frame(typename Backend::Window* w) { + Backend::PollEvents(); + Backend::NewFrame(); + ImGui::NewFrame(); + /* ... UI ... */ + ImGui::Render(); + const auto fb = Backend::FramebufferSize(w); + Backend::Viewport(0, 0, fb.width, fb.height); + Backend::RenderDrawData(ImGui::GetDrawData()); + Backend::SwapBuffers(w); +} +``` + +### Tier-2 — 显式 / `imgui.backend.` 模块 + alias(完全控制) + +显式导入一个具体后端模块并 alias;换后端 = 换 import + 改一行 alias,其余不变。 + +```cpp +import imgui.core; +import imgui.backend.glfw_opengl3; +using Backend = ImGui::Backend::GlfwOpenGL3; // 换后端只需改这两行 + +int main() { + Backend::InitGlfw(); + auto* window = Backend::CreateWindow(960, 540, "demo"); + Backend::MakeContextCurrent(window); + ImGuiContext* ctx = ImGui::CreateContext(); + ImGui::SetCurrentContext(ctx); + Backend::Init(window); + while (!Backend::WindowShouldClose(window)) { /* 手写帧循环 */ } + Backend::Shutdown(); + ImGui::DestroyContext(ctx); + Backend::DestroyWindow(window); + Backend::TerminateGlfw(); +} +``` + +复杂度单调下沉:Tier-0 最少代码 → Tier-2 最大控制。三档共享同一套 +`RecommendedGlConfig()` 跨平台 GL/GLSL 默认与同一后端契约。 + +--- + +## 3. Lockfile 策略 + +### 策略 + +`mcpp.lock` 必须反映当前 index 的解析结果。GL 运行时闭合依赖 `compat.glx-runtime` +(Linux 上 `compat.glfw` 的传递依赖,把 host libGL/GLX 软链进 install 目录, +供 rpath/RUNPATH 透传)。lock 应随当前 index 重生成,不手工编辑。 + +重生成方式:仓库根目录 `mcpp update`(清空 lock)→ `mcpp build`(重解析并重写 lock)。 + +### 实测现状(诚实记录) + +- `compat.glx-runtime@2026.06.03` 确已存在于 index + (`compat.glfw.lua` linux `deps` 含 `compat.glx-runtime`),并在 BMI 解析的依赖树中可见。 +- 但用 **mcpp 0.0.46** 重生成后,根 `mcpp.lock` 仅记录**直接依赖** + (`compat.glfw` / `compat.imgui` / `compat.opengl`),**未**展开 `compat.glx-runtime` + 等传递依赖。即:当前 lock 格式只锁直接依赖,GL 运行时闭合发生在解析/链接期, + 而非在 lock 文本里展开。 +- 另注:本仓 `.gitignore` 忽略 `mcpp.lock`,故 lock 不入库。 + +这对应 Master Plan §1 的 **R3**(lock 相对 index 的 glx-runtime 接线 stale)与 +W1 的链接闭合修复(R2 rpath)。**完整的传递闭合(让 glx-runtime 显式落到 lock / +RUNPATH)需要 mcpp 核心侧的解析/rpath 工作就绪**;imgui-m 侧已做到「不 pin + 用当前 +index 重生成 lock + 文档化策略」。待 mcpp 核心改动落地后,重生成的 lock/链接将 +自然纳入 glx-runtime,无需改本包。 + +--- + +## 4. CI 过渡步骤(显式环境默认,非特殊设计) + +Linux CI 今天会红,根因是 Master Plan **R1**:全新机器 mcpp bootstrap 默认装 +musl-static 工具链,无法链接 glibc 世界的 X11/GL 栈。 + +修复:在 `.github/workflows/ci.yml` 的 "Install project tools" 之后、"Build library" +之前,加**一步**(仅 Linux): + +```yaml +- name: Set default toolchain (env) + if: runner.os == 'Linux' + shell: bash + run: mcpp toolchain default gcc@16.1.0 +``` + +为什么这不是"特殊设计":这是在 *CI 环境层* 显式声明环境默认工具链 +(三档模型里的"显式档,局部叠加"),与最终架构一致;**包仍不 pin**。它是过渡而非长期: +待 Master Plan W1(mcpp bootstrap 默认改为 glibc 工具链)合并后,此步可直接删除。 +macOS / Windows 已通过,保持不变;矩阵与 `continue-on-error` 设置不变。 + +--- + +## 5. 与 Master Plan 的映射 + +| 本文小节 | Master Plan 对应 | +|---|---| +| §1 不 pin 工具链 | §2.1 两平面 / §2.3 三档默认档 / §1 R1 | +| §2 三档 UX | §2.3 三档递进;W3 的 `imgui.app` (Tier-0) | +| §3 lock 策略 | §1 R3(lock stale)/ W1 运行闭合(R2 rpath)/ §6 W3 | +| §4 CI 过渡步骤 | §7 注 100–102(过渡:CI 环境默认,W1 后删) | + +本文是 Master Plan 列出的三份子文档之一(imgui-m 侧);另两份分别在 mcpp 核心 +(runtime-closure-and-toolchain-defaults)与 mcpp-index(capability-runtime-metadata)。 diff --git a/.agents/docs/2026-06-03-imgui-backend-abstraction-design.md b/.agents/docs/2026-06-03-imgui-backend-abstraction-design.md index 704e144..dbe419f 100644 --- a/.agents/docs/2026-06-03-imgui-backend-abstraction-design.md +++ b/.agents/docs/2026-06-03-imgui-backend-abstraction-design.md @@ -245,17 +245,17 @@ int main() { ## 8. 跨平台工程化 -### 8.1 toolchain +### 8.1 toolchain(不锁定 / unpinned) -`mcpp.toml` 增加 macOS / Windows toolchain 条目(与 mcpp 支持的工具链命名对齐), -例如: +本包**不在任何 `mcpp.toml` 中锁定 toolchain**(没有 `[toolchain]` 段)。 +mcpp 解析环境/默认 toolchain;GL 运行时由 mcpp/mcpp-index 闭合 +(`compat.glx-runtime`,Linux 上由 `compat.glfw` 传递依赖引入),不由本包打包。 -```toml -[toolchain] -linux = "llvm@20.1.7" -macos = "llvm@20.1.7" # 或系统 clang;最终以 mcpp-index 可用项为准 -windows = "llvm@20.1.7" -``` +> 过渡说明:目前全新机器上 mcpp bootstrap 默认是 musl-static 工具链,无法链接 +> 宿主 X11/GL 运行时。CI 在 Linux 上用一个显式环境默认步骤 +> (`mcpp toolchain default gcc@16.1.0`)绕开,而不是在 `mcpp.toml` 里锁定。 +> 待 mcpp bootstrap 默认改为 glibc 工具链后即可移除该步骤。详见 +> `.agents/docs/2026-06-03-consumer-ux-and-lock.md`。 ### 8.2 GL/GLSL 配置 @@ -291,7 +291,7 @@ windows = "llvm@20.1.7" - `src/core.cppm` → 补 `ImVec4` 等(§7) - `tests/backend_test.cpp` → 针对新表面 + `static_assert(BackendApi<...>)` - `examples/minimal_window`、`examples/glfw_opengl3` → 统一 `Backend::` 用法 + `RecommendedGlConfig()` -- `mcpp.toml`(toolchain + sources)、`.github/workflows/ci.yml`(矩阵) +- `mcpp.toml`(sources;**不含** toolchain)、`.github/workflows/ci.yml`(矩阵 + Linux 环境默认 toolchain 过渡步骤) - `docs/architecture.md`、`README.md` 同步 > 旧的 `imgui.backend.glfw` / `imgui.backend.opengl3` 自由函数命名空间被 diff --git a/README.md b/README.md index 2111c8b..e95c39d 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,19 @@ module interfaces for the core API plus GLFW/OpenGL3 backend entry points. ## Modules +Three tiers of consumer UX: + +- **Tier-0** `imgui.app` — the convenience facade. Owns the whole window/context + lifecycle; you supply only a per-frame UI callback. +- **Tier-1** automatic via the `imgui.backend` contract — write backend-agnostic + code against the `BackendApi` concept and shared types. +- **Tier-2** explicit `imgui.backend.` — import a concrete backend module + and alias it (`using Backend = ...;`); swap backend with one import + alias. + +- `imgui.app` + - Tier-0 facade. `ImGui::App::run(opts, ui)` / `ImGui::App::run(ui)` drive the + full GLFW/OpenGL3 lifecycle using the default backend. `export import`s + `imgui.core` so a consumer gets the `ImGui::*` surface for free. - `imgui.core` - Core Dear ImGui context, frame, widget, and draw-data APIs. - `imgui.backend` @@ -39,6 +52,12 @@ The root package depends on: The repository does not vendor Dear ImGui sources. Source and header files come from compat packages through mcpp dependency metadata. +### Toolchain and GL runtime + +The package does not pin a toolchain; mcpp resolves the environment/default +toolchain. The GL runtime is closed by mcpp/mcpp-index (`compat.glx-runtime`, +pulled in transitively by `compat.glfw` on Linux), not bundled by this package. + ## Quick Start ```bash @@ -86,7 +105,24 @@ mcpp run imgui = "0.0.1" ``` -Then import the modules you need: +Then import the modules you need. + +Tier-0 (`imgui.app` facade — least code): + +```cpp +import imgui.core; +import imgui.app; + +int main() { + return ImGui::App::run([] { + ImGui::Begin("hi"); + ImGui::TextUnformatted("imgui.app facade"); + ImGui::End(); + }); +} +``` + +Tier-2 (explicit backend module + alias — full control): ```cpp import imgui.core; @@ -135,6 +171,7 @@ The `0.0.1` release state is verified with mcpp `0.0.44`: - `mcpp build` - `mcpp test` - `cd examples/basic && mcpp run` +- `cd examples/app_minimal && mcpp build` - `cd examples/minimal_window && mcpp build` - `cd examples/glfw_opengl3 && mcpp build` diff --git a/docs/architecture.md b/docs/architecture.md index 06336fc..202537a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -5,7 +5,12 @@ upstream source ownership in compat packages. ## Goals +- Offer a three-tier consumer UX: + - Tier-0 `imgui.app` — convenience facade owning the full lifecycle. + - Tier-1 automatic via the `imgui.backend` contract (`BackendApi` concept). + - Tier-2 explicit `imgui.backend.` module + alias. - Let consumers use explicit module imports: + - `import imgui.app;` (Tier-0 facade; `export import`s `imgui.core`) - `import imgui.core;` - `import imgui.backend;` (generic abstraction layer: shared types + contract) - `import imgui.backend.platform.glfw;` @@ -27,6 +32,7 @@ upstream source ownership in compat packages. |-- mcpp.toml |-- src/ | |-- core.cppm +| |-- app.cppm (Tier-0 imgui.app facade) | `-- backends/ | |-- backend.cppm (abstraction layer: types + BackendApi) | |-- platform_glfw.cppm (GLFW platform piece) @@ -39,6 +45,7 @@ upstream source ownership in compat packages. | `-- backend_test.cpp `-- examples/ |-- basic/ + |-- app_minimal/ |-- minimal_window/ `-- glfw_opengl3/ ``` @@ -52,6 +59,7 @@ backend implementation translation units, and depends on compat packages: [build] sources = [ "src/core.cppm", + "src/app.cppm", "src/backends/backend.cppm", "src/backends/platform_glfw.cppm", "src/backends/renderer_opengl3.cppm", @@ -69,6 +77,10 @@ compat.opengl = "2026.05.31" The wrapper package does not vendor `third_party/imgui`. Upstream headers, core sources, and backend files are read from `compat.imgui`. +The package does not pin a toolchain; mcpp resolves the environment/default +toolchain. The GL runtime is closed by mcpp/mcpp-index (`compat.glx-runtime`, +a transitive dependency of `compat.glfw` on Linux), not bundled by this package. + ## Module Wrappers `src/core.cppm` adapts upstream `imgui.h` internally, then exports selected @@ -80,6 +92,12 @@ internally and export explicit wrapper functions. The implementation `.cpp` files compile upstream backend sources from `compat.imgui/backends` so consumers do not need to copy backend sources into their own package. +`src/app.cppm` (`imgui.app`) is the Tier-0 facade. It `export import`s +`imgui.core` and privately imports `imgui.backend.glfw_opengl3`, exposing +`ImGui::App::run(...)` as an inline header-style template (the UI callback is a +template parameter, so there is no `` dependency). It drives the +full lifecycle so a consumer supplies only a per-frame UI callback. + ## Validation Primary proof points: @@ -88,6 +106,7 @@ Primary proof points: mcpp build mcpp test cd examples/basic && mcpp run +cd ../app_minimal && mcpp build cd ../minimal_window && mcpp build cd ../glfw_opengl3 && mcpp build ``` From 4db2d01c544acaabc1eeedb2104f0514c8cc9767 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Wed, 3 Jun 2026 23:26:24 +0800 Subject: [PATCH 4/4] ci: install gcc 16.1.0 before setting it as default (transition step) --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91f1d5f..7bcd830 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,7 +69,9 @@ jobs: - name: Set default toolchain (env) if: runner.os == 'Linux' shell: bash - run: mcpp toolchain default gcc@16.1.0 + run: | + mcpp toolchain install gcc 16.1.0 + mcpp toolchain default gcc@16.1.0 - name: Show mcpp version shell: bash