From 01da174126b26075c24fb03562f14e619e3e03c5 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 5 Dec 2020 14:19:17 -0800 Subject: [PATCH] fix store allocs and deallocs --- src/component_manager.zig | 9 ++++++++- src/component_store.zig | 20 +++++++++++++++++--- src/type_store.zig | 34 +++++++--------------------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/component_manager.zig b/src/component_manager.zig index 9bde171..b1e3881 100644 --- a/src/component_manager.zig +++ b/src/component_manager.zig @@ -21,11 +21,18 @@ pub const ComponentManager = struct { } 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(); } 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 { diff --git a/src/component_store.zig b/src/component_store.zig index 50b026f..72172b3 100644 --- a/src/component_store.zig +++ b/src/component_store.zig @@ -14,6 +14,7 @@ pub fn ComponentStore(comptime TComponent: type) type { entityIDToIndex: std.AutoArrayHashMap(usize, usize), indexToEntity: std.ArrayList(Entity), components: std.ArrayList(TComponent), + safeDeinit: fn (*Self) void, pub fn init(allocator: *Allocator) Self { return Self { @@ -21,13 +22,26 @@ pub fn ComponentStore(comptime TComponent: type) type { .entityIDToIndex = std.AutoArrayHashMap(usize, usize).init(allocator), .indexToEntity = std.ArrayList(Entity).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 { - self.entityIDToIndex.deinit(); - self.indexToEntity.deinit(); - self.components.deinit(); + self.safeDeinit(self); } pub fn has(self: Self, entityID: usize) bool { diff --git a/src/type_store.zig b/src/type_store.zig index 0688a8b..46aea5f 100644 --- a/src/type_store.zig +++ b/src/type_store.zig @@ -4,34 +4,30 @@ const std = @import("std"); /// stores a single object of type T for each T added pub const TypeStore = struct { - map: std.AutoHashMap(u32, []u8), + map: std.AutoHashMap(u32, usize), allocator: *std.mem.Allocator, pub fn init(allocator: *std.mem.Allocator) TypeStore { return TypeStore{ - .map = std.AutoHashMap(u32, []u8).init(allocator), + .map = std.AutoHashMap(u32, usize).init(allocator), .allocator = allocator, }; } pub fn deinit(self: *TypeStore) void { var iter = self.map.iterator(); - while (iter.next()) |kv| { - self.allocator.free(kv.value); - } self.map.deinit(); } /// adds instance, returning a pointer to the item as it lives in the store pub fn add(self: *TypeStore, instance: anytype) void { - var bytes = self.allocator.alloc(u8, @sizeOf(@TypeOf(instance))) catch unreachable; - std.mem.copy(u8, bytes, std.mem.asBytes(&instance)); - _ = self.map.put(typeId(@TypeOf(instance)), bytes) catch unreachable; + var ptr = @ptrToInt(&instance); + _ = self.map.put(typeId(@TypeOf(instance)), ptr) catch unreachable; } pub fn get(self: *TypeStore, comptime T: type) *T { - if (self.map.get(typeId(T))) |bytes| { - return @ptrCast(*T, @alignCast(@alignOf(T), bytes)); + if (self.map.get(typeId(T))) |ptr| { + return @intToPtr(*T, ptr); } unreachable; } @@ -40,17 +36,8 @@ pub const TypeStore = struct { 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 { - if (self.map.get(typeId(T))) |bytes| { - self.allocator.free(bytes); + if (self.map.get(typeId(T))) |ptr| { _ = self.map.remove(typeId(T)); } } @@ -95,11 +82,4 @@ test "TypeStore" { store.remove(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); }