change built-in component names
This commit is contained in:
@@ -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
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user