ecs-test/main.odin

198 lines
5.6 KiB
Odin

package main
import "base:runtime"
import "base:intrinsics"
import "core:log"
import "core:mem"
import "core:time"
import "core:fmt"
import "core:testing"
import "core:strings"
import "core:path/filepath"
import "core:math"
import "core:math/linalg"
import "core:os"
import "core:math/rand"
import stbi "vendor:stb/image"
import sa "sokol/app"
import sh "sokol/helpers"
import "ecs"
Vec2 :: [2]f32
Vec3 :: [3]f32
Vec4 :: [4]f32
Globals :: struct {
coordinator: ecs.Coordinator,
physics_system: ^ecs.PhysicsSystem,
render_system: ^ecs.RenderSystem,
entities: []ecs.EntityID,
}
g: ^Globals
mouse_move: Vec2
key_down: #sparse[sa.Keycode]bool
default_context: runtime.Context
main :: proc() {
context.logger = log.create_console_logger()
tracking_allocator: mem.Tracking_Allocator
mem.tracking_allocator_init(&tracking_allocator, context.allocator)
context.allocator = mem.tracking_allocator(&tracking_allocator)
defer reset_tracking_allocator(&tracking_allocator)
default_context = context
sa.run({
window_title = "Ecs Test",
allocator = sa.Allocator(sh.allocator(&default_context)),
logger = sa.Logger(sh.logger(&default_context)),
init_cb = init_cb,
frame_cb = frame_cb,
cleanup_cb = cleanup_cb,
event_cb = event_cb,
})
}
init_cb :: proc "c" () {
context = default_context
sa.show_mouse(false)
sa.lock_mouse(true)
g = new(Globals)
g.coordinator = ecs.coordinator_create()
create_scene()
}
frame_cb:: proc "c" () {
context = default_context
if key_down[.ESCAPE] {
sa.quit()
return
}
dt := f32(sa.frame_duration())
ecs.physics_system_update(g.physics_system, &g.coordinator, dt)
ecs.render_system_update(g.render_system, &g.coordinator, dt, key_down, mouse_move)
mouse_move = {}
}
cleanup_cb :: proc "c" () {
context = default_context
ecs.delete_render_system(g.render_system)
delete(g.entities)
ecs.coordinator_destroy(&g.coordinator)
free(g)
}
event_cb :: proc "c" (event: ^sa.Event) {
context = default_context
#partial switch event.type {
case .MOUSE_MOVE:
mouse_move += {event.mouse_dx, event.mouse_dy}
case .KEY_DOWN:
key_down[event.key_code] = true
case .KEY_UP:
key_down[event.key_code] = false
}
}
create_scene :: proc() {
ecs.coordinator_register_component(ecs.Gravity, &g.coordinator)
ecs.coordinator_register_component(ecs.RigidBody, &g.coordinator)
ecs.coordinator_register_component(ecs.Transform, &g.coordinator)
ecs.coordinator_register_component(ecs.Color, &g.coordinator)
g.physics_system = ecs.coordinator_register_system(ecs.PhysicsSystem, &g.coordinator)
g.render_system = ecs.coordinator_register_system(ecs.RenderSystem, &g.coordinator)
ecs.init_render_system(g.render_system)
signature := ecs.signature_create()
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Gravity, &g.coordinator))
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.RigidBody, &g.coordinator))
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Transform, &g.coordinator))
ecs.coordinator_set_system_signature(ecs.PhysicsSystem, &g.coordinator, signature)
signature = ecs.signature_create()
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Transform, &g.coordinator))
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Color, &g.coordinator))
ecs.coordinator_set_system_signature(ecs.RenderSystem, &g.coordinator, signature)
g.entities = make([]ecs.EntityID, ecs.ENTITY_MAX)
for &entity in g.entities {
entity = ecs.coordinator_create_entity(&g.coordinator)
ecs.coordinator_add_component(
ecs.Gravity,
&g.coordinator,
entity,
ecs.Gravity{
ecs.Vec3{0.0, -2.82, 0.0}
})
ecs.coordinator_add_component(
ecs.RigidBody,
&g.coordinator,
entity,
ecs.RigidBody{
velocity = ecs.Vec3{0.0, 0.0, 0.0},
acceleration = ecs.Vec3{0.0, 0.0, 0.0},
})
ecs.coordinator_add_component(
ecs.Transform,
&g.coordinator,
entity,
ecs.Transform{
position = Vec3{
f32(rand.int_max(50)),
f32(rand.int_max(10)),
f32(rand.int_max(50)),
},
rotation = ecs.Vec3{0.0, 0.0, 0.0},
scale = ecs.Vec3{1.0, 1.0, 1.0},
})
ecs.coordinator_add_component(
ecs.Color,
&g.coordinator,
entity,
ecs.Color{
color = Vec4{
rand.float32_uniform(0,1),
rand.float32_uniform(0,1),
rand.float32_uniform(0,1),
rand.float32_uniform(0,1),
},
})
}
}
reset_tracking_allocator :: proc(track: ^mem.Tracking_Allocator) {
if len(track.allocation_map) > 0 {
fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map))
for _, entry in track.allocation_map {
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
}
}
if len(track.bad_free_array) > 0 {
fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array))
for entry in track.bad_free_array {
fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
}
}
mem.tracking_allocator_destroy(track)
}