135 lines
4.0 KiB
Zig
135 lines
4.0 KiB
Zig
const ComponentStore = @import("component_store.zig").ComponentStore;
|
|
const TypeStore = @import("type_store.zig").TypeStore;
|
|
const Entity = @import("entity.zig").Entity;
|
|
|
|
const std = @import("std");
|
|
const mem = std.mem;
|
|
const testing = std.testing;
|
|
const Allocator = mem.Allocator;
|
|
|
|
pub const ComponentManager = struct {
|
|
const Self = @This();
|
|
|
|
allocator: *Allocator,
|
|
component_stores: TypeStore,
|
|
|
|
pub fn init(allocator: *Allocator) Self {
|
|
return Self {
|
|
.allocator = allocator,
|
|
.component_stores = TypeStore.init(allocator),
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *Self) void {
|
|
var iter = self.component_stores.map.iterator();
|
|
while (iter.next()) |ptr| {
|
|
// HACK: we dont know the Type here but we need to call deinit
|
|
var storage = @intToPtr(*ComponentStore(u1), ptr.value);
|
|
storage.deinit();
|
|
self.allocator.destroy(storage);
|
|
}
|
|
self.component_stores.deinit();
|
|
}
|
|
|
|
pub fn register(self: *Self, comptime TComponent: type) void {
|
|
const ptr = ComponentStore(TComponent).heapInit(self.allocator);
|
|
self.component_stores.add(ptr.*);
|
|
}
|
|
|
|
pub fn add_component(self: *Self, entityID: usize, component: anytype) void {
|
|
self.component_stores.get(ComponentStore(@TypeOf(component))).*.set(entityID, component);
|
|
}
|
|
|
|
pub fn get_component(self: *Self, comptime TComponent: type, entityID: usize) !TComponent {
|
|
return self.component_stores.get(ComponentStore(TComponent)).*.get(entityID) catch |err| return err;
|
|
}
|
|
|
|
pub fn read_components(self: *Self, comptime TComponent: type) []TComponent {
|
|
return self.component_stores.get(ComponentStore(TComponent)).*.all_components();
|
|
}
|
|
|
|
pub fn read_entities(self: *Self, comptime TComponent: type) []Entity {
|
|
return self.component_stores.get(ComponentStore(TComponent)).*.all_entities();
|
|
}
|
|
};
|
|
|
|
const TestComponent = struct {
|
|
number: i32,
|
|
};
|
|
|
|
test "add component" {
|
|
const component = TestComponent {
|
|
.number = 3
|
|
};
|
|
|
|
var component_manager = ComponentManager.init(std.testing.allocator);
|
|
defer component_manager.deinit();
|
|
|
|
component_manager.register(TestComponent);
|
|
|
|
component_manager.add_component(2, component);
|
|
var expectedComponent = try component_manager.get_component(TestComponent, 2);
|
|
expectedComponent.number = 5; // should be immutable!
|
|
|
|
expectedComponent = try component_manager.get_component(TestComponent, 2);
|
|
testing.expect(expectedComponent.number == 3);
|
|
}
|
|
|
|
test "read components" {
|
|
const component = TestComponent {
|
|
.number = 3
|
|
};
|
|
|
|
const componentTwo = TestComponent {
|
|
.number = 8
|
|
};
|
|
|
|
const componentThree = TestComponent {
|
|
.number = 14
|
|
};
|
|
|
|
var component_manager = ComponentManager.init(std.testing.allocator);
|
|
defer component_manager.deinit();
|
|
|
|
component_manager.register(TestComponent);
|
|
|
|
component_manager.add_component(2, component);
|
|
component_manager.add_component(5, componentTwo);
|
|
component_manager.add_component(52, componentThree);
|
|
|
|
var components = component_manager.read_components(TestComponent);
|
|
|
|
testing.expect(components[0].number == 3);
|
|
testing.expect(components[1].number == 8);
|
|
testing.expect(components[2].number == 14);
|
|
}
|
|
|
|
test "read entities" {
|
|
const component = TestComponent {
|
|
.number = 3
|
|
};
|
|
|
|
const componentTwo = TestComponent {
|
|
.number = 8
|
|
};
|
|
|
|
const componentThree = TestComponent {
|
|
.number = 14
|
|
};
|
|
|
|
var component_manager = ComponentManager.init(std.testing.allocator);
|
|
defer component_manager.deinit();
|
|
|
|
component_manager.register(TestComponent);
|
|
|
|
component_manager.add_component(2, component);
|
|
component_manager.add_component(5, componentTwo);
|
|
component_manager.add_component(52, componentThree);
|
|
|
|
var entities = component_manager.read_entities(TestComponent);
|
|
|
|
testing.expect(entities[0].ID == 2);
|
|
testing.expect(entities[1].ID == 5);
|
|
testing.expect(entities[2].ID == 52);
|
|
}
|