Standardise and make ECS more robust
This commit is contained in:
parent
b9aaeb62c9
commit
2ba1022f79
13 changed files with 245 additions and 232 deletions
7
Makefile
7
Makefile
|
|
@ -1,18 +1,25 @@
|
||||||
build-shaders:
|
build-shaders:
|
||||||
./sokol-shdc -i shaders/src/cube.glsl -o shaders/out/cube.odin -l metal_macos -f sokol_odin
|
./sokol-shdc -i shaders/src/cube.glsl -o shaders/out/cube.odin -l metal_macos -f sokol_odin
|
||||||
./sokol-shdc -i shaders/src/outline.glsl -o shaders/out/outline.odin -l metal_macos -f sokol_odin
|
./sokol-shdc -i shaders/src/outline.glsl -o shaders/out/outline.odin -l metal_macos -f sokol_odin
|
||||||
|
|
||||||
build: build-shaders
|
build: build-shaders
|
||||||
odin build . -use-single-module
|
odin build . -use-single-module
|
||||||
|
|
||||||
build-debug: build-shaders
|
build-debug: build-shaders
|
||||||
odin build . -debug -use-single-module
|
odin build . -debug -use-single-module
|
||||||
|
|
||||||
|
build-release: build-shaders
|
||||||
|
odin build . -o:speed -use-single-module
|
||||||
|
|
||||||
run: build-shaders
|
run: build-shaders
|
||||||
odin run . -use-single-module
|
odin run . -use-single-module
|
||||||
|
|
||||||
run-debug: build-shaders
|
run-debug: build-shaders
|
||||||
odin run . -debug -use-single-module
|
odin run . -debug -use-single-module
|
||||||
|
|
||||||
|
run-release: build-shaders
|
||||||
|
odin run . -o:speed -use-single-module
|
||||||
|
|
||||||
check: build-shaders
|
check: build-shaders
|
||||||
odin strip-semicolon .
|
odin strip-semicolon .
|
||||||
odin check .
|
odin check .
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,13 @@ import "core:math"
|
||||||
import "core:math/linalg"
|
import "core:math/linalg"
|
||||||
|
|
||||||
CameraSystem :: struct {
|
CameraSystem :: struct {
|
||||||
using base: SystemBase,
|
using _: SystemBase,
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
camera_system_init :: proc(camera_system: ^CameraSystem) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
camera_system_update :: proc(camera_system: ^CameraSystem, coordinator: ^Coordinator, dt: f32) {
|
camera_system_update :: proc(camera_system: ^CameraSystem, coordinator: ^Coordinator, dt: f32) {
|
||||||
for entity in camera_system.entities {
|
for entity_id in camera_system.entities {
|
||||||
camera := coordinator_get_component(CameraComponent, coordinator, entity)
|
camera := coordinator_get_component(coordinator, CameraComponent, entity_id)
|
||||||
input := coordinator_get_component(InputComponent, coordinator, entity)
|
input := coordinator_get_component(coordinator, InputComponent, entity_id)
|
||||||
|
|
||||||
move_input: Vec3
|
move_input: Vec3
|
||||||
if input.key_down[.W] do move_input.y = 1
|
if input.key_down[.W] do move_input.y = 1
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,88 @@
|
||||||
|
#+private
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
|
|
||||||
ComponentManager :: struct {
|
ComponentManager :: struct {
|
||||||
component_types: map[typeid]ComponentType,
|
component_ids: map[typeid]ComponentID,
|
||||||
component_pools: map[typeid]^ComponentPool(any),
|
component_pools: map[typeid]^ComponentPool(any),
|
||||||
destroy_procs: map[typeid]proc(pool: ^ComponentPool(any), entity_id: EntityID),
|
next_component_id: ComponentID,
|
||||||
next_component_type: ComponentType,
|
|
||||||
|
component_pool_destroy_entity_cbs: map[typeid]proc(pool: ^ComponentPool(any), entity_id: EntityID),
|
||||||
|
component_pool_delete_cbs: map[typeid]proc(pool: ^ComponentPool(any)),
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_create :: proc() -> ComponentManager {
|
component_manager_init :: proc(component_manager: ^ComponentManager) {
|
||||||
component_manager := ComponentManager {
|
component_manager.component_ids = make(map[typeid]ComponentID, context.allocator)
|
||||||
component_types = make(map[typeid]ComponentType, context.allocator),
|
component_manager.component_pools = make(map[typeid]^ComponentPool(any), context.allocator)
|
||||||
component_pools = make(map[typeid]^ComponentPool(any), context.allocator),
|
|
||||||
next_component_type = 0
|
component_manager.component_pool_destroy_entity_cbs = make(map[typeid]proc(pool: ^ComponentPool(any), entity_id: EntityID), context.allocator)
|
||||||
|
component_manager.component_pool_delete_cbs = make(map[typeid]proc(pool: ^ComponentPool(any)), context.allocator)
|
||||||
|
|
||||||
|
component_manager.next_component_id = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return component_manager
|
component_manager_register_component :: proc($Component: typeid, component_manager: ^ComponentManager) {
|
||||||
}
|
log.assertf(Component not_in component_manager.component_ids, "Registering component more than once")
|
||||||
|
|
||||||
component_manager_register_component :: proc($T: typeid, component_manager: ^ComponentManager) {
|
component_manager.component_ids[Component] = component_manager.next_component_id
|
||||||
log.assertf(T not_in component_manager.component_types, "Registering component more than once")
|
|
||||||
|
|
||||||
component_manager.component_types[T] = component_manager.next_component_type
|
component_pool := new(ComponentPool(Component), context.allocator)
|
||||||
component_pool := new(ComponentPool(T), context.allocator)
|
component_pool_init(component_pool)
|
||||||
component_pool^ = component_pool_create(T)
|
|
||||||
component_manager.component_pools[T] = cast(^ComponentPool(any))component_pool
|
|
||||||
|
|
||||||
component_manager.destroy_procs[T] = proc(component_pool: ^ComponentPool(any), id: EntityID) {
|
component_manager.component_pools[Component] = cast(^ComponentPool(any))component_pool
|
||||||
typed_component_pool := cast(^ComponentPool(T))component_pool
|
|
||||||
|
|
||||||
if id in typed_component_pool.entity_to_index {
|
component_manager.component_pool_destroy_entity_cbs[Component] = proc(any_component_pool: ^ComponentPool(any), entity_id: EntityID) {
|
||||||
component_pool_remove_data(typed_component_pool, id)
|
typed_component_pool := cast(^ComponentPool(Component))any_component_pool
|
||||||
|
if entity_id in typed_component_pool.entity_to_index {
|
||||||
|
component_pool_remove_data(typed_component_pool, entity_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager.next_component_type += 1
|
component_manager.component_pool_delete_cbs[Component] = proc(any_component_pool: ^ComponentPool(any)) {
|
||||||
|
typed_component_pool := cast(^ComponentPool(Component))any_component_pool
|
||||||
|
component_pool_delete(typed_component_pool)
|
||||||
|
free(typed_component_pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_get_component_type :: proc($T: typeid, component_manager: ^ComponentManager) -> ComponentType {
|
component_manager.next_component_id += 1
|
||||||
log.assertf(T in component_manager.component_types, "Component not registered before use")
|
|
||||||
return component_manager.component_types[T]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_add_component :: proc($T: typeid, component_manager: ^ComponentManager, entity_id: EntityID, component: T) {
|
component_manager_get_component_id :: proc(component_manager: ^ComponentManager, $Component: typeid) -> ComponentID {
|
||||||
component_pool := cast(^ComponentPool(T))component_manager.component_pools[T]
|
log.assertf(Component in component_manager.component_ids, "Component not registered before use")
|
||||||
|
return component_manager.component_ids[Component]
|
||||||
|
}
|
||||||
|
|
||||||
|
component_manager_add_component :: proc(component_manager: ^ComponentManager, component: $Component, entity_id: EntityID) {
|
||||||
|
component_pool := cast(^ComponentPool(Component))component_manager.component_pools[Component]
|
||||||
component_pool_insert_data(component_pool, entity_id, component)
|
component_pool_insert_data(component_pool, entity_id, component)
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_remove_component :: proc($T: typeid, component_manager: ^ComponentManager, entity_id: EntityID) {
|
component_manager_remove_component :: proc(component_manager: ^ComponentManager, $Component: typeid, entity_id: EntityID) {
|
||||||
component_pool := cast(^ComponentPool(T))component_manager.component_pools[T]
|
component_pool := cast(^ComponentPool(Component))component_manager.component_pools[Component]
|
||||||
component_pool_remove_data(component_pool, entity_id)
|
component_pool_remove_data(component_pool, entity_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_get_component :: proc($T: typeid, component_manager: ^ComponentManager, entity_id: EntityID) -> ^T {
|
component_manager_get_component :: proc(component_manager: ^ComponentManager, $Component: typeid, entity_id: EntityID) -> ^Component {
|
||||||
component_pool := cast(^ComponentPool(T)) component_manager.component_pools[T]
|
component_pool := cast(^ComponentPool(Component)) component_manager.component_pools[Component]
|
||||||
return component_pool_get(component_pool, entity_id)
|
return component_pool_get(component_pool, entity_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_destroy_entity :: proc(component_manager: ^ComponentManager, entity_id: EntityID) {
|
component_manager_destroy_entity :: proc(component_manager: ^ComponentManager, entity_id: EntityID) {
|
||||||
for T, component_pool in component_manager.component_pools {
|
for Component, component_pool in component_manager.component_pools {
|
||||||
component_manager.destroy_procs[T](component_pool, entity_id)
|
component_manager.component_pool_destroy_entity_cbs[Component](component_pool, entity_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component_manager_destroy :: proc(component_manager: ^ComponentManager) {
|
component_manager_delete :: proc(component_manager: ^ComponentManager) {
|
||||||
for _, &component_pool in component_manager.component_pools {
|
for Component, &component_pool in component_manager.component_pools {
|
||||||
component_pool_destroy(component_pool)
|
component_manager.component_pool_delete_cbs[Component](component_pool)
|
||||||
free(component_pool)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(component_manager.component_pools)
|
delete(component_manager.component_pools)
|
||||||
delete(component_manager.component_types)
|
delete(component_manager.component_ids)
|
||||||
|
|
||||||
|
delete(component_manager.component_pool_destroy_entity_cbs)
|
||||||
|
delete(component_manager.component_pool_delete_cbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,23 @@
|
||||||
|
#+private
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
|
|
||||||
ComponentPool :: struct(T: typeid) {
|
ComponentPool :: struct(Component: typeid) {
|
||||||
data: []T,
|
data: []Component,
|
||||||
entity_to_index: map[EntityID]uintptr,
|
entity_to_index: map[EntityID]uintptr,
|
||||||
index_to_entity: map[uintptr]EntityID,
|
index_to_entity: map[uintptr]EntityID,
|
||||||
size: uintptr,
|
size: uintptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
component_pool_create :: proc($T: typeid) -> ComponentPool(T) {
|
component_pool_init :: proc(component_pool: ^ComponentPool($Component)) {
|
||||||
component_pool := ComponentPool(T) {
|
component_pool.data = make([]Component, ENTITY_MAX, context.allocator)
|
||||||
data = make([]T, ENTITY_MAX),
|
component_pool.entity_to_index = make(map[EntityID]uintptr, context.allocator)
|
||||||
entity_to_index = make(map[EntityID]uintptr, context.allocator),
|
component_pool.index_to_entity = make(map[uintptr]EntityID, context.allocator)
|
||||||
index_to_entity = make(map[uintptr]EntityID, context.allocator),
|
component_pool.size = 0
|
||||||
size = 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return component_pool
|
component_pool_insert_data :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID, component: Component) {
|
||||||
}
|
|
||||||
|
|
||||||
component_pool_insert_data :: proc(component_pool: ^ComponentPool($T), entity_id: EntityID, component: T) {
|
|
||||||
log.assertf(entity_id not_in component_pool.entity_to_index, "Component already added to entity")
|
log.assertf(entity_id not_in component_pool.entity_to_index, "Component already added to entity")
|
||||||
|
|
||||||
new_idx := component_pool.size
|
new_idx := component_pool.size
|
||||||
|
|
@ -31,7 +28,7 @@ component_pool_insert_data :: proc(component_pool: ^ComponentPool($T), entity_id
|
||||||
component_pool.size += 1
|
component_pool.size += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
component_pool_remove_data :: proc(component_pool: ^ComponentPool($T), entity_id: EntityID) {
|
component_pool_remove_data :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID) {
|
||||||
log.assertf(entity_id in component_pool.entity_to_index, "Entity doesn't have component")
|
log.assertf(entity_id in component_pool.entity_to_index, "Entity doesn't have component")
|
||||||
|
|
||||||
removed_entity_idx := component_pool.entity_to_index[entity_id]
|
removed_entity_idx := component_pool.entity_to_index[entity_id]
|
||||||
|
|
@ -48,21 +45,21 @@ component_pool_remove_data :: proc(component_pool: ^ComponentPool($T), entity_id
|
||||||
component_pool.size -= 1
|
component_pool.size -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
component_pool_get :: proc(component_pool: ^ComponentPool($T), entity_id: EntityID) -> ^T {
|
component_pool_get :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID) -> ^Component {
|
||||||
log.assertf(entity_id in component_pool.entity_to_index, "Entity doesn't have component")
|
log.assertf(entity_id in component_pool.entity_to_index, "Entity doesn't have component")
|
||||||
|
|
||||||
idx := component_pool.entity_to_index[entity_id]
|
idx := component_pool.entity_to_index[entity_id]
|
||||||
return &component_pool.data[idx]
|
return &component_pool.data[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
component_pool_destroy_entity :: proc(component_pool: ^ComponentPool($T), entity_id: EntityID) {
|
component_pool_destroy_entity :: proc(component_pool: ^ComponentPool($Component), entity_id: EntityID) {
|
||||||
if entity_id in component_pool.entity_to_index {
|
if entity_id in component_pool.entity_to_index {
|
||||||
component_pool_remove_data(component_pool, entity_id)
|
component_pool_remove_data(component_pool, entity_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component_pool_destroy :: proc(component_pool: ^ComponentPool($T)) {
|
component_pool_delete :: proc(component_pool: ^ComponentPool($Component)) {
|
||||||
|
delete(component_pool.data)
|
||||||
delete(component_pool.entity_to_index)
|
delete(component_pool.entity_to_index)
|
||||||
delete(component_pool.index_to_entity)
|
delete(component_pool.index_to_entity)
|
||||||
delete(component_pool.data)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ COMPONENT_MAX :: 32
|
||||||
ID :: u32
|
ID :: u32
|
||||||
|
|
||||||
EntityID :: ID
|
EntityID :: ID
|
||||||
ComponentType :: u16
|
ComponentID :: u16
|
||||||
|
|
|
||||||
|
|
@ -1,82 +1,70 @@
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
Coordinator :: struct {
|
Coordinator :: struct {
|
||||||
component_manager: ^ComponentManager,
|
component_manager: ComponentManager,
|
||||||
entity_manager: ^EntityManager,
|
entity_manager: EntityManager,
|
||||||
system_manager: ^SystemManager,
|
system_manager: SystemManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_create :: proc() -> Coordinator {
|
coordinator_init:: proc(coordinator: ^Coordinator) {
|
||||||
coordinator := Coordinator{}
|
component_manager_init(&coordinator.component_manager)
|
||||||
coordinator.component_manager = new(ComponentManager, context.allocator)
|
entity_manager_init(&coordinator.entity_manager)
|
||||||
coordinator.component_manager^ = component_manager_create()
|
system_manager_init(&coordinator.system_manager)
|
||||||
|
|
||||||
coordinator.entity_manager = new(EntityManager, context.allocator)
|
|
||||||
coordinator.entity_manager^ = entity_manager_create()
|
|
||||||
|
|
||||||
coordinator.system_manager = new(SystemManager, context.allocator)
|
|
||||||
coordinator.system_manager^ = system_manager_create()
|
|
||||||
|
|
||||||
return coordinator
|
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_create_entity :: proc(coordinator: ^Coordinator) -> EntityID {
|
coordinator_create_entity :: proc(coordinator: ^Coordinator) -> EntityID {
|
||||||
return entity_manager_create_entity(coordinator.entity_manager)
|
return entity_manager_create_entity(&coordinator.entity_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_destroy_entity :: proc(coordinator: ^Coordinator, entity_id: EntityID) {
|
coordinator_destroy_entity :: proc(coordinator: ^Coordinator, entity_id: EntityID) {
|
||||||
component_manager_destroy_entity(coordinator.component_manager, entity_id)
|
component_manager_destroy_entity(&coordinator.component_manager, entity_id)
|
||||||
entity_manager_destroy_entity(coordinator.entity_manager, entity_id)
|
entity_manager_destroy_entity(&coordinator.entity_manager, entity_id)
|
||||||
system_manager_destroy_entity(coordinator.system_manager, entity_id)
|
system_manager_destroy_entity(&coordinator.system_manager, entity_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_register_component :: proc($T: typeid, coordinator: ^Coordinator) {
|
coordinator_register_component :: proc(coordinator: ^Coordinator, $Component: typeid) {
|
||||||
component_manager_register_component(T, coordinator.component_manager)
|
component_manager_register_component(Component, &coordinator.component_manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_add_component :: proc($T: typeid, coordinator: ^Coordinator, entity_id: EntityID, component: T) {
|
coordinator_add_component :: proc(coordinator: ^Coordinator, component: $Component, entity_id: EntityID) {
|
||||||
component_manager_add_component(T, coordinator.component_manager, entity_id, component)
|
component_manager_add_component(&coordinator.component_manager, component, entity_id)
|
||||||
|
|
||||||
signature := entity_manager_get_signature(coordinator.entity_manager, entity_id)
|
signature := entity_manager_get_signature(&coordinator.entity_manager, entity_id)
|
||||||
signature_set(&signature, component_manager_get_component_type(T, coordinator.component_manager))
|
signature_set(&signature, component_manager_get_component_id(&coordinator.component_manager, Component))
|
||||||
entity_manager_set_signature(coordinator.entity_manager, entity_id, signature)
|
entity_manager_set_signature(&coordinator.entity_manager, entity_id, signature)
|
||||||
|
|
||||||
system_manager_change_entity_signature(coordinator.system_manager, entity_id, signature)
|
system_manager_change_entity_signature(&coordinator.system_manager, entity_id, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_remove_component :: proc($T: typeid, coordinator: ^Coordinator, entity_id: EntityID) {
|
coordinator_remove_component :: proc(coordinator: ^Coordinator, $Component: typeid, entity_id: EntityID) {
|
||||||
component_manager_remove_component(T, coordinator.component_manager, entity_id)
|
component_manager_remove_component(&coordinator.component_manager, Component, entity_id)
|
||||||
|
|
||||||
signature := entity_manager_get_signature(coordinator.entity_manager, entity_id)
|
signature := entity_manager_get_signature(&coordinator.entity_manager, entity_id)
|
||||||
signature_unset(&signature, component_manager_get_component_type(T, coordinator.component_manager))
|
signature_unset(&signature, component_manager_get_component_id(&coordinator.component_manager, Component))
|
||||||
entity_manager_set_signature(coordinator.entity_manager, entity_id, signature)
|
entity_manager_set_signature(&coordinator.entity_manager, entity_id, signature)
|
||||||
|
|
||||||
system_manager_change_entity_signature(coordinator.system_manager, entity_id, signature)
|
system_manager_change_entity_signature(&coordinator.system_manager, entity_id, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_get_component :: proc($T: typeid, coordinator: ^Coordinator, entity_id: EntityID) -> ^T {
|
coordinator_get_component :: proc(coordinator: ^Coordinator, $Component: typeid, entity_id: EntityID) -> ^Component {
|
||||||
return component_manager_get_component(T, coordinator.component_manager, entity_id)
|
return component_manager_get_component(&coordinator.component_manager, Component, entity_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_get_component_type :: proc($T: typeid, coordinator: ^Coordinator) -> ComponentType {
|
coordinator_get_component_id :: proc(coordinator: ^Coordinator, $Component: typeid) -> ComponentID {
|
||||||
return component_manager_get_component_type(T, coordinator.component_manager)
|
return component_manager_get_component_id(&coordinator.component_manager, Component)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_register_system :: proc($T: typeid, coordinator: ^Coordinator) -> ^T {
|
coordinator_register_system :: proc(coordinator: ^Coordinator, $System: typeid) -> ^System {
|
||||||
return system_manager_register_system(T, coordinator.system_manager)
|
return system_manager_register_system(&coordinator.system_manager, System)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_set_system_signature :: proc($T: typeid, coordinator: ^Coordinator, signature: Signature) {
|
coordinator_set_system_signature :: proc(coordinator: ^Coordinator, $System: typeid, signature: Signature) {
|
||||||
system_manager_set_signature(T, coordinator.system_manager, signature)
|
system_manager_set_signature(&coordinator.system_manager, System, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator_destroy :: proc(coordinator: ^Coordinator) {
|
coordinator_delete :: proc(coordinator: ^Coordinator) {
|
||||||
component_manager_destroy(coordinator.component_manager)
|
component_manager_delete(&coordinator.component_manager)
|
||||||
entity_manager_destroy(coordinator.entity_manager)
|
entity_manager_delete(&coordinator.entity_manager)
|
||||||
system_manager_destroy(coordinator.system_manager)
|
system_manager_delete(&coordinator.system_manager)
|
||||||
|
|
||||||
free(coordinator.component_manager)
|
|
||||||
free(coordinator.entity_manager)
|
|
||||||
free(coordinator.system_manager)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#+private
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
|
|
@ -9,15 +10,12 @@ EntityManager :: struct {
|
||||||
living_entity_count: u32,
|
living_entity_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_manager_create :: proc() -> EntityManager {
|
entity_manager_init :: proc(entity_manager: ^EntityManager) {
|
||||||
entity_manager := EntityManager{living_entity_count = 0}
|
|
||||||
queue.init(&entity_manager.available_entities)
|
queue.init(&entity_manager.available_entities)
|
||||||
|
|
||||||
for entity_id in 0..<ENTITY_MAX {
|
for entity_id in 0..<ENTITY_MAX {
|
||||||
queue.push_back(&entity_manager.available_entities, cast(EntityID) entity_id)
|
queue.push_back(&entity_manager.available_entities, cast(EntityID) entity_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity_manager
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_manager_create_entity :: proc(entity_manager: ^EntityManager) -> EntityID {
|
entity_manager_create_entity :: proc(entity_manager: ^EntityManager) -> EntityID {
|
||||||
|
|
@ -49,6 +47,6 @@ entity_manager_get_signature :: proc(entity_manager: ^EntityManager, entity_id:
|
||||||
return entity_manager.signatures[entity_id]
|
return entity_manager.signatures[entity_id]
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_manager_destroy :: proc(entity_manager: ^EntityManager) {
|
entity_manager_delete :: proc(entity_manager: ^EntityManager) {
|
||||||
queue.destroy(&entity_manager.available_entities)
|
queue.destroy(&entity_manager.available_entities)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ package ecs
|
||||||
import sa "../sokol/app"
|
import sa "../sokol/app"
|
||||||
|
|
||||||
InputSystem :: struct {
|
InputSystem :: struct {
|
||||||
using base: SystemBase,
|
using _: SystemBase,
|
||||||
}
|
}
|
||||||
|
|
||||||
input_system_update :: proc(input_system: ^InputSystem, coordinator: ^Coordinator, event: ^sa.Event) {
|
input_system_update :: proc(input_system: ^InputSystem, coordinator: ^Coordinator, event: ^sa.Event) {
|
||||||
for entity in input_system.entities {
|
for entity_id in input_system.entities {
|
||||||
input := coordinator_get_component(InputComponent, coordinator, entity)
|
input := coordinator_get_component(coordinator, InputComponent, entity_id)
|
||||||
|
|
||||||
#partial switch event.type {
|
#partial switch event.type {
|
||||||
case .MOUSE_MOVE:
|
case .MOUSE_MOVE:
|
||||||
|
|
@ -24,9 +24,9 @@ input_system_update :: proc(input_system: ^InputSystem, coordinator: ^Coordinato
|
||||||
}
|
}
|
||||||
|
|
||||||
input_system_mouse_reset :: proc(input_system: ^InputSystem, coordinator: ^Coordinator) {
|
input_system_mouse_reset :: proc(input_system: ^InputSystem, coordinator: ^Coordinator) {
|
||||||
for entity in input_system.entities {
|
for entity_id in input_system.entities {
|
||||||
input := coordinator_get_component(InputComponent, coordinator, entity)
|
input_id := coordinator_get_component(coordinator, InputComponent, entity_id)
|
||||||
|
|
||||||
input.mouse_movement = { 0, 0 }
|
input_id.mouse_movement = { 0, 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,23 @@ import "core:log"
|
||||||
import program_config "../config"
|
import program_config "../config"
|
||||||
|
|
||||||
PhysicsSystem :: struct {
|
PhysicsSystem :: struct {
|
||||||
using base: SystemBase,
|
using _: SystemBase,
|
||||||
}
|
}
|
||||||
|
|
||||||
physics_system_update :: proc(physics_system: ^PhysicsSystem, coordinator: ^Coordinator, dt: f32) {
|
physics_system_update :: proc(physics_system: ^PhysicsSystem, coordinator: ^Coordinator, dt: f32) {
|
||||||
entities_to_delete := make([dynamic]EntityID)
|
entities_to_delete := make([dynamic]EntityID)
|
||||||
defer delete(entities_to_delete)
|
defer delete(entities_to_delete)
|
||||||
|
|
||||||
for entity in physics_system.entities {
|
for entity_id in physics_system.entities {
|
||||||
rigid_body := coordinator_get_component(RigidBodyComponent, coordinator, entity)
|
rigid_body := coordinator_get_component(coordinator, RigidBodyComponent, entity_id)
|
||||||
transform := coordinator_get_component(TransformComponent, coordinator, entity)
|
transform := coordinator_get_component(coordinator, TransformComponent, entity_id)
|
||||||
gravity := coordinator_get_component(GravityComponent, coordinator, entity)
|
gravity := coordinator_get_component(coordinator, GravityComponent, entity_id)
|
||||||
|
|
||||||
transform.position += rigid_body.velocity * dt
|
transform.position += rigid_body.velocity * dt
|
||||||
rigid_body.velocity += gravity.force * dt
|
rigid_body.velocity += gravity.force * dt
|
||||||
|
|
||||||
if transform.position.y < program_config.Y_DESPAWN_CUTOFF {
|
if transform.position.y < program_config.Y_DESPAWN_CUTOFF {
|
||||||
append(&entities_to_delete, entity)
|
append(&entities_to_delete, entity_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ Material :: struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSystem :: struct {
|
RenderSystem :: struct {
|
||||||
using base: SystemBase,
|
using _: SystemBase,
|
||||||
camera_entity: EntityID,
|
user_entity: EntityID,
|
||||||
|
|
||||||
materials: map[MaterialID]Material,
|
materials: map[MaterialID]Material,
|
||||||
meshes : map[MeshID]Mesh,
|
meshes : map[MeshID]Mesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private="file")
|
||||||
init_outline_material :: proc(render_system: ^RenderSystem) {
|
init_outline_material :: proc(render_system: ^RenderSystem) {
|
||||||
shader := sg.make_shader(shaders.outline_shader_desc(sg.query_backend()))
|
shader := sg.make_shader(shaders.outline_shader_desc(sg.query_backend()))
|
||||||
pipeline := sg.make_pipeline({
|
pipeline := sg.make_pipeline({
|
||||||
|
|
@ -79,7 +79,7 @@ init_outline_material :: proc(render_system: ^RenderSystem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private="file")
|
||||||
init_cube_material :: proc(render_system: ^RenderSystem) {
|
init_cube_material :: proc(render_system: ^RenderSystem) {
|
||||||
shader := sg.make_shader(shaders.cube_shader_desc(sg.query_backend()))
|
shader := sg.make_shader(shaders.cube_shader_desc(sg.query_backend()))
|
||||||
pipeline := sg.make_pipeline({
|
pipeline := sg.make_pipeline({
|
||||||
|
|
@ -108,7 +108,7 @@ init_cube_material :: proc(render_system: ^RenderSystem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private="file")
|
||||||
init_cube_mesh :: proc (render_system: ^RenderSystem) {
|
init_cube_mesh :: proc (render_system: ^RenderSystem) {
|
||||||
cube_vertices := []CubeVertexData {
|
cube_vertices := []CubeVertexData {
|
||||||
{ pos = { -0.5, -0.5, 0.5 } },
|
{ pos = { -0.5, -0.5, 0.5 } },
|
||||||
|
|
@ -171,7 +171,7 @@ init_cube_mesh :: proc (render_system: ^RenderSystem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_system_init :: proc(render_system: ^RenderSystem, camera_entity: EntityID) {
|
render_system_init :: proc(render_system: ^RenderSystem, user_entity: EntityID) {
|
||||||
default_context := runtime.default_context()
|
default_context := runtime.default_context()
|
||||||
|
|
||||||
sg.setup({
|
sg.setup({
|
||||||
|
|
@ -182,7 +182,7 @@ render_system_init :: proc(render_system: ^RenderSystem, camera_entity: EntityID
|
||||||
|
|
||||||
render_system.materials = make(map[MaterialID]Material)
|
render_system.materials = make(map[MaterialID]Material)
|
||||||
render_system.meshes = make(map[MeshID]Mesh)
|
render_system.meshes = make(map[MeshID]Mesh)
|
||||||
render_system.camera_entity = camera_entity
|
render_system.user_entity = user_entity
|
||||||
|
|
||||||
init_cube_mesh(render_system)
|
init_cube_mesh(render_system)
|
||||||
init_cube_material(render_system)
|
init_cube_material(render_system)
|
||||||
|
|
@ -209,7 +209,7 @@ render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
|
||||||
sg.shutdown()
|
sg.shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private="file")
|
||||||
CLEAR_SCREEN_ACTION :: sg.Pass_Action{
|
CLEAR_SCREEN_ACTION :: sg.Pass_Action{
|
||||||
colors = {
|
colors = {
|
||||||
0 = {
|
0 = {
|
||||||
|
|
@ -219,10 +219,11 @@ CLEAR_SCREEN_ACTION :: sg.Pass_Action{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
outline_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj: Mat4, view: Mat4) {
|
outline_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj: Mat4, view: Mat4) {
|
||||||
for entity in render_system.entities {
|
for entity_id in render_system.entities {
|
||||||
transform := coordinator_get_component(TransformComponent, coordinator, entity)
|
transform := coordinator_get_component(coordinator, TransformComponent, entity_id)
|
||||||
mesh_id := coordinator_get_component(MeshComponent, coordinator, entity).mesh_id
|
mesh_id := coordinator_get_component(coordinator, MeshComponent, entity_id).mesh_id
|
||||||
mesh := render_system.meshes[mesh_id]
|
mesh := render_system.meshes[mesh_id]
|
||||||
|
|
||||||
scale_mat := linalg.matrix4_scale_f32(transform.scale * 1.2)
|
scale_mat := linalg.matrix4_scale_f32(transform.scale * 1.2)
|
||||||
|
|
@ -257,17 +258,18 @@ outline_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, pr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
cube_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj: Mat4, view: Mat4) {
|
cube_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj: Mat4, view: Mat4) {
|
||||||
for entity in render_system.entities {
|
for entity_id in render_system.entities {
|
||||||
transform := coordinator_get_component(TransformComponent, coordinator, entity)
|
transform := coordinator_get_component(coordinator, TransformComponent, entity_id)
|
||||||
|
|
||||||
mesh_id := coordinator_get_component(MeshComponent, coordinator, entity).mesh_id
|
mesh_id := coordinator_get_component(coordinator, MeshComponent, entity_id).mesh_id
|
||||||
mesh := render_system.meshes[mesh_id]
|
mesh := render_system.meshes[mesh_id]
|
||||||
|
|
||||||
material_id := coordinator_get_component(MaterialComponent, coordinator, entity).material_id
|
material_id := coordinator_get_component(coordinator, MaterialComponent, entity_id).material_id
|
||||||
material := render_system.materials[material_id]
|
material := render_system.materials[material_id]
|
||||||
|
|
||||||
color := coordinator_get_component(ColorComponent, coordinator, entity)
|
color := coordinator_get_component(coordinator, ColorComponent, entity_id)
|
||||||
|
|
||||||
scale_mat := linalg.matrix4_scale_f32(transform.scale)
|
scale_mat := linalg.matrix4_scale_f32(transform.scale)
|
||||||
rot_mat := linalg.matrix4_from_yaw_pitch_roll_f32(
|
rot_mat := linalg.matrix4_from_yaw_pitch_roll_f32(
|
||||||
|
|
@ -295,7 +297,7 @@ cube_pass :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, proj:
|
||||||
}
|
}
|
||||||
|
|
||||||
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator) {
|
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator) {
|
||||||
camera := coordinator_get_component(CameraComponent, coordinator, render_system.camera_entity)
|
camera := coordinator_get_component(coordinator, CameraComponent, render_system.user_entity)
|
||||||
|
|
||||||
proj := linalg.matrix4_perspective_f32(70, sa.widthf() / sa.heightf(), 0.001, 1000)
|
proj := linalg.matrix4_perspective_f32(70, sa.widthf() / sa.heightf(), 0.001, 1000)
|
||||||
view := linalg.matrix4_look_at_f32(camera.position, camera.target, { 0, 1, 0 } )
|
view := linalg.matrix4_look_at_f32(camera.position, camera.target, { 0, 1, 0 } )
|
||||||
|
|
@ -308,11 +310,13 @@ render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
|
||||||
sg.commit()
|
sg.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
sg_range :: proc {
|
sg_range :: proc {
|
||||||
sg_range_from_slice,
|
sg_range_from_slice,
|
||||||
sg_range_from_struct,
|
sg_range_from_struct,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
sg_range_from_slice :: proc(s: []$T) -> sg.Range {
|
sg_range_from_slice :: proc(s: []$T) -> sg.Range {
|
||||||
return {
|
return {
|
||||||
ptr = raw_data(s),
|
ptr = raw_data(s),
|
||||||
|
|
@ -320,6 +324,7 @@ sg_range_from_slice :: proc(s: []$T) -> sg.Range {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
sg_range_from_struct :: proc(s: ^$T) -> sg.Range where intrinsics.type_is_struct(T) {
|
sg_range_from_struct :: proc(s: ^$T) -> sg.Range where intrinsics.type_is_struct(T) {
|
||||||
return {
|
return {
|
||||||
ptr = s,
|
ptr = s,
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,15 @@ package ecs
|
||||||
|
|
||||||
Signature :: bit_set[0..<COMPONENT_MAX]
|
Signature :: bit_set[0..<COMPONENT_MAX]
|
||||||
|
|
||||||
signature_create :: proc() -> Signature {
|
signature_make :: proc() -> Signature {
|
||||||
return Signature{}
|
return Signature{}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature_set :: proc(signature: ^Signature, type: ComponentType) {
|
signature_set :: proc(signature: ^Signature, type: ComponentID) {
|
||||||
signature^ += {cast(int)type}
|
signature^ += {cast(int)type}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature_unset :: proc(signature: ^Signature, type: ComponentType) {
|
signature_unset :: proc(signature: ^Signature, type: ComponentID) {
|
||||||
signature^ -= {cast(int)type}
|
signature^ -= {cast(int)type}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
|
#+private
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:log"
|
import "core:log"
|
||||||
|
|
||||||
|
@(private = "file")
|
||||||
|
EntitySet :: map[EntityID]struct{}
|
||||||
|
|
||||||
SystemBase :: struct {
|
SystemBase :: struct {
|
||||||
entities: map[EntityID]struct{}, // Treat as set
|
entities: EntitySet
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemManager :: struct {
|
SystemManager :: struct {
|
||||||
|
|
@ -12,29 +16,30 @@ SystemManager :: struct {
|
||||||
systems: map[typeid]^SystemBase
|
systems: map[typeid]^SystemBase
|
||||||
}
|
}
|
||||||
|
|
||||||
system_manager_create :: proc() -> SystemManager {
|
system_base_init :: proc(system_base: ^SystemBase) {
|
||||||
system_manager := SystemManager{
|
system_base.entities = make(EntitySet, context.allocator)
|
||||||
signatures = make(map[typeid]Signature, context.allocator),
|
|
||||||
systems = make(map[typeid]^SystemBase, context.allocator),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return system_manager
|
system_manager_init :: proc(system_manager: ^SystemManager) {
|
||||||
|
system_manager.signatures = make(map[typeid]Signature, context.allocator)
|
||||||
|
system_manager.systems = make(map[typeid]^SystemBase, context.allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
system_manager_register_system :: proc($T: typeid, system_manager: ^SystemManager) -> ^T {
|
system_manager_register_system :: proc(system_manager: ^SystemManager, $System: typeid) -> ^System {
|
||||||
log.assertf(T not_in system_manager.systems, "Registering system more than once")
|
log.assertf(System not_in system_manager.systems, "Registering system more than once")
|
||||||
log.assertf(intrinsics.type_has_field(T, "entities"), "Registering non system type")
|
log.assertf(intrinsics.type_has_field(System, "entities"), "Registering non system type")
|
||||||
|
|
||||||
system := new(T, context.allocator)
|
system := new(System, context.allocator)
|
||||||
system.entities = make(map[EntityID]struct{})
|
system_base_init(system)
|
||||||
system_manager.systems[T] = system
|
|
||||||
|
system_manager.systems[System] = system
|
||||||
|
|
||||||
return system
|
return system
|
||||||
}
|
}
|
||||||
|
|
||||||
system_manager_set_signature :: proc($T: typeid, system_manager: ^SystemManager, signature: Signature) {
|
system_manager_set_signature :: proc(system_manager: ^SystemManager, $System: typeid, signature: Signature) {
|
||||||
log.assertf(T in system_manager.systems, "System used before registered")
|
log.assertf(System in system_manager.systems, "System used before registered")
|
||||||
system_manager.signatures[T] = signature
|
system_manager.signatures[System] = signature
|
||||||
}
|
}
|
||||||
|
|
||||||
system_manager_destroy_entity :: proc(system_manager: ^SystemManager, entity_id: EntityID) {
|
system_manager_destroy_entity :: proc(system_manager: ^SystemManager, entity_id: EntityID) {
|
||||||
|
|
@ -54,7 +59,7 @@ system_manager_change_entity_signature :: proc(system_manager: ^SystemManager, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
system_manager_destroy :: proc(system_manager: ^SystemManager) {
|
system_manager_delete :: proc(system_manager: ^SystemManager) {
|
||||||
for _, system in system_manager.systems {
|
for _, system in system_manager.systems {
|
||||||
delete(system.entities)
|
delete(system.entities)
|
||||||
free(system)
|
free(system)
|
||||||
|
|
|
||||||
130
main.odin
130
main.odin
|
|
@ -40,14 +40,13 @@ Globals :: struct {
|
||||||
g: ^Globals
|
g: ^Globals
|
||||||
|
|
||||||
default_context: runtime.Context
|
default_context: runtime.Context
|
||||||
|
tracking_allocator: mem.Tracking_Allocator
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
context.logger = log.create_console_logger()
|
context.logger = log.create_console_logger()
|
||||||
|
|
||||||
tracking_allocator: mem.Tracking_Allocator
|
|
||||||
mem.tracking_allocator_init(&tracking_allocator, context.allocator)
|
mem.tracking_allocator_init(&tracking_allocator, context.allocator)
|
||||||
context.allocator = mem.tracking_allocator(&tracking_allocator)
|
context.allocator = mem.tracking_allocator(&tracking_allocator)
|
||||||
defer reset_tracking_allocator(&tracking_allocator)
|
|
||||||
|
|
||||||
default_context = context
|
default_context = context
|
||||||
|
|
||||||
|
|
@ -71,7 +70,7 @@ init_cb :: proc "c" () {
|
||||||
sa.lock_mouse(true)
|
sa.lock_mouse(true)
|
||||||
|
|
||||||
g = new(Globals)
|
g = new(Globals)
|
||||||
g.coordinator = ecs.coordinator_create()
|
ecs.coordinator_init(&g.coordinator)
|
||||||
|
|
||||||
create_scene()
|
create_scene()
|
||||||
}
|
}
|
||||||
|
|
@ -99,8 +98,10 @@ cleanup_cb :: proc "c" () {
|
||||||
|
|
||||||
ecs.render_system_delete(g.render_system, &g.coordinator)
|
ecs.render_system_delete(g.render_system, &g.coordinator)
|
||||||
|
|
||||||
ecs.coordinator_destroy(&g.coordinator)
|
ecs.coordinator_delete(&g.coordinator)
|
||||||
free(g)
|
free(g)
|
||||||
|
|
||||||
|
reset_tracking_allocator(&tracking_allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
event_cb :: proc "c" (event: ^sa.Event) {
|
event_cb :: proc "c" (event: ^sa.Event) {
|
||||||
|
|
@ -113,24 +114,22 @@ create_cube :: proc() {
|
||||||
entity := ecs.coordinator_create_entity(&g.coordinator)
|
entity := ecs.coordinator_create_entity(&g.coordinator)
|
||||||
|
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.GravityComponent,
|
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
|
||||||
ecs.GravityComponent{
|
ecs.GravityComponent{
|
||||||
ecs.Vec3{ 0.0, program_config.GRAVITY_CONSTANT, 0.0 }
|
ecs.Vec3{ 0.0, program_config.GRAVITY_CONSTANT, 0.0 }
|
||||||
})
|
},
|
||||||
|
entity
|
||||||
|
)
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.RigidBodyComponent,
|
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
|
||||||
ecs.RigidBodyComponent{
|
ecs.RigidBodyComponent{
|
||||||
velocity = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
velocity = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
||||||
acceleration = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
acceleration = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
||||||
})
|
},
|
||||||
|
entity
|
||||||
|
)
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.TransformComponent,
|
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
|
||||||
ecs.TransformComponent{
|
ecs.TransformComponent{
|
||||||
position = Vec3{
|
position = Vec3{
|
||||||
f32(rand.int_max(program_config.SPAWN_AREA)),
|
f32(rand.int_max(program_config.SPAWN_AREA)),
|
||||||
|
|
@ -139,108 +138,115 @@ create_cube :: proc() {
|
||||||
},
|
},
|
||||||
rotation = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
rotation = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
||||||
scale = ecs.Vec3{ 1.0, 1.0, 1.0 },
|
scale = ecs.Vec3{ 1.0, 1.0, 1.0 },
|
||||||
})
|
},
|
||||||
|
entity
|
||||||
|
)
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.ColorComponent,
|
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
|
||||||
ecs.ColorComponent{
|
ecs.ColorComponent{
|
||||||
color = program_config.CUBE_COLORS[g.current_color]
|
color = program_config.CUBE_COLORS[g.current_color]
|
||||||
})
|
},
|
||||||
|
entity
|
||||||
|
)
|
||||||
g.current_color += 1
|
g.current_color += 1
|
||||||
g.current_color %= i32(len(program_config.CUBE_COLORS))
|
g.current_color %= i32(len(program_config.CUBE_COLORS))
|
||||||
|
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.MeshComponent,
|
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
|
||||||
ecs.MeshComponent{
|
ecs.MeshComponent{
|
||||||
mesh_id = .Cube
|
mesh_id = .Cube
|
||||||
})
|
},
|
||||||
|
entity
|
||||||
|
)
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.MaterialComponent,
|
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
|
||||||
ecs.MaterialComponent{
|
ecs.MaterialComponent{
|
||||||
material_id = .Cube
|
material_id = .Cube
|
||||||
})
|
},
|
||||||
|
entity
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
create_scene :: proc() {
|
create_scene :: proc() {
|
||||||
ecs.coordinator_register_component(ecs.GravityComponent, &g.coordinator)
|
coordinator := &g.coordinator
|
||||||
ecs.coordinator_register_component(ecs.RigidBodyComponent, &g.coordinator)
|
|
||||||
ecs.coordinator_register_component(ecs.TransformComponent, &g.coordinator)
|
|
||||||
ecs.coordinator_register_component(ecs.ColorComponent, &g.coordinator)
|
|
||||||
ecs.coordinator_register_component(ecs.CameraComponent, &g.coordinator)
|
|
||||||
ecs.coordinator_register_component(ecs.MaterialComponent, &g.coordinator)
|
|
||||||
ecs.coordinator_register_component(ecs.MeshComponent, &g.coordinator)
|
|
||||||
ecs.coordinator_register_component(ecs.InputComponent, &g.coordinator)
|
|
||||||
|
|
||||||
g.physics_system = ecs.coordinator_register_system(ecs.PhysicsSystem, &g.coordinator)
|
ecs.coordinator_register_component(coordinator, ecs.GravityComponent)
|
||||||
signature := ecs.signature_create()
|
ecs.coordinator_register_component(coordinator, ecs.RigidBodyComponent)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.GravityComponent, &g.coordinator))
|
ecs.coordinator_register_component(coordinator, ecs.TransformComponent)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.RigidBodyComponent, &g.coordinator))
|
ecs.coordinator_register_component(coordinator, ecs.ColorComponent)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.TransformComponent, &g.coordinator))
|
ecs.coordinator_register_component(coordinator, ecs.CameraComponent)
|
||||||
ecs.coordinator_set_system_signature(ecs.PhysicsSystem, &g.coordinator, signature)
|
ecs.coordinator_register_component(coordinator, ecs.MaterialComponent)
|
||||||
|
ecs.coordinator_register_component(coordinator, ecs.MeshComponent)
|
||||||
|
ecs.coordinator_register_component(coordinator, ecs.InputComponent)
|
||||||
|
|
||||||
g.render_system = ecs.coordinator_register_system(ecs.RenderSystem, &g.coordinator)
|
g.physics_system = ecs.coordinator_register_system(coordinator, ecs.PhysicsSystem)
|
||||||
|
signature := ecs.signature_make()
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.GravityComponent))
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.RigidBodyComponent))
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.TransformComponent))
|
||||||
|
ecs.coordinator_set_system_signature(coordinator, ecs.PhysicsSystem, signature)
|
||||||
|
|
||||||
|
g.render_system = ecs.coordinator_register_system(coordinator, ecs.RenderSystem)
|
||||||
ecs.signature_clear(&signature)
|
ecs.signature_clear(&signature)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.TransformComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.TransformComponent))
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.ColorComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.ColorComponent))
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.MeshComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.MeshComponent))
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.MaterialComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.MaterialComponent))
|
||||||
ecs.coordinator_set_system_signature(ecs.RenderSystem, &g.coordinator, signature)
|
ecs.coordinator_set_system_signature(coordinator, ecs.RenderSystem, signature)
|
||||||
|
|
||||||
g.camera_system = ecs.coordinator_register_system(ecs.CameraSystem, &g.coordinator)
|
g.camera_system = ecs.coordinator_register_system(coordinator, ecs.CameraSystem)
|
||||||
ecs.signature_clear(&signature)
|
ecs.signature_clear(&signature)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.CameraComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.CameraComponent))
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.InputComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.InputComponent))
|
||||||
ecs.coordinator_set_system_signature(ecs.CameraSystem, &g.coordinator, signature)
|
ecs.coordinator_set_system_signature(coordinator, ecs.CameraSystem, signature)
|
||||||
|
|
||||||
g.input_system = ecs.coordinator_register_system(ecs.InputSystem, &g.coordinator)
|
g.input_system = ecs.coordinator_register_system(coordinator, ecs.InputSystem)
|
||||||
ecs.signature_clear(&signature)
|
ecs.signature_clear(&signature)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.InputComponent, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.InputComponent))
|
||||||
ecs.coordinator_set_system_signature(ecs.InputSystem, &g.coordinator, signature)
|
ecs.coordinator_set_system_signature(coordinator, ecs.InputSystem, signature)
|
||||||
|
|
||||||
user_entity := ecs.coordinator_create_entity(&g.coordinator)
|
user_entity := ecs.coordinator_create_entity(coordinator)
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.CameraComponent,
|
coordinator,
|
||||||
&g.coordinator,
|
|
||||||
user_entity,
|
|
||||||
ecs.CameraComponent{
|
ecs.CameraComponent{
|
||||||
position = program_config.START_POSITION,
|
position = program_config.START_POSITION,
|
||||||
target = { 0, 0, 1 },
|
target = { 0, 0, 1 },
|
||||||
look = { 0, 0 },
|
look = { 0, 0 },
|
||||||
|
|
||||||
movement_speed = program_config.MOVEMENT_SPEED,
|
movement_speed = program_config.MOVEMENT_SPEED,
|
||||||
look_sensitivity = program_config.LOOK_SENSITIVITY,
|
look_sensitivity = program_config.LOOK_SENSITIVITY,
|
||||||
})
|
},
|
||||||
|
user_entity
|
||||||
|
)
|
||||||
|
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.InputComponent,
|
coordinator,
|
||||||
&g.coordinator,
|
|
||||||
user_entity,
|
|
||||||
ecs.InputComponent{
|
ecs.InputComponent{
|
||||||
key_down = {},
|
key_down = {},
|
||||||
mouse_movement = Vec2{ 0, 0 }
|
mouse_movement = Vec2{ 0, 0 }
|
||||||
})
|
},
|
||||||
|
user_entity
|
||||||
|
)
|
||||||
|
|
||||||
ecs.render_system_init(g.render_system, user_entity)
|
ecs.render_system_init(g.render_system, user_entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_tracking_allocator :: proc(track: ^mem.Tracking_Allocator) {
|
reset_tracking_allocator :: proc(track: ^mem.Tracking_Allocator) {
|
||||||
|
clean := true
|
||||||
if len(track.allocation_map) > 0 {
|
if len(track.allocation_map) > 0 {
|
||||||
fmt.eprintf("=== %v allocations not freed: ===\n", len(track.allocation_map))
|
fmt.eprintfln("=== %v allocations not freed: ===", len(track.allocation_map))
|
||||||
for _, entry in track.allocation_map {
|
for _, entry in track.allocation_map {
|
||||||
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
|
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
|
||||||
}
|
}
|
||||||
|
clean = false
|
||||||
}
|
}
|
||||||
if len(track.bad_free_array) > 0 {
|
if len(track.bad_free_array) > 0 {
|
||||||
fmt.eprintf("=== %v incorrect frees: ===\n", len(track.bad_free_array))
|
fmt.eprintfln("=== %v incorrect frees: ===", len(track.bad_free_array))
|
||||||
for entry in track.bad_free_array {
|
for entry in track.bad_free_array {
|
||||||
fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
|
fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
|
||||||
}
|
}
|
||||||
|
clean = false
|
||||||
}
|
}
|
||||||
|
if clean do fmt.printfln("=== No memory leaked ===")
|
||||||
|
|
||||||
mem.tracking_allocator_destroy(track)
|
mem.tracking_allocator_destroy(track)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue