Skip to content

feat(apps): formalize dual-mode App framework with tier-based auto re…#18

Merged
Charliechen114514 merged 2 commits into
mainfrom
feat/app-dual-mode
Jul 1, 2026
Merged

feat(apps): formalize dual-mode App framework with tier-based auto re…#18
Charliechen114514 merged 2 commits into
mainfrom
feat/app-dual-mode

Conversation

@Charliechen114514

Copy link
Copy Markdown
Member

…solution

Replace the builtin: string-prefix hack with a LaunchKind-based dual-mode framework so the same App runs either as a detached process or as an in-process builtin panel, decided by hardware tier (Low -> in-process to save RAM on i.MX6ULL, Mid/High -> detached for isolation).

  • LaunchKind enum (Auto/DetachedProcess/BuiltinPanel) on AppEntry
  • IBuiltinPanel interface (IPanel style) + BuiltinPanelRegistry (map-based, non-owning; aex has no named-factory variant to reuse)
  • AboutPanel implements IBuiltinPanel; wire the missing grid entry (builtin:about was unreachable before)
  • Drop the if(id=="about") chain; dispatch by entry.launch_kind
  • loadAppsConfig merges builtin registry + discovered manifests; Auto resolves to BuiltinPanel only when prefer_inprocess && a builtin impl exists, otherwise DetachedProcess (no silent builtin fallback)
  • CalculatorBuiltinPanel adapter: same CalculatorPanel source compiled two ways (standalone exe + in-process builtin) -> dual-mode verified
  • HardwareTierCapabilities::prefer_inprocess_apps (Low/Unknown = true)
  • manifest launch_kind (auto/detached/builtin) parsed by AppDiscoverer
  • Tests: BuiltinPanelRegistry (5), launch_kind parsing (3), full green
  • Docs: milestone_04 sec 6, new milestone_07 (third-party plan)

Architecture exception: desktop compiles apps/calculator/calculator_panel.cpp and links cfdesktop_calculator_parser (desktop->apps reverse dep, violates layering spirit). Top-level CMake reorders apps before desktop to resolve the target. Debt tracked in milestone_07 for migration to a neutral lib.

…solution

Replace the builtin: string-prefix hack with a LaunchKind-based dual-mode
framework so the same App runs either as a detached process or as an
in-process builtin panel, decided by hardware tier (Low -> in-process to
save RAM on i.MX6ULL, Mid/High -> detached for isolation).

- LaunchKind enum (Auto/DetachedProcess/BuiltinPanel) on AppEntry
- IBuiltinPanel interface (IPanel style) + BuiltinPanelRegistry
  (map-based, non-owning; aex has no named-factory variant to reuse)
- AboutPanel implements IBuiltinPanel; wire the missing grid entry
  (builtin:about was unreachable before)
- Drop the if(id=="about") chain; dispatch by entry.launch_kind
- loadAppsConfig merges builtin registry + discovered manifests; Auto
  resolves to BuiltinPanel only when prefer_inprocess && a builtin impl
  exists, otherwise DetachedProcess (no silent builtin fallback)
- CalculatorBuiltinPanel adapter: same CalculatorPanel source compiled
  two ways (standalone exe + in-process builtin) -> dual-mode verified
- HardwareTierCapabilities::prefer_inprocess_apps (Low/Unknown = true)
- manifest launch_kind (auto/detached/builtin) parsed by AppDiscoverer
- Tests: BuiltinPanelRegistry (5), launch_kind parsing (3), full green
- Docs: milestone_04 sec 6, new milestone_07 (third-party plan)

Architecture exception: desktop compiles apps/calculator/calculator_panel.cpp
and links cfdesktop_calculator_parser (desktop->apps reverse dep, violates
layering spirit). Top-level CMake reorders apps before desktop to resolve
the target. Debt tracked in milestone_07 for migration to a neutral lib.
…ng pointers

The registry is a process-wide singleton holding non-owning pointers; each
test registered stack-local FakePanels that dangled after the test ended.
AllIncludesRegistered then iterated all() across the accumulated dangling
pointers, calling through freed vtables — SegFault on Clang, access
violation (0xc0000005) on MSVC. GCC survived by UB luck.

Switch to a TEST_F fixture that clears the registry in SetUp, so each test
starts empty and all() only sees live panels. Tightens AllIncludesRegistered
to assert size==1 (deterministic across compilers).

Adds BuiltinPanelRegistry::clear() (test/reset only; production registers
once at startup and never clears).
@Charliechen114514 Charliechen114514 merged commit 563ff51 into main Jul 1, 2026
6 checks passed
@Charliechen114514 Charliechen114514 deleted the feat/app-dual-mode branch July 1, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant