Skip to content

refactor(codegen): extract lifecycle/callback.zig from main_zig.zig (#183 step 8b) - #203

Merged
apotema merged 1 commit into
feat/183-split-main-zigfrom
refactor/183-extract-lifecycle-callback
May 25, 2026
Merged

apotema merged 1 commit into
feat/183-split-main-zigfrom
refactor/183-extract-lifecycle-callback

Conversation

@apotema

@apotema apotema commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Step 8b of the cut plan in docs/REFACTOR-PLAN-main-zig.md (#193). Moves the three callback-lifecycle builders -- buildCallbackInitCode, buildImmersiveEntryCode, buildCallbackCleanupCode -- from src/main_zig.zig to a new src/codegen/lifecycle/callback.zig submodule (252 lines, all 3 functions plus header doc).

  • main_zig.zig: 3817 -> 3636 lines (-181).
  • Re-export shim: pub const lifecycle_callback = @import("codegen/lifecycle/callback.zig"); plus three private aliases keep the orchestrator's call sites (lines 3315 / 3332 / 3447) unchanged.
  • HIGH-risk per the plan: the init builder mirrors buildSetupCode's call order across image-wiring -> conditional audio/font -> resource loads -> prefabs -> JSONC scenes + manifests + initial state -> setScene -> runner.setup -> plugin systems + controllers. Preserved exactly; verified by bit-identical diff below.

Why the still-here helpers stayed put

writeImageBackendWiring, writeAudioBackendWiring, writeFontBackendWiring, emitResourceLoad, and LoadStyle are dependencies of buildCallbackInitCode -- but the matching blocks/asset_wiring.zig + blocks/resource_loader.zig extractions (plan steps 4-5) haven't landed yet. Rather than churn them through an intermediate location, the new submodule reaches them through @import("../../main_zig.zig") and they were promoted from fn to pub fn (visibility only -- zero logic edit). When the block extractions land, the import flips and these revert to private.

pathToIdent is reached via scan.zig directly (already extracted in the PoC), avoiding an unnecessary main_zig.zig round-trip.

Verification

zig build                                              -> ok
zig build test --summary all                           -> 506/510 passed (4 skipped), exit 0
scripts/gen_all_examples.sh                            -> 8/9 examples generated
                                                          (sokol_imgui fails on baseline too -- missing labelle-imgui sibling)
bit-identical diff vs origin/feat/183-split-main-zig:
  - 58 generated .zig files (every main.zig / build.zig / test tree): 0 diffs
  - 90 non-deps files total (excluding flow_catalog.json timestamps): 0 diffs

Test plan

  • zig build succeeds
  • zig build test exit 0, 506/510 expected
  • Generated main.zig byte-identical across raylib / sokol / null / plugin-controllers / flows-smoke / asset-streaming-smoke / bgfx / wgpu
  • Sokol + asset-streaming-smoke (which exercise these builders most) confirmed byte-identical
  • Re-run scripts/gen_all_examples.sh against the umbrella after the parallel lifecycle/loop.zig PR lands

Coordination

A sibling agent is extracting src/codegen/lifecycle/loop.zig in parallel off the same umbrella. Different functions, non-overlapping line ranges in main_zig.zig. The re-export header will have a small mechanical merge at merge time (one extra pub const lifecycle_loop = ... line next to this PR's pub const lifecycle_callback = ...).

Builds on: #202 (umbrella feat/183-split-main-zig)
Refs: #183

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request extracts the callback-lifecycle code builders (buildCallbackInitCode, buildImmersiveEntryCode, and buildCallbackCleanupCode) from src/main_zig.zig into a dedicated submodule src/codegen/lifecycle/callback.zig. To avoid breaking existing orchestrator calls, these functions are re-exported in src/main_zig.zig. Additionally, several helper functions and types in src/main_zig.zig have been made public so they can be accessed by the new submodule. I have no feedback to provide as there are no review comments to assess.

@apotema
apotema marked this pull request as ready for review May 25, 2026 20:25
@cursor

cursor Bot commented May 25, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
HIGH-risk area per the refactor plan because init codegen order directly affects generated main.zig, but this PR is a pure move with re-exports and reported bit-identical codegen output.

Overview
Refactor (#183 step 8b): sokol/wasm/Android callback lifecycle codegen moves out of main_zig.zig into new src/codegen/lifecycle/callback.zig — buildCallbackInitCode, buildImmersiveEntryCode, and buildCallbackCleanupCode (init/cleanup template bodies plus Android immersive entry in sokol_main()).

main_zig.zig shrinks by ~181 lines and wires the orchestrator through lifecycle_callback re-exports so call sites stay the same. The new module still depends on helpers left in main_zig (write*BackendWiring, emitResourceLoad, etc.) until later block extractions; pathToIdent is imported from scan.zig directly.

Behavior is intended unchanged: init emission order (image wiring → audio/font → resources → scenes → runner/plugins) and error style (.catch_panic_style vs loop try) are preserved; PR claims byte-identical generated main.zig across backends.

Reviewed by Cursor Bugbot for commit 993f5f3. Bugbot is set up for automated code reviews on this repo. Configure here.

…part of #183)

Per the plan in #193. Moved buildCallbackInitCode +
buildImmersiveEntryCode + buildCallbackCleanupCode (sokol/wasm/Android
callback path) to src/codegen/lifecycle/callback.zig (252 lines).
Re-exported from main_zig.zig so callers in the orchestrator stay
unchanged.

HIGH-risk extraction per the plan -- preserves call order across the
preview-mode wiring constants and the wasm/Android conditional
branches. Verified bit-identical across all 8 working bundled
examples (scripts/gen_all_examples.sh).

The asset-wiring + resource-loader helpers (writeImageBackendWiring,
writeAudioBackendWiring, writeFontBackendWiring, emitResourceLoad,
LoadStyle) are still in main_zig.zig because the matching
blocks/asset_wiring.zig + blocks/resource_loader.zig extractions
(plan steps 4-5) haven't landed yet; the new submodule reaches them
through @import("../../main_zig.zig") in the meantime. When those
blocks land, the import flips to the new module paths and the pub
markers in main_zig.zig revert to private.

Refs: #183
Builds on: #202 (umbrella)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@apotema
apotema force-pushed the refactor/183-extract-lifecycle-callback branch from 79e8b58 to 993f5f3 Compare May 25, 2026 20:33
@apotema
apotema merged commit 3e28430 into feat/183-split-main-zig May 25, 2026
1 check passed
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