Backlog/extras/gameExtras/src/objectSpawner.zig

97 lines
2.8 KiB
Zig

allocator: std.mem.Allocator,
objectList: *core.GameObjectList,
windowOpen: bool = true,
spawnFuncs: std.ArrayListUnmanaged(SpawnEntry) = .{},
spawnPosition: core.Vectorf = .{},
spawnRotation: core.Rotation = .{},
pub const SpawnEntry = struct {
typeName: []const u8,
spawnFunc: core.GameObjectList.SpawnFunc,
opts: Options,
};
pub const Options = struct {
absoluteSpawnposition: bool = false, // if set, won't move the object to where the spawn rotation and position is
};
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.objectSpawner");
pub fn create(allocator: std.mem.Allocator) !*@This() {
const self = try allocator.create(@This());
self.* = .{
.allocator = allocator,
.objectList = try core.GameObjectList.create(allocator),
};
return self;
}
pub fn objectSpawnOptions(self: *@This()) void {
for (self.spawnFuncs.items) |entry| {
if (ig.smallButton(entry.typeName.ptr)) {
if (entry.spawnFunc(self.objectList)) |new| {
const entity = new.vtable.getEntity.?(new.ptr);
if (!entry.opts.absoluteSpawnposition) {
self.prepareEntity(entity);
}
}
}
}
}
fn spawnedObjectsList(self: *@This()) void {
for (self.objectList.objects.items, 0..) |interface, i| {
ig.textFmt("{s}", .{interface.vtable.objectName}) catch {};
ig.sameLine(0.0, 2.0);
ig.pushID_Int(@intCast(i));
if (ig.smallButton("delete me")) {
interface.vtable.destroy(interface.ptr);
}
ig.popID();
}
}
pub fn tick(self: *@This(), dt: f64) void {
self.objectList.tick(dt);
if (self.windowOpen) {
if (ig.begin("object Spawner", null, .{})) {
self.objectSpawnOptions();
self.spawnedObjectsList();
}
ig.end();
}
}
pub fn addSpawnFunction(self: *@This(), comptime name: []const u8, comptime T: type) !void {
var opts: Options = .{};
if (@hasDecl(T, "SpawnOptions")) {
opts = T.SpawnOptions;
}
try self.spawnFuncs.append(self.allocator, .{ .typeName = name, .spawnFunc = core.GameObjectList.spawnObjectFunction(T), .opts = opts });
}
pub fn prepareEntity(self: *@This(), entity: core.Entity) void {
if (entity.fetch(core.Scene)) |scene| {
scene.setPosition(self.spawnPosition);
scene.setRotation(scene.getRotation().add(self.spawnRotation));
_ = scene.getAndResolveTransform();
}
}
pub fn destroy(self: *@This()) void {
self.spawnFuncs.deinit(self.allocator);
self.objectList.destroy();
self.allocator.destroy(self);
}
const std = @import("std");
const backlog = @import("Backlog");
const core = backlog.core;
const rend = backlog.rend;
const ig = backlog.imgui.api;