From 74e4abd8fdae8324dc68581abb6ca34562b10356 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 5 Dec 2020 01:10:29 -0800 Subject: [PATCH] entity and ID manager --- build.zig | 8 ++--- src/entity.zig | 10 ++----- src/entity_manager.zig | 60 ++++++++++++++++++++++++++++++++++++++ src/id_manager.zig | 66 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 src/entity_manager.zig create mode 100644 src/id_manager.zig diff --git a/build.zig b/build.zig index 677886c..e871dfc 100644 --- a/build.zig +++ b/build.zig @@ -6,13 +6,13 @@ pub fn build(b: *Builder) void { lib.setBuildMode(mode); lib.install(); - var entity_test = b.addTest("src/entity.zig"); - entity_test.setBuildMode(mode); - var component_store_test = b.addTest("src/component_store.zig"); component_store_test.setBuildMode(mode); + var entity_manager_test = b.addTest("src/entity_manager.zig"); + entity_manager_test.setBuildMode(mode); + const test_step = b.step("test", "Run library tests"); - test_step.dependOn(&entity_test.step); test_step.dependOn(&component_store_test.step); + test_step.dependOn(&entity_manager_test.step); } diff --git a/src/entity.zig b/src/entity.zig index 6011fde..5279bbe 100644 --- a/src/entity.zig +++ b/src/entity.zig @@ -2,16 +2,12 @@ const std = @import("std"); const testing = std.testing; pub const Entity = struct { - ID: u32, - - pub fn init(id: u32) Entity { - return .{ .ID = id }; - } + ID: usize }; test "entity init" { - const e1 = Entity.init(12); - const e2 = Entity.init(21); + const e1 = Entity { .ID = 12 }; + const e2 = Entity { .ID = 21 }; testing.expect(e1.ID == 12); testing.expect(e2.ID == 21); diff --git a/src/entity_manager.zig b/src/entity_manager.zig new file mode 100644 index 0000000..dade305 --- /dev/null +++ b/src/entity_manager.zig @@ -0,0 +1,60 @@ +const IDManager = @import("id_manager.zig").IDManager; +const Entity = @import("entity.zig").Entity; + +const std = @import("std"); +const mem = std.mem; +const testing = std.testing; +const Allocator = mem.Allocator; + +pub const EntityManager = struct { + const Self = @This(); + + allocator: *Allocator, + idManager: IDManager, + ids: std.AutoHashMap(usize, bool), + + pub fn init(allocator: *Allocator) Self { + return Self { + .allocator = allocator, + .idManager = IDManager.init(allocator), + .ids = std.AutoHashMap(usize, bool).init(allocator) + }; + } + + pub fn create(self: *Self) !Entity { + const id = self.idManager.next(); + var entity = Entity { .ID = id }; + self.ids.put(id, true) catch |err| return err; + return entity; + } + + pub fn exists(self: Self, entityID: usize) bool { + return self.ids.contains(entityID); + } +}; + +test "create" { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + + const allocator = &arena.allocator; + + var entity_manager = EntityManager.init(allocator); + + var entity = try entity_manager.create(); + + testing.expect(entity.ID == 0); +} + +test "exists" { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + + const allocator = &arena.allocator; + + var entity_manager = EntityManager.init(allocator); + + var entity = try entity_manager.create(); + + testing.expect(entity_manager.exists(0)); +} diff --git a/src/id_manager.zig b/src/id_manager.zig new file mode 100644 index 0000000..0c7c160 --- /dev/null +++ b/src/id_manager.zig @@ -0,0 +1,66 @@ +const std = @import("std"); +const testing = std.testing; +const mem = std.mem; +const Allocator = mem.Allocator; + +pub const IDManager = struct { + const Self = @This(); + + allocator: *Allocator, + nextID: usize = 0, + availableIDs: std.ArrayList(usize), + + pub fn init(allocator: *Allocator) Self { + return Self { + .allocator = allocator, + .availableIDs = std.ArrayList(usize).init(allocator), + }; + } + + pub fn next(self: *Self) usize { + if (self.availableIDs.items.len > 0) + { + return self.availableIDs.pop(); + } + else + { + var result = self.nextID; + self.nextID += 1; + return result; + } + } + + pub fn free(self: *Self, id: usize) !void { + self.availableIDs.append(id) catch |err| return err; + } +}; + +test "next" { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + + const allocator = &arena.allocator; + + var id_manager = IDManager.init(allocator); + + testing.expect(id_manager.next() == 0); + testing.expect(id_manager.next() == 1); +} + +test "free" { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + + const allocator = &arena.allocator; + + var id_manager = IDManager.init(allocator); + + var id_zero = id_manager.next(); + var id_one = id_manager.next(); + var id_two = id_manager.next(); + + try id_manager.free(id_one); + + testing.expect(id_manager.next() == id_one); + testing.expect(id_manager.next() == 3); +}