| 1 | struct Entity { |
| 2 | id u16 |
| 3 | } |
| 4 | |
| 5 | struct Position { |
| 6 | x f64 |
| 7 | y f64 |
| 8 | z f64 |
| 9 | } |
| 10 | |
| 11 | struct Velocity { |
| 12 | x f64 |
| 13 | y f64 |
| 14 | z f64 |
| 15 | } |
| 16 | |
| 17 | interface ComponentStore[T] { |
| 18 | len() int |
| 19 | mut: |
| 20 | add(Entity, T) |
| 21 | } |
| 22 | |
| 23 | struct Store[T] { |
| 24 | mut: |
| 25 | items []T |
| 26 | } |
| 27 | |
| 28 | fn (mut s Store[T]) add(_ Entity, value T) { |
| 29 | s.items << value |
| 30 | } |
| 31 | |
| 32 | fn (s &Store[T]) len() int { |
| 33 | return s.items.len |
| 34 | } |
| 35 | |
| 36 | @[heap] |
| 37 | struct Registry { |
| 38 | mut: |
| 39 | data map[string]ComponentStore |
| 40 | } |
| 41 | |
| 42 | fn new_registry() &Registry { |
| 43 | return &Registry{ |
| 44 | data: map[string]ComponentStore{} |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | fn (mut r Registry) create_store[T]() { |
| 49 | if T.name in r.data { |
| 50 | return |
| 51 | } |
| 52 | r.data[T.name] = Store[T]{} |
| 53 | } |
| 54 | |
| 55 | fn (mut r Registry) add_component[T](entity Entity, component T) { |
| 56 | r.create_store[T]() |
| 57 | r.data[T.name].add(entity, component) |
| 58 | } |
| 59 | |
| 60 | fn (mut r Registry) count[T]() int { |
| 61 | return r.data[T.name].len() |
| 62 | } |
| 63 | |
| 64 | fn test_generic_interface_map_values_can_store_multiple_concrete_instantiations() { |
| 65 | mut registry := new_registry() |
| 66 | entity := Entity{ |
| 67 | id: 1 |
| 68 | } |
| 69 | registry.add_component(entity, Position{ |
| 70 | x: 10 |
| 71 | y: 2 |
| 72 | z: 0 |
| 73 | }) |
| 74 | registry.add_component(entity, Position{ |
| 75 | x: 11 |
| 76 | y: 3 |
| 77 | z: 1 |
| 78 | }) |
| 79 | registry.add_component(entity, Velocity{ |
| 80 | x: 1 |
| 81 | y: 2 |
| 82 | z: 3 |
| 83 | }) |
| 84 | assert registry.count[Position]() == 2 |
| 85 | assert registry.count[Velocity]() == 1 |
| 86 | } |
| 87 | |