allocator: std.mem.Allocator = undefined, selectedObjectToSpawn: ?core.Name = null, spawnedObjects: std.ArrayListUnmanaged(core.Entity) = .{}, pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "extras.ObjectSystemSpawner"); pub fn create(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); self.* = .{ .allocator = allocator }; if (core.getEngineObject(igu.TopBar)) |topbar| { topbar.addMenuObject(self, "New Object Spawner") catch {}; } return self; } // spawns an arbitrary object, no type acquisition here pub fn spawnObjectAt(self: *@This(), spawnPosRot: core.ScenePosRot) ?core.Entity { if (self.selectedObjectToSpawn == null) return null; const objectSystem: *core.GameObjectSystem = core.get(core.GameObjectSystem); const r = objectSystem.spawnObjectFromTableByName(&self.selectedObjectToSpawn.?, .{ .posRot = spawnPosRot }) catch return null; self.spawnedObjects.append(self.allocator, r.entity) catch return null; return r.entity; } pub fn windowOpen(entry: *igu.MenuEntry, dt: f64) void { const self: *@This() = @ptrCast(@alignCast(entry.ctx)); _ = dt; const object = core.getEngineObject(core.GameObjectSystem).?; if (ig.begin("ObjectSystemSpawner", null, .{})) { if (self.selectedObjectToSpawn) |*selected| { ig.textf("now spawning : {s}", .{selected.utf8()}); } else { ig.textf("click an object to spawn", .{}); } var buf: [256]u8 = undefined; var i = object.objectDefinitions.iterator(); while (i.next()) |v| { const x = std.fmt.bufPrintZ(&buf, "spawn##{d}", .{v.value_ptr.objectBaseName.handle()}) catch unreachable; ig.textf("{s}", .{v.value_ptr.objectBaseName.utf8()}); ig.sameLine(0, 10); if (ig.smallButton(x)) { self.selectedObjectToSpawn = v.value_ptr.objectBaseName; } } ig.separator(); var destroyed: ?usize = null; for (self.spawnedObjects.items, 0..) |entity, j| { const x = std.fmt.bufPrintZ(&buf, "delete {d}", .{entity.handle.index}) catch unreachable; if (ig.smallButton(x)) { entity.destroy(); destroyed = j; } } if (destroyed) |destroyedIndex| { _ = self.spawnedObjects.orderedRemove(destroyedIndex); } } ig.end(); } pub fn destroy(self: *@This()) void { self.spawnedObjects.deinit(self.allocator); self.allocator.destroy(self); } const backlog = @import("Backlog"); const core = backlog.core; const rend = backlog.rend; const ig = backlog.imgui.api; const igu = backlog.imgui.utils; const std = @import("std");