-
Notifications
You must be signed in to change notification settings - Fork 0
/
world.odin
72 lines (61 loc) · 2.04 KB
/
world.odin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package ecs
import "base:intrinsics"
import "core:os"
import "core:thread"
import "core:time"
import "core:fmt"
World :: struct($T: typeid) {
components: map[typeid]map[int]T,
systems_collections: map[string]System_Collection(T),
parallel_systems: [dynamic]Parallel_System,
pool: ^thread.Pool,
entities: [dynamic]Entity,
// Pointer to user defined data, can be used for whatever you want
user_data: rawptr,
prev_frame_time: Maybe(time.Time),
delta: f32, // in secs
delta_dur: time.Duration,
}
new_world :: proc($T: typeid, user_data: rawptr = nil) -> World(T) where intrinsics.type_is_union(T) {
pool := new(thread.Pool)
thread.pool_init(pool, context.allocator, os.processor_core_count())
thread.pool_start(pool)
return World(T) {
entities = make([dynamic]Entity),
components = make(map[typeid]map[int]T),
systems_collections = make(map[string]System_Collection(T)),
pool = pool,
user_data = user_data,
}
}
// Should be called only from main loop.
update :: proc(world: ^World($T)) {
update_time(world)
for _, collection in world.systems_collections {
fmt.println("updating collection:", collection)
for system in collection.systems {
system(world)
}
}
run_parallel_systems(world)
}
// `update_collection` only updates the specified collection of systems, without
// updating the time info. In order to update the time call `update_time` directrly.
// Should be called only from main loop.
update_collection :: proc(world: ^World($T), collection: string) {
collection_ := world.systems_collections[collection]
for system in collection_.systems {
system(world)
}
}
// `update_time` must be called only once per frame
// Should be called only from main loop.
update_time :: proc(world: ^World($T)) {
if world.prev_frame_time == nil {
world.prev_frame_time = time.now()
}
delta_dur := time.since(world.prev_frame_time.(time.Time))
world.delta_dur = delta_dur
world.delta = f32(time.duration_seconds(delta_dur))
world.prev_frame_time = time.now()
}