encompass-zig/src/component_manager.zig

135 lines
3.8 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 {
self.component_stores.deinit();
}
pub fn register(self: *Self, comptime TComponent: type) void {
self.component_stores.add(ComponentStore(TComponent).init(self.allocator));
}
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 arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = &arena.allocator;
var component_manager = ComponentManager.init(allocator);
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 arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = &arena.allocator;
var component_manager = ComponentManager.init(allocator);
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);
}