entity and ID manager

main
cosmonaut 2020-12-05 01:10:29 -08:00
parent 2875fc285d
commit 74e4abd8fd
4 changed files with 133 additions and 11 deletions

View File

@ -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);
}

View File

@ -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);

60
src/entity_manager.zig Normal file
View File

@ -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));
}

66
src/id_manager.zig Normal file
View File

@ -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);
}