change built-in component names

This commit is contained in:
wooshings
2026-10-27 21:26:29 -07:00
parent c45e6b1dbb
commit 16bf55f093
4 changed files with 45 additions and 12 deletions
+4 -4
View File
@@ -5,7 +5,7 @@ import rl "vendor:raylib"
// what the app's window opens with: size, title, and the clear color. // what the app's window opens with: size, title, and the clear color.
// DefaultPlugin opens the window from it at STARTUP and paints the clear // DefaultPlugin opens the window from it at STARTUP and paints the clear
// color at PRE_DRAW // color at PRE_DRAW
WindowComponent :: struct { Window :: struct {
width: i32, width: i32,
height: i32, height: i32,
title: string, title: string,
@@ -13,20 +13,20 @@ WindowComponent :: struct {
} }
// the mouse position, refreshed every UPDATE by DefaultPlugin // the mouse position, refreshed every UPDATE by DefaultPlugin
CursorComponent :: struct { Cursor :: struct {
position: rl.Vector2, position: rl.Vector2,
} }
// a texture DefaultPlugin draws at DRAW, placed by the same entity's // a texture DefaultPlugin draws at DRAW, placed by the same entity's
// TransformComponent (so every sprite entity needs a Transform component // TransformComponent (so every sprite entity needs a Transform component
// too) // too)
SpriteComponent :: struct { Sprite :: struct {
texture: rl.Texture2D, texture: rl.Texture2D,
} }
// 2D translation + rotation, read back by draw_sprite when it places the // 2D translation + rotation, read back by draw_sprite when it places the
// entity's SpriteComponent // entity's SpriteComponent
TransformComponent :: struct { Transform :: struct {
translation: rl.Vector2, translation: rl.Vector2,
rotation: f32, rotation: f32,
} }
+8 -8
View File
@@ -24,7 +24,7 @@ DefaultPlugin :: proc(app: ^App) {
add_system(app, UPDATE, run_timers) add_system(app, UPDATE, run_timers)
add_system(app, UPDATE, update_cursor_position) add_system(app, UPDATE, update_cursor_position)
add_system(app, PRE_DRAW, proc(world: ^World) {rl.BeginDrawing() add_system(app, PRE_DRAW, proc(world: ^World) {rl.BeginDrawing()
window, _ := single(world, WindowComponent) window, _ := single(world, Window)
rl.ClearBackground(window.background)}) rl.ClearBackground(window.background)})
add_system(app, POST_DRAW, proc() {rl.EndDrawing()}) add_system(app, POST_DRAW, proc() {rl.EndDrawing()})
add_system(app, DESTROY, proc() {rl.CloseWindow()}) add_system(app, DESTROY, proc() {rl.CloseWindow()})
@@ -36,25 +36,25 @@ DefaultPlugin :: proc(app: ^App) {
add_component( add_component(
world, world,
display, display,
WindowComponent{width = 800, height = 600, title = "shoal window", background = rl.BLACK}, Window{width = 800, height = 600, title = "shoal window", background = rl.BLACK},
) )
cursor := spawn_entity(world) cursor := spawn_entity(world)
add_component(world, cursor, CursorComponent) add_component(world, cursor, Cursor)
} }
@(private) @(private)
update_cursor_position :: proc(world: ^World) { update_cursor_position :: proc(world: ^World) {
cursor, _ := single(world, CursorComponent) cursor, _ := single(world, Cursor)
cursor.position = rl.GetMousePosition() cursor.position = rl.GetMousePosition()
} }
@(private) @(private)
draw_sprite :: proc(world: ^World) { draw_sprite :: proc(world: ^World) {
components := slice(world, SpriteComponent) components := slice(world, Sprite)
entities := slice_entity(world, SpriteComponent) entities := slice_entity(world, Sprite)
for &v, i in components { for &v, i in components {
sprite_transform := get_component(world, entities[i], TransformComponent) sprite_transform := get_component(world, entities[i], Transform)
rl.DrawTexture( rl.DrawTexture(
v.texture, v.texture,
i32(sprite_transform.translation.x), i32(sprite_transform.translation.x),
@@ -66,7 +66,7 @@ draw_sprite :: proc(world: ^World) {
@(private) @(private)
startup_window :: proc(world: ^World) { startup_window :: proc(world: ^World) {
window, _ := single(world, WindowComponent) window, _ := single(world, Window)
rl.InitWindow(window.width, window.height, strings.clone_to_cstring(window.title)) rl.InitWindow(window.width, window.height, strings.clone_to_cstring(window.title))
rl.SetTargetFPS(60) rl.SetTargetFPS(60)
} }
+11
View File
@@ -22,6 +22,8 @@ rlmu_init :: proc "contextless" () {
global_state = new(RLMU_State) global_state = new(RLMU_State)
} }
// bake the default microui atlas into a raylib texture and set up the mui
// context (text metrics + clipboard callbacks). UIPlugin runs it at STARTUP
init :: proc(state := global_state) { init :: proc(state := global_state) {
// Allocate an array of 32 bit pixel colors for the atlas used by mui // Allocate an array of 32 bit pixel colors for the atlas used by mui
// An atlas is a big image packed with multiple smaller images. Like a sprite sheet! // An atlas is a big image packed with multiple smaller images. Like a sprite sheet!
@@ -62,11 +64,15 @@ init :: proc(state := global_state) {
state.ctx.textbox_state.get_clipboard = get_clipboard state.ctx.textbox_state.get_clipboard = get_clipboard
} }
// unload the atlas texture. UIPlugin runs it at DESTROY
destroy :: proc(state := global_state) { destroy :: proc(state := global_state) {
// Free atlas texture // Free atlas texture
rl.UnloadTexture(state.atlas) rl.UnloadTexture(state.atlas)
} }
// forward this frame's raylib input (text, mouse, keys) to microui and start
// the frame. returns the context to build ui against. UIPlugin runs it at
// PRE_DRAW and hands the result to get_ctx()
begin :: proc(state: ^RLMU_State = global_state) -> ^mu.Context { begin :: proc(state: ^RLMU_State = global_state) -> ^mu.Context {
// Forward all input from raylib to mui // Forward all input from raylib to mui
// We need to tell mui what keys are pressed, where the mouse is etc so the ui can react accordingly // We need to tell mui what keys are pressed, where the mouse is etc so the ui can react accordingly
@@ -80,6 +86,8 @@ begin :: proc(state: ^RLMU_State = global_state) -> ^mu.Context {
return &state.ctx return &state.ctx
} }
// 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
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)
@@ -140,8 +148,11 @@ end :: proc(state := global_state) {
rl.EndScissorMode() rl.EndScissorMode()
} }
// init() with destroy() deferred to scope exit: set the ui up and tear it
// down around a block
@(deferred_in = destroy) @(deferred_in = destroy)
init_scope :: proc(state := global_state) -> ^mu.Context {init(state); return &state.ctx} init_scope :: proc(state := global_state) -> ^mu.Context {init(state); return &state.ctx}
// begin() with end() deferred to scope exit: a whole frame of ui in one block
@(deferred_in = end) @(deferred_in = end)
begin_scope :: proc(state := global_state) -> ^mu.Context {begin(state); return &state.ctx} begin_scope :: proc(state := global_state) -> ^mu.Context {begin(state); return &state.ctx}
+22
View File
@@ -1,9 +1,31 @@
package ui package ui
import ecs "../src"
import ml "vendor:microui" import ml "vendor:microui"
// the microui context UIPlugin refreshes every frame, nil until the first
// PRE_DRAW. use get_ctx() instead of touching it directly
ui_ctx: ^ml.Context ui_ctx: ^ml.Context
// wires the ui package into the app, in frame order:
//
// STARTUP init() bakes the microui atlas into a texture
// 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
// 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) {
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.PRE_DRAW, proc() {ui_ctx = begin()})
ecs.add_system(app, ecs.POST_DRAW, proc() {end()})
ecs.add_system(app, ecs.DESTROY, proc() {destroy()})
}
// the microui context for this frame. pass it to every microui call. valid
// from PRE_DRAW onwards (nil before the first frame)
get_ctx :: proc() -> ^ml.Context { get_ctx :: proc() -> ^ml.Context {
return ui_ctx return ui_ctx
} }