added an object spawner
This commit is contained in:
parent
20e0c1b3ee
commit
442705c786
|
|
@ -36,6 +36,8 @@ pub const Console = struct {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
const command = core.stringStrip(c);
|
const command = core.stringStrip(c);
|
||||||
|
|
||||||
|
core.console_log("console_eval > {s}", .{c});
|
||||||
|
|
||||||
while (i < command.len) : (i += 1) {
|
while (i < command.len) : (i += 1) {
|
||||||
if (command[i] == ' ') {
|
if (command[i] == ' ') {
|
||||||
const func = command[0..i];
|
const func = command[0..i];
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const gameObjectList = @import("utils/gameObjectList.zig");
|
||||||
|
pub const GameObjectList = gameObjectList.GameObjectList;
|
||||||
|
pub const GameObjectInterface = gameObjectList.GameObjectInterface;
|
||||||
|
pub const GameObjectData = gameObjectList.GameObjectData;
|
||||||
|
|
||||||
pub const inputs = @import("inputs/inputStack.zig");
|
pub const inputs = @import("inputs/inputStack.zig");
|
||||||
pub const getInputStack = inputs.getInputStack;
|
pub const getInputStack = inputs.getInputStack;
|
||||||
pub const ActionEvent = inputs.ActionEvent;
|
pub const ActionEvent = inputs.ActionEvent;
|
||||||
|
|
@ -156,9 +161,9 @@ pub fn shutdown_module(_: std.mem.Allocator) void {
|
||||||
MemoryTracker.MTPrintStatsDelta();
|
MemoryTracker.MTPrintStatsDelta();
|
||||||
|
|
||||||
logging.shutdownLogging();
|
logging.shutdownLogging();
|
||||||
ecs.shutdown();
|
|
||||||
|
|
||||||
debug_draw.shutdownDrawInterface();
|
debug_draw.shutdownDrawInterface();
|
||||||
|
|
||||||
|
ecs.shutdown();
|
||||||
algorithm.destroyNameRegistry();
|
algorithm.destroyNameRegistry();
|
||||||
gEngine.deinit();
|
gEngine.deinit();
|
||||||
gPackerFS.destroy();
|
gPackerFS.destroy();
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,16 @@ pub fn createEntity() !Entity {
|
||||||
return .{ .handle = try gEcsRegistry.baseSet.createObject(.{}) };
|
return .{ .handle = try gEcsRegistry.baseSet.createObject(.{}) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroyEntity(e: Entity) void {
|
||||||
|
if (gEcsRegistry.baseSet.get(e.handle)) |entityEntry| {
|
||||||
|
for (entityEntry.containers.items) |ref| {
|
||||||
|
ref.vtable.destroyObject(ref.ptr, e.handle);
|
||||||
|
}
|
||||||
|
entityEntry.containers.deinit(gEcsRegistry.allocator);
|
||||||
|
gEcsRegistry.baseSet.destroyObject(e.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn CreateEntity_Lua(state: lua.LuaState) i32 {
|
pub fn CreateEntity_Lua(state: lua.LuaState) i32 {
|
||||||
const ud = state.newZigUserdata(Entity) catch return 0;
|
const ud = state.newZigUserdata(Entity) catch return 0;
|
||||||
ud.* = createEntity() catch {
|
ud.* = createEntity() catch {
|
||||||
|
|
@ -255,6 +265,11 @@ pub const EcsRegistry = struct {
|
||||||
for (self.systems.items) |ref| {
|
for (self.systems.items) |ref| {
|
||||||
ref.vtable.destroy(ref.ptr);
|
ref.vtable.destroy(ref.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (self.baseSet.dense.items) |*entry| {
|
||||||
|
entry.value.containers.deinit(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
self.systems.deinit(self.allocator);
|
self.systems.deinit(self.allocator);
|
||||||
self.tickableSystems.deinit(self.allocator);
|
self.tickableSystems.deinit(self.allocator);
|
||||||
self.baseSet.deinit();
|
self.baseSet.deinit();
|
||||||
|
|
@ -277,6 +292,7 @@ pub fn defineComponent(comptime Component: type, allocator: std.mem.Allocator) !
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undefineComponent(comptime Component: type) void {
|
pub fn undefineComponent(comptime Component: type) void {
|
||||||
|
core.engine_logs("undefining component " ++ @typeName(Component));
|
||||||
Component.BaseContainer.destroy();
|
Component.BaseContainer.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,6 +308,10 @@ pub const Entity = struct {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
destroyEntity(self.*);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fromHandle(handle: core.ObjectHandle) @This() {
|
pub fn fromHandle(handle: core.ObjectHandle) @This() {
|
||||||
return .{ .handle = handle };
|
return .{ .handle = handle };
|
||||||
}
|
}
|
||||||
|
|
@ -299,6 +319,10 @@ pub const Entity = struct {
|
||||||
pub fn addComponent(self: @This(), comptime Component: type) ?*Component {
|
pub fn addComponent(self: @This(), comptime Component: type) ?*Component {
|
||||||
const rv = Component.BaseContainer.createWithHandleECS(self.handle);
|
const rv = Component.BaseContainer.createWithHandleECS(self.handle);
|
||||||
|
|
||||||
|
const list = &gEcsRegistry.baseSet.get(self.handle).?.containers;
|
||||||
|
const allocator = gEcsRegistry.allocator;
|
||||||
|
list.append(allocator, getTypeContainer(Component)) catch return null;
|
||||||
|
|
||||||
// if (@hasDecl(Component, "init")) {
|
// if (@hasDecl(Component, "init")) {
|
||||||
// rv.init(self.handle);
|
// rv.init(self.handle);
|
||||||
// }
|
// }
|
||||||
|
|
@ -365,6 +389,7 @@ pub fn getTypeContainer(comptime T: type) EcsContainerRef {
|
||||||
|
|
||||||
pub const EcsEntry = struct {
|
pub const EcsEntry = struct {
|
||||||
containersCount: u32 = 0,
|
containersCount: u32 = 0,
|
||||||
|
containers: std.ArrayListUnmanaged(EcsContainerRef) = .{},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const BaseSet = p2.SparseSet(EcsEntry);
|
pub const BaseSet = p2.SparseSet(EcsEntry);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
// helper, add this to your game manager class and invoke it's tick,
|
||||||
|
//
|
||||||
|
// will automatically manage spawning and despawning entities and manage de-initialization for you
|
||||||
|
// i actually don't reccomend using this for the most part for more serious games
|
||||||
|
// but it's something that will help a lot when implementing gamejams
|
||||||
|
//
|
||||||
|
// what i would rather reccomend instead is creating components instead with SparseMap base container for most things
|
||||||
|
//
|
||||||
|
// however if you want to define prefabs, then something like this might be useful.
|
||||||
|
//
|
||||||
|
// Like i said, more geared towards gamejams and toys than serious work.
|
||||||
|
|
||||||
|
pub const GameObjectInterfaceVTable = struct {
|
||||||
|
destroy: *const fn (*anyopaque) void,
|
||||||
|
tick: ?*const fn (*anyopaque, f64) void,
|
||||||
|
getEntity: ?*const fn (*anyopaque) core.Entity,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GameObjectData = struct {
|
||||||
|
index: u32,
|
||||||
|
list: *GameObjectList,
|
||||||
|
|
||||||
|
pub fn release(self: *@This(), outer: anytype) void {
|
||||||
|
core.engine_log("releases {d}", .{self.list.objects.items.len});
|
||||||
|
if (self.list.objects.items.len > 1) {
|
||||||
|
self.list.objects.items[self.list.objects.items.len - 1].data.index = self.index;
|
||||||
|
}
|
||||||
|
_ = self.list.objects.swapRemove(@intCast(self.index));
|
||||||
|
|
||||||
|
self.list.allocator.destroy(outer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GameObjectInterface = struct {
|
||||||
|
vtable: *const GameObjectInterfaceVTable,
|
||||||
|
ptr: *anyopaque,
|
||||||
|
data: *GameObjectData,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GameObjectList = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
|
objects: std.ArrayListUnmanaged(GameObjectInterface) = .{},
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
self.* = .{ .allocator = allocator };
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const SpawnFunc = *const fn (*anyopaque) ?GameObjectInterface;
|
||||||
|
|
||||||
|
pub fn spawnObjectFunction(comptime T: type) SpawnFunc {
|
||||||
|
const Wrapped = struct {
|
||||||
|
pub fn w_spawn(list_p: *anyopaque) ?GameObjectInterface {
|
||||||
|
const ctx: *GameObjectList = @ptrCast(@alignCast(list_p));
|
||||||
|
|
||||||
|
return ctx.spawnObject(T) catch null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Wrapped.w_spawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawnObject(self: *@This(), comptime T: type) !GameObjectInterface {
|
||||||
|
const Wrapped = struct {
|
||||||
|
pub fn w_tick(ptr: *anyopaque, dt: f64) void {
|
||||||
|
const object: *T = @ptrCast(@alignCast(ptr));
|
||||||
|
object.tick(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn w_getEntity(ptr: *anyopaque) core.Entity {
|
||||||
|
const object: *T = @ptrCast(@alignCast(ptr));
|
||||||
|
return object.getEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn w_destroy(ptr: *anyopaque) void {
|
||||||
|
const object: *T = @ptrCast(@alignCast(ptr));
|
||||||
|
object.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const VTable = GameObjectInterfaceVTable{
|
||||||
|
.tick = if (@hasDecl(T, "tick")) w_tick else null,
|
||||||
|
.getEntity = if (@hasDecl(T, "getEntity")) w_getEntity else null,
|
||||||
|
.destroy = w_destroy,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const new = try T.create(self.allocator);
|
||||||
|
new.data = .{
|
||||||
|
.index = @intCast(self.objects.items.len),
|
||||||
|
.list = self,
|
||||||
|
};
|
||||||
|
|
||||||
|
const interface = GameObjectInterface{
|
||||||
|
.vtable = &Wrapped.VTable,
|
||||||
|
.ptr = new,
|
||||||
|
.data = &new.data,
|
||||||
|
};
|
||||||
|
|
||||||
|
try self.objects.append(self.allocator, interface);
|
||||||
|
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn newObject(self: *@This(), comptime T: type) !*T {
|
||||||
|
const interface = try self.spawnObject(T);
|
||||||
|
|
||||||
|
return @ptrCast(@alignCast(interface.ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
for (self.objects.items) |interface| {
|
||||||
|
if (interface.vtable.tick) |tick_fn| {
|
||||||
|
tick_fn(interface.ptr, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
for (self.objects.items) |interface| {
|
||||||
|
interface.vtable.destroy(interface.ptr);
|
||||||
|
}
|
||||||
|
self.objects.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const core = @import("../core.zig");
|
||||||
|
|
@ -23,6 +23,7 @@ test "simple systems setup for core" {
|
||||||
|
|
||||||
try test_loadingConfigs();
|
try test_loadingConfigs();
|
||||||
try test_consoleCommands();
|
try test_consoleCommands();
|
||||||
|
try test_gameObjects(std.testing.allocator);
|
||||||
|
|
||||||
try memory.dumpTimeline("test-core-timeline.txt");
|
try memory.dumpTimeline("test-core-timeline.txt");
|
||||||
}
|
}
|
||||||
|
|
@ -47,6 +48,8 @@ fn test_loadingConfigs() !void {
|
||||||
if (core.getConfigVar([]const u8, "platform.windowName")) |height| {
|
if (core.getConfigVar([]const u8, "platform.windowName")) |height| {
|
||||||
core.engine_log("config string: {s}", .{height});
|
core.engine_log("config string: {s}", .{height});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try core.assert(core.configVar(f64, "platform.extent.height", 0) == core.getConfigVar(f64, "platform.extent.height").?);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_consoleCommands() !void {
|
fn test_consoleCommands() !void {
|
||||||
|
|
@ -81,3 +84,54 @@ fn test_consoleCommands() !void {
|
||||||
core.console.evaluate("echo lmfao");
|
core.console.evaluate("echo lmfao");
|
||||||
core.console.evaluate("foo lmfao");
|
core.console.evaluate("foo lmfao");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_gameObjects(allocator: std.mem.Allocator) !void {
|
||||||
|
engine_logs("test: gameobjects... ");
|
||||||
|
|
||||||
|
const objList = try core.GameObjectList.create(allocator);
|
||||||
|
defer objList.destroy();
|
||||||
|
|
||||||
|
const GameObject = struct {
|
||||||
|
data: core.GameObjectData = undefined,
|
||||||
|
entity: core.Entity,
|
||||||
|
|
||||||
|
pub fn create(alloc: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try alloc.create(@This());
|
||||||
|
self.entity = try core.createEntity();
|
||||||
|
_ = self.entity.addComponent(core.Scene);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getEntity(self: *@This()) core.Entity {
|
||||||
|
return self.entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
_ = dt;
|
||||||
|
engine_log("gameObject ticking.... {d} {d}", .{ self.data.index, self.entity.handle.index });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.entity.destroy();
|
||||||
|
self.data.release(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const gameObject = try objList.newObject(GameObject);
|
||||||
|
|
||||||
|
const gameObject2 = try objList.newObject(GameObject);
|
||||||
|
objList.tick(0.016);
|
||||||
|
gameObject.destroy();
|
||||||
|
|
||||||
|
objList.tick(0.016);
|
||||||
|
gameObject2.destroy();
|
||||||
|
objList.tick(0.016);
|
||||||
|
|
||||||
|
const spawnFunc = core.GameObjectList.spawnObjectFunction(GameObject);
|
||||||
|
const interface = spawnFunc(objList).?;
|
||||||
|
|
||||||
|
core.engine_log("handle = {x}", .{interface.vtable.getEntity.?(interface.ptr).handle.index});
|
||||||
|
|
||||||
|
objList.tick(0.016);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
pub const FpCamera = @import("FpCamera.zig");
|
pub const FpCamera = @import("FpCamera.zig");
|
||||||
|
|
||||||
pub const inputDebugger = @import("inputDebugger.zig");
|
pub const inputDebugger = @import("inputDebugger.zig");
|
||||||
|
|
||||||
|
pub const ObjectSpawner = @import("objectSpawner.zig");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
objectList: *core.GameObjectList,
|
||||||
|
windowOpen: bool = true,
|
||||||
|
spawnFuncs: std.ArrayListUnmanaged(SpawnEntry) = .{},
|
||||||
|
spawnPosition: core.Vectorf = .{},
|
||||||
|
|
||||||
|
pub const SpawnEntry = struct {
|
||||||
|
typeName: []const u8,
|
||||||
|
spawnFunc: core.GameObjectList.SpawnFunc,
|
||||||
|
};
|
||||||
|
|
||||||
|
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 tick(self: *@This(), dt: f64) void {
|
||||||
|
self.objectList.tick(dt);
|
||||||
|
|
||||||
|
if (self.windowOpen) {
|
||||||
|
if (ig.begin("object Spawner", null, .{})) {
|
||||||
|
for (self.spawnFuncs.items) |entry| {
|
||||||
|
if (ig.smallButton(entry.typeName.ptr)) {
|
||||||
|
if (entry.spawnFunc(self.objectList)) |new| {
|
||||||
|
const entity = new.vtable.getEntity.?(new.ptr);
|
||||||
|
self.prepareEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ig.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addSpawnFunction(self: *@This(), comptime name: []const u8, comptime T: type) !void {
|
||||||
|
try self.spawnFuncs.append(self.allocator, .{ .typeName = name, .spawnFunc = core.GameObjectList.spawnObjectFunction(T) });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepareEntity(self: *@This(), entity: core.Entity) void {
|
||||||
|
if (entity.fetch(core.Scene)) |scene| {
|
||||||
|
scene.setPosition(self.spawnPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
@ -199,7 +199,7 @@ pub fn SparseMultiSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
||||||
return self.createObjectInternal(initValue, handle.index, handle.generation);
|
return self.createObjectInternal(initValue, handle.index, handle.generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroyObject(self: *@This(), handle: SetHandle) bool {
|
pub fn destroyObject(self: *@This(), handle: SetHandle) false {
|
||||||
// to destroy an object
|
// to destroy an object
|
||||||
// get handle and get the dense position, swap and remove.
|
// get handle and get the dense position, swap and remove.
|
||||||
// Then insert the tombstone value into the sparse handle
|
// Then insert the tombstone value into the sparse handle
|
||||||
|
|
@ -225,8 +225,6 @@ pub fn SparseMultiSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
||||||
if (self.containerListener) |l| {
|
if (self.containerListener) |l| {
|
||||||
l.onHandleRemoved(l.ptr, self.containerID, handle);
|
l.onHandleRemoved(l.ptr, self.containerID, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var prng = std.Random.DefaultPrng.init(0x1234);
|
var prng = std.Random.DefaultPrng.init(0x1234);
|
||||||
|
|
@ -469,7 +467,7 @@ pub fn SparseSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
||||||
// Will fail if the handle already exists.
|
// Will fail if the handle already exists.
|
||||||
pub fn createWithHandle(self: *@This(), handle: SetHandle, initValue: T) !ConstructResult {
|
pub fn createWithHandle(self: *@This(), handle: SetHandle, initValue: T) !ConstructResult {
|
||||||
if (handle.index >= DefaultSparseSize) {
|
if (handle.index >= DefaultSparseSize) {
|
||||||
std.debug.print("this should never happen handle index is huge: {d}\n", .{handle.index});
|
std.debug.print("this should never happen handle index is huge: {x} {d}\n", .{ handle.index, handle.index });
|
||||||
@panic("impossible handle");
|
@panic("impossible handle");
|
||||||
}
|
}
|
||||||
var currentDenseHandle = self.sparse[handle.index];
|
var currentDenseHandle = self.sparse[handle.index];
|
||||||
|
|
@ -709,6 +707,7 @@ pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterface
|
||||||
handleExists: *const fn (*const anyopaque, SetHandle) bool,
|
handleExists: *const fn (*const anyopaque, SetHandle) bool,
|
||||||
get: *const fn (*const anyopaque, SetHandle) ?*anyopaque,
|
get: *const fn (*const anyopaque, SetHandle) ?*anyopaque,
|
||||||
createWithHandle: *const fn (*anyopaque, SetHandle) *anyopaque,
|
createWithHandle: *const fn (*anyopaque, SetHandle) *anyopaque,
|
||||||
|
destroyObject: *const fn (*anyopaque, SetHandle) void,
|
||||||
getContainerID: *const fn (*const anyopaque) u32,
|
getContainerID: *const fn (*const anyopaque) u32,
|
||||||
onRegister: *const fn (*anyopaque, u32, ContainerListener) void,
|
onRegister: *const fn (*anyopaque, u32, ContainerListener) void,
|
||||||
evictFromRegistry: *const fn (*anyopaque) void,
|
evictFromRegistry: *const fn (*anyopaque) void,
|
||||||
|
|
@ -736,6 +735,12 @@ pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterface
|
||||||
return @ptrCast(ptr.get(handle));
|
return @ptrCast(ptr.get(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroyObject(p: *anyopaque, handle: SetHandle) void {
|
||||||
|
// std.debug.print("creat with handle {p}\n", .{p});
|
||||||
|
var ptr = @as(*TargetType, @ptrCast(@alignCast(p)));
|
||||||
|
ptr.destroyObject(handle);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn createWithHandle(p: *anyopaque, handle: SetHandle) *anyopaque {
|
pub fn createWithHandle(p: *anyopaque, handle: SetHandle) *anyopaque {
|
||||||
// std.debug.print("creat with handle {p}\n", .{p});
|
// std.debug.print("creat with handle {p}\n", .{p});
|
||||||
var ptr = @as(*TargetType, @ptrCast(@alignCast(p)));
|
var ptr = @as(*TargetType, @ptrCast(@alignCast(p)));
|
||||||
|
|
@ -769,6 +774,7 @@ pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterface
|
||||||
.handleExists = Wrap.handleExists,
|
.handleExists = Wrap.handleExists,
|
||||||
.get = Wrap.get,
|
.get = Wrap.get,
|
||||||
.createWithHandle = Wrap.createWithHandle,
|
.createWithHandle = Wrap.createWithHandle,
|
||||||
|
.destroyObject = Wrap.destroyObject,
|
||||||
.getContainerID = Wrap.getContainerID,
|
.getContainerID = Wrap.getContainerID,
|
||||||
.onRegister = Wrap.onRegister,
|
.onRegister = Wrap.onRegister,
|
||||||
.evictFromRegistry = Wrap.evictFromRegistry,
|
.evictFromRegistry = Wrap.evictFromRegistry,
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,9 @@ doomplayer: *DoomPlayer = undefined,
|
||||||
videoplayerObject: core.Entity = undefined,
|
videoplayerObject: core.Entity = undefined,
|
||||||
doomplayerObject: core.Entity = undefined,
|
doomplayerObject: core.Entity = undefined,
|
||||||
|
|
||||||
inputEnabled: bool = true,
|
objectSpawner: *extras.ObjectSpawner = undefined,
|
||||||
|
|
||||||
|
inputEnabled: bool = true,
|
||||||
videoFullbright: bool = false,
|
videoFullbright: bool = false,
|
||||||
|
|
||||||
moveLight: bool = true,
|
moveLight: bool = true,
|
||||||
|
|
@ -47,16 +48,16 @@ const assetReferences = [_]assets.AssetImportReference{
|
||||||
"m_skybox",
|
"m_skybox",
|
||||||
.{ .path = "meshes/skybox.obj" },
|
.{ .path = "meshes/skybox.obj" },
|
||||||
),
|
),
|
||||||
// assets.MakeImportRefOptions(
|
assets.MakeImportRefOptions(
|
||||||
// "Mesh",
|
"Mesh",
|
||||||
// "m_fox",
|
"m_fox",
|
||||||
// .{ .path = "gltf-samples/Fox/glTF/Fox.gltf" },
|
.{ .path = "gltf-samples/Fox/glTF/Fox.gltf" },
|
||||||
// ),
|
),
|
||||||
// assets.MakeImportRefOptions(
|
assets.MakeImportRefOptions(
|
||||||
// "Texture",
|
"Texture",
|
||||||
// "t_fox",
|
"t_fox",
|
||||||
// .{ .path = "gltf-samples/Fox/glTF/Texture.png" },
|
.{ .path = "gltf-samples/Fox/glTF/Texture.png" },
|
||||||
// ),
|
),
|
||||||
assets.MakeImportRefOptions(
|
assets.MakeImportRefOptions(
|
||||||
"Texture",
|
"Texture",
|
||||||
"t_empire",
|
"t_empire",
|
||||||
|
|
@ -79,6 +80,35 @@ const assetReferences = [_]assets.AssetImportReference{
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const FoxObject = struct {
|
||||||
|
data: core.GameObjectData = undefined,
|
||||||
|
entity: core.Entity,
|
||||||
|
|
||||||
|
pub fn create(alloc: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try alloc.create(@This());
|
||||||
|
const fox = try core.createEntity();
|
||||||
|
const scene = fox.addComponent(core.Scene).?;
|
||||||
|
|
||||||
|
scene.setScale(0.1, 0.1, 0.1);
|
||||||
|
const mesh = fox.addComponent(rend.MeshComponent).?;
|
||||||
|
mesh.setMesh("m_fox");
|
||||||
|
mesh.setTexture("t_fox");
|
||||||
|
|
||||||
|
self.entity = fox;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getEntity(self: *@This()) core.Entity {
|
||||||
|
return self.entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.entity.destroy();
|
||||||
|
self.data.release(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn prepare(self: *@This()) !void {
|
pub fn prepare(self: *@This()) !void {
|
||||||
core.engine_log(">>>>>>> game prepare", .{});
|
core.engine_log(">>>>>>> game prepare", .{});
|
||||||
var z = core.tracy.ZoneN(@src(), "PREPARING GAME");
|
var z = core.tracy.ZoneN(@src(), "PREPARING GAME");
|
||||||
|
|
@ -87,6 +117,9 @@ pub fn prepare(self: *@This()) !void {
|
||||||
try script.loadTypes("scripts");
|
try script.loadTypes("scripts");
|
||||||
try script.runScriptFile("scripts/prepare.lua");
|
try script.runScriptFile("scripts/prepare.lua");
|
||||||
|
|
||||||
|
self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
|
||||||
|
try self.objectSpawner.addSpawnFunction("fox", FoxObject);
|
||||||
|
|
||||||
try assets.loadList(assetReferences);
|
try assets.loadList(assetReferences);
|
||||||
self.videoplayer = try VideoPlayer.create(self.allocator);
|
self.videoplayer = try VideoPlayer.create(self.allocator);
|
||||||
try self.videoplayer.startPlayback("LAPWING2.ogv");
|
try self.videoplayer.startPlayback("LAPWING2.ogv");
|
||||||
|
|
@ -293,6 +326,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
const fdt: f32 = @floatCast(dt);
|
const fdt: f32 = @floatCast(dt);
|
||||||
|
|
||||||
extras.inputDebugger.tick();
|
extras.inputDebugger.tick();
|
||||||
|
self.objectSpawner.tick(dt);
|
||||||
self.videoplayer.tick(dt);
|
self.videoplayer.tick(dt);
|
||||||
self.doomplayer.tick(dt);
|
self.doomplayer.tick(dt);
|
||||||
self.fpcamera.tick(dt);
|
self.fpcamera.tick(dt);
|
||||||
|
|
@ -312,6 +346,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
|
||||||
const forward = self.fpcamera.getForward();
|
const forward = self.fpcamera.getForward();
|
||||||
const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist));
|
const debugCenter = self.fpcamera.getPosition().add(forward.fmul(self.centerDist));
|
||||||
|
self.objectSpawner.spawnPosition = debugCenter;
|
||||||
|
|
||||||
if (self.moveLight) {
|
if (self.moveLight) {
|
||||||
core.debugSphere(debugCenter, 0.3, .{});
|
core.debugSphere(debugCenter, 0.3, .{});
|
||||||
|
|
@ -339,6 +374,7 @@ pub fn deinit(self: *@This()) void {
|
||||||
self.doomplayer.destroy();
|
self.doomplayer.destroy();
|
||||||
self.fpcamera.destroy();
|
self.fpcamera.destroy();
|
||||||
|
|
||||||
|
self.objectSpawner.destroy();
|
||||||
self.videoplayer.destroy();
|
self.videoplayer.destroy();
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue