add late_draw schedule

This commit is contained in:
wooshings
2026-10-28 22:07:55 -07:00
parent 939841d143
commit b522a28069
4 changed files with 15 additions and 10 deletions
+8 -3
View File
@@ -8,19 +8,24 @@ package shoal
// POST_UPDATE / (signal_system clears the buses here) // POST_UPDATE / (signal_system clears the buses here)
// PRE_DRAW \ // PRE_DRAW \
// DRAW | every frame, the raylib drawing part // DRAW | every frame, the raylib drawing part
// POST_DRAW / // LATE_DRAW / (LATE_DRAW runs after every DRAW system, for overlays)
// POST_DRAW once per frame, after all drawing
// DESTROY once, after the loop exits and the window closes // DESTROY once, after the loop exits and the window closes
// //
// DefaultPlugin opens the raylib frame at PRE_DRAW (BeginDrawing + clear) and // DefaultPlugin opens the raylib frame at PRE_DRAW (BeginDrawing + clear) and
// closes it at POST_DRAW (EndDrawing), so DRAW is where your draw calls go. // closes it at POST_DRAW (EndDrawing), so DRAW is where your draw calls go.
// renderers that flush accumulated draw state (like the ui plugin replaying
// microui's command list) go on LATE_DRAW, so they run after all game DRAW
// systems but still inside the raylib frame.
STARTUP :: 0 STARTUP :: 0
PRE_UPDATE :: 1 PRE_UPDATE :: 1
UPDATE :: 2 UPDATE :: 2
POST_UPDATE :: 3 POST_UPDATE :: 3
PRE_DRAW :: 4 PRE_DRAW :: 4
DRAW :: 5 DRAW :: 5
POST_DRAW :: 6 LATE_DRAW :: 6
DESTROY :: 7 POST_DRAW :: 7
DESTROY :: 8
// easing ids for the (wip) Tween.ease field. see tween.odin, nothing reads // easing ids for the (wip) Tween.ease field. see tween.odin, nothing reads
// them yet // them yet
+3 -1
View File
@@ -79,7 +79,8 @@ get_world :: proc(app: ^App) -> ^World {
// run every plugin (in registration order), then the STARTUP systems once, // run every plugin (in registration order), then the STARTUP systems once,
// then the frame loop: PRE_UPDATE -> UPDATE -> POST_UPDATE -> PRE_DRAW -> // then the frame loop: PRE_UPDATE -> UPDATE -> POST_UPDATE -> PRE_DRAW ->
// DRAW -> POST_DRAW, over and over until rl.WindowShouldClose() says stop, // DRAW -> LATE_DRAW -> POST_DRAW, over and over until rl.WindowShouldClose()
// says stop,
// and finally the DESTROY systems. world systems get handed the app's own // and finally the DESTROY systems. world systems get handed the app's own
// world, the same one run() is holding. there's no second copy // world, the same one run() is holding. there's no second copy
run :: proc(app: ^App) { run :: proc(app: ^App) {
@@ -94,6 +95,7 @@ run :: proc(app: ^App) {
for s in get_system(app, POST_UPDATE) {run_system(app, s)} for s in get_system(app, POST_UPDATE) {run_system(app, s)}
for s in get_system(app, PRE_DRAW) {run_system(app, s)} for s in get_system(app, PRE_DRAW) {run_system(app, s)}
for s in get_system(app, DRAW) {run_system(app, s)} for s in get_system(app, DRAW) {run_system(app, s)}
for s in get_system(app, LATE_DRAW) {run_system(app, s)}
for s in get_system(app, POST_DRAW) {run_system(app, s)} for s in get_system(app, POST_DRAW) {run_system(app, s)}
} }
+1 -1
View File
@@ -87,7 +87,7 @@ begin :: proc(state: ^RLMU_State = global_state) -> ^mu.Context {
} }
// tell microui the frame is finished, then replay its command list as raylib // tell microui the frame is finished, then replay its command list as raylib
// draw calls (and close any lingering scissor). UIPlugin runs it at POST_DRAW // draw calls (and close any lingering scissor). UIPlugin runs it at LATE_DRAW
end :: proc(state := global_state) { end :: proc(state := global_state) {
// Tell mui that we're done drawing ui // Tell mui that we're done drawing ui
mu.end(&state.ctx) mu.end(&state.ctx)
+3 -5
View File
@@ -11,16 +11,14 @@ ui_ctx: ^ml.Context
// //
// STARTUP init() bakes the microui atlas into a texture // STARTUP init() bakes the microui atlas into a texture
// PRE_DRAW begin() forwards raylib input, starts the frame, stashes ui_ctx // PRE_DRAW begin() forwards raylib input, starts the frame, stashes ui_ctx
// POST_DRAW the frame's temp arena is freed, then end() renders the ui // LATE_DRAW end() renders the ui after all game drawing, still in-frame
// POST_DRAW the frame's temp arena is freed
// DESTROY destroy() unloads the atlas texture // DESTROY destroy() unloads the atlas texture
//
// (systems within a schedule run in registration order, so POST_DRAW frees
// the arena first and renders second)
UIPlugin :: proc(app: ^ecs.App) { UIPlugin :: proc(app: ^ecs.App) {
ecs.add_system(app, ecs.STARTUP, proc() {init()}) ecs.add_system(app, ecs.STARTUP, proc() {init()})
ecs.add_system(app, ecs.POST_DRAW, proc() {free_all(context.temp_allocator)}) ecs.add_system(app, ecs.POST_DRAW, proc() {free_all(context.temp_allocator)})
ecs.add_system(app, ecs.PRE_DRAW, proc() {ui_ctx = begin()}) ecs.add_system(app, ecs.PRE_DRAW, proc() {ui_ctx = begin()})
ecs.add_system(app, ecs.POST_DRAW, proc() {end()}) ecs.add_system(app, ecs.LATE_DRAW, proc() {end()})
ecs.add_system(app, ecs.DESTROY, proc() {destroy()}) ecs.add_system(app, ecs.DESTROY, proc() {destroy()})
} }