fix store allocs and deallocs

main
cosmonaut 2020-12-05 14:19:17 -08:00
parent 2a3d11702c
commit 01da174126
3 changed files with 32 additions and 31 deletions

View File

@ -21,11 +21,18 @@ pub const ComponentManager = struct {
} }
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
var iter = self.component_stores.map.iterator();
while (iter.next()) |ptr| {
var storage = @intToPtr(*ComponentStore(u1), ptr.value);
storage.deinit();
self.allocator.destroy(storage);
}
self.component_stores.deinit(); self.component_stores.deinit();
} }
pub fn register(self: *Self, comptime TComponent: type) void { pub fn register(self: *Self, comptime TComponent: type) void {
self.component_stores.add(ComponentStore(TComponent).init(self.allocator)); const ptr = ComponentStore(TComponent).heapInit(self.allocator);
self.component_stores.add(ptr.*);
} }
pub fn add_component(self: *Self, entityID: usize, component: anytype) void { pub fn add_component(self: *Self, entityID: usize, component: anytype) void {

View File

@ -14,6 +14,7 @@ pub fn ComponentStore(comptime TComponent: type) type {
entityIDToIndex: std.AutoArrayHashMap(usize, usize), entityIDToIndex: std.AutoArrayHashMap(usize, usize),
indexToEntity: std.ArrayList(Entity), indexToEntity: std.ArrayList(Entity),
components: std.ArrayList(TComponent), components: std.ArrayList(TComponent),
safeDeinit: fn (*Self) void,
pub fn init(allocator: *Allocator) Self { pub fn init(allocator: *Allocator) Self {
return Self { return Self {
@ -21,13 +22,26 @@ pub fn ComponentStore(comptime TComponent: type) type {
.entityIDToIndex = std.AutoArrayHashMap(usize, usize).init(allocator), .entityIDToIndex = std.AutoArrayHashMap(usize, usize).init(allocator),
.indexToEntity = std.ArrayList(Entity).init(allocator), .indexToEntity = std.ArrayList(Entity).init(allocator),
.components = std.ArrayList(TComponent).init(allocator), .components = std.ArrayList(TComponent).init(allocator),
.safeDeinit = struct {
// we need to enclose the type here
// which is why this indirection exists for deinit
fn deinit(self: *Self) void {
self.entityIDToIndex.deinit();
self.indexToEntity.deinit();
self.components.deinit();
}
}.deinit,
}; };
} }
pub fn heapInit(allocator: *Allocator) *Self {
var ptr = allocator.create(Self) catch unreachable;
ptr.* = init(allocator);
return ptr;
}
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
self.entityIDToIndex.deinit(); self.safeDeinit(self);
self.indexToEntity.deinit();
self.components.deinit();
} }
pub fn has(self: Self, entityID: usize) bool { pub fn has(self: Self, entityID: usize) bool {

View File

@ -4,34 +4,30 @@ const std = @import("std");
/// stores a single object of type T for each T added /// stores a single object of type T for each T added
pub const TypeStore = struct { pub const TypeStore = struct {
map: std.AutoHashMap(u32, []u8), map: std.AutoHashMap(u32, usize),
allocator: *std.mem.Allocator, allocator: *std.mem.Allocator,
pub fn init(allocator: *std.mem.Allocator) TypeStore { pub fn init(allocator: *std.mem.Allocator) TypeStore {
return TypeStore{ return TypeStore{
.map = std.AutoHashMap(u32, []u8).init(allocator), .map = std.AutoHashMap(u32, usize).init(allocator),
.allocator = allocator, .allocator = allocator,
}; };
} }
pub fn deinit(self: *TypeStore) void { pub fn deinit(self: *TypeStore) void {
var iter = self.map.iterator(); var iter = self.map.iterator();
while (iter.next()) |kv| {
self.allocator.free(kv.value);
}
self.map.deinit(); self.map.deinit();
} }
/// adds instance, returning a pointer to the item as it lives in the store /// adds instance, returning a pointer to the item as it lives in the store
pub fn add(self: *TypeStore, instance: anytype) void { pub fn add(self: *TypeStore, instance: anytype) void {
var bytes = self.allocator.alloc(u8, @sizeOf(@TypeOf(instance))) catch unreachable; var ptr = @ptrToInt(&instance);
std.mem.copy(u8, bytes, std.mem.asBytes(&instance)); _ = self.map.put(typeId(@TypeOf(instance)), ptr) catch unreachable;
_ = self.map.put(typeId(@TypeOf(instance)), bytes) catch unreachable;
} }
pub fn get(self: *TypeStore, comptime T: type) *T { pub fn get(self: *TypeStore, comptime T: type) *T {
if (self.map.get(typeId(T))) |bytes| { if (self.map.get(typeId(T))) |ptr| {
return @ptrCast(*T, @alignCast(@alignOf(T), bytes)); return @intToPtr(*T, ptr);
} }
unreachable; unreachable;
} }
@ -40,17 +36,8 @@ pub const TypeStore = struct {
return self.get(T).*; return self.get(T).*;
} }
pub fn getOrAdd(self: *TypeStore, comptime T: type) *T {
if (!self.has(T)) {
var instance = std.mem.zeroes(T);
self.add(instance);
}
return self.get(T);
}
pub fn remove(self: *TypeStore, comptime T: type) void { pub fn remove(self: *TypeStore, comptime T: type) void {
if (self.map.get(typeId(T))) |bytes| { if (self.map.get(typeId(T))) |ptr| {
self.allocator.free(bytes);
_ = self.map.remove(typeId(T)); _ = self.map.remove(typeId(T));
} }
} }
@ -95,11 +82,4 @@ test "TypeStore" {
store.remove(Vector); store.remove(Vector);
std.testing.expect(!store.has(Vector)); std.testing.expect(!store.has(Vector));
var v3 = store.getOrAdd(u32);
std.testing.expectEqual(v3.*, 0);
v3.* = 777;
var v4 = store.get(u32);
std.testing.expectEqual(v3.*, 777);
} }