moved filewatch out of packer, and moving spng to rend, and deleted a lot of dead code
This commit is contained in:
parent
08bad270e6
commit
180badad39
|
|
@ -2,14 +2,9 @@ const std = @import("std");
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"p2",
|
"p2",
|
||||||
"tracy",
|
"tracy", // usually doesnt have C deps... unless we're compiled with it on, in which case we only support static builds
|
||||||
"zmath",
|
"zmath",
|
||||||
"packer", // packer might need to be split into another setup that doesn't have C deps.
|
"packer", // packer no longer has C deps.
|
||||||
|
|
||||||
// these ones use c deps, but if i move them out to platform... then core will have zero c dependencies.
|
|
||||||
"lua",
|
|
||||||
"spng",
|
|
||||||
// "nfd",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.name = .core,
|
.name = .core,
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.spng = .{ .path = "../../lib/spng" },
|
// .spng = .{ .path = "../../lib/spng" },
|
||||||
// .nfd = .{ .path = "../../lib/nfd" },
|
// .nfd = .{ .path = "../../lib/nfd" },
|
||||||
|
|
||||||
// with -Dtracy = false, this one pulls in no C dependencies
|
// with -Dtracy = false, this one pulls in no C dependencies
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
.zmath = .{ .path = "../../lib/zmath" },
|
.zmath = .{ .path = "../../lib/zmath" },
|
||||||
.packer = .{ .path = "../../lib/packer" },
|
.packer = .{ .path = "../../lib/packer" },
|
||||||
.p2 = .{ .path = "../../lib/p2" },
|
.p2 = .{ .path = "../../lib/p2" },
|
||||||
.lua = .{ .path = "../../lib/lua" },
|
// .lua = .{ .path = "../../lib/lua" },
|
||||||
// .zgltf = .{ .path = "../../lib/zgltf" },
|
// .zgltf = .{ .path = "../../lib/zgltf" },
|
||||||
},
|
},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ pub const debugBox = debug_draw.debugBox;
|
||||||
pub const debugLine = debug_draw.debugLine;
|
pub const debugLine = debug_draw.debugLine;
|
||||||
// pub const script_bindings = script.script_bindings;
|
// pub const script_bindings = script.script_bindings;
|
||||||
|
|
||||||
pub const misc = @import("misc.zig");
|
|
||||||
pub const engineTime = @import("engineTime.zig");
|
pub const engineTime = @import("engineTime.zig");
|
||||||
pub const engineObject = @import("engineObject.zig");
|
pub const engineObject = @import("engineObject.zig");
|
||||||
pub const EngineObjectVTable = engineObject.EngineObjectVTable;
|
pub const EngineObjectVTable = engineObject.EngineObjectVTable;
|
||||||
|
|
@ -43,12 +42,8 @@ pub const ThreadContext = jobs.ThreadContext;
|
||||||
pub const JobManager = jobs.JobManager;
|
pub const JobManager = jobs.JobManager;
|
||||||
pub const JobWorker = jobs.JobWorker;
|
pub const JobWorker = jobs.JobWorker;
|
||||||
|
|
||||||
pub const file_utils = @import("file_utils.zig");
|
|
||||||
pub const string_utils = @import("string_utils.zig");
|
|
||||||
pub const type_utils = @import("type_utils.zig");
|
|
||||||
pub const engine = @import("engine.zig");
|
pub const engine = @import("engine.zig");
|
||||||
pub const tracy = @import("tracy").t;
|
pub const tracy = @import("tracy").t;
|
||||||
pub const png = @import("png.zig");
|
|
||||||
|
|
||||||
pub const colors = @import("colors.zig");
|
pub const colors = @import("colors.zig");
|
||||||
|
|
||||||
|
|
@ -141,8 +136,6 @@ pub const SceneSystem = scene.SceneSystem;
|
||||||
|
|
||||||
pub const Engine = engine.Engine;
|
pub const Engine = engine.Engine;
|
||||||
|
|
||||||
pub const spng = @import("spng");
|
|
||||||
|
|
||||||
pub const MemoryTracker = @import("MemoryTracker.zig");
|
pub const MemoryTracker = @import("MemoryTracker.zig");
|
||||||
|
|
||||||
pub const DefaultSavePath = "Saved";
|
pub const DefaultSavePath = "Saved";
|
||||||
|
|
@ -173,14 +166,16 @@ pub const defaultHighlight = logging.defaultHighlight;
|
||||||
|
|
||||||
pub const packer = @import("packer");
|
pub const packer = @import("packer");
|
||||||
|
|
||||||
pub const FileSystem = packer.PackerFS;
|
|
||||||
pub const PackerFS = packer.PackerFS;
|
|
||||||
|
|
||||||
pub const StackCompactor = stacks.StackCompactor;
|
pub const StackCompactor = stacks.StackCompactor;
|
||||||
|
|
||||||
var staticsInitialized = false;
|
var staticsInitialized = false;
|
||||||
var gEngine: *Engine = undefined;
|
var gEngine: *Engine = undefined;
|
||||||
|
pub const PackerFS = packer.PackerFS;
|
||||||
var gPackerFS: *PackerFS = undefined;
|
var gPackerFS: *PackerFS = undefined;
|
||||||
|
|
||||||
|
pub fn fs() *PackerFS {
|
||||||
|
return gPackerFS;
|
||||||
|
}
|
||||||
var fsInitialized: bool = false;
|
var fsInitialized: bool = false;
|
||||||
|
|
||||||
pub fn EngineObject(comptime T: type) type {
|
pub fn EngineObject(comptime T: type) type {
|
||||||
|
|
@ -217,8 +212,6 @@ pub const undefineComponentList = ecs.undefineComponentList;
|
||||||
pub const Entity = ecs.Entity;
|
pub const Entity = ecs.Entity;
|
||||||
pub const createEntity = ecs.createEntity;
|
pub const createEntity = ecs.createEntity;
|
||||||
|
|
||||||
pub const script = @import("script.zig");
|
|
||||||
|
|
||||||
pub const stacks = @import("stacks.zig");
|
pub const stacks = @import("stacks.zig");
|
||||||
pub const walkAndPrintStack = stacks.walkAndPrintStack;
|
pub const walkAndPrintStack = stacks.walkAndPrintStack;
|
||||||
|
|
||||||
|
|
@ -237,10 +230,6 @@ pub fn registerObjectAdvanced(comptime T: type, name: []const u8, comptime funcN
|
||||||
try get(GameObjectSystem).registerObjectAdvanced(name, T, funcName);
|
try get(GameObjectSystem).registerObjectAdvanced(name, T, funcName);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fs() *PackerFS {
|
|
||||||
return gPackerFS;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Module = ModuleDescription{
|
pub const Module = ModuleDescription{
|
||||||
.name = "core",
|
.name = "core",
|
||||||
.enabledByDefault = true,
|
.enabledByDefault = true,
|
||||||
|
|
@ -295,15 +284,9 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
||||||
fatDump = true;
|
fatDump = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
script.lua.setupMiniDump(fatDump);
|
|
||||||
_ = try algorithm.createNameRegistry(allocator);
|
_ = try algorithm.createNameRegistry(allocator);
|
||||||
// LUA BEGIN -- what if i want to make the scripting integration optional?
|
|
||||||
// try script.start_lua(allocator);
|
|
||||||
// LUA END
|
|
||||||
try maybeInitPackerFs(allocator);
|
try maybeInitPackerFs(allocator);
|
||||||
|
|
||||||
// load configs.
|
|
||||||
//const name = if (@hasField(@TypeOf(programSpec), "configName")) programSpec.configName else programSpec.name;
|
|
||||||
var name = map.get("name").?.string;
|
var name = map.get("name").?.string;
|
||||||
|
|
||||||
if (map.get("configName")) |x| {
|
if (map.get("configName")) |x| {
|
||||||
|
|
@ -330,8 +313,6 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
||||||
|
|
||||||
try algorithm.string_pool.setup(allocator);
|
try algorithm.string_pool.setup(allocator);
|
||||||
|
|
||||||
// _ = try gEngine.createObject(script_bindings.ScriptTicks, .{ .can_tick = true });
|
|
||||||
|
|
||||||
_ = try createObject(GameObjectSystem, .{ .can_tick = true });
|
_ = try createObject(GameObjectSystem, .{ .can_tick = true });
|
||||||
_ = try inputs.initInputStack();
|
_ = try inputs.initInputStack();
|
||||||
|
|
||||||
|
|
@ -344,7 +325,6 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
||||||
pub fn setupFromModule(__args: ModuleLoaderArgs) !void {
|
pub fn setupFromModule(__args: ModuleLoaderArgs) !void {
|
||||||
gEngine = __args.engine;
|
gEngine = __args.engine;
|
||||||
gPackerFS = __args.packerFS;
|
gPackerFS = __args.packerFS;
|
||||||
// script.setupLuaFromModule(__args.luaState, __args.luaAllocator);
|
|
||||||
algorithm.names.gRegistry = __args.nameRegistry;
|
algorithm.names.gRegistry = __args.nameRegistry;
|
||||||
logging.setupLoggingFromModule();
|
logging.setupLoggingFromModule();
|
||||||
staticsInitialized = true;
|
staticsInitialized = true;
|
||||||
|
|
@ -368,9 +348,6 @@ pub fn shutdown_module(_: std.mem.Allocator) void {
|
||||||
ecs.shutdown();
|
ecs.shutdown();
|
||||||
algorithm.destroyNameRegistry();
|
algorithm.destroyNameRegistry();
|
||||||
gPackerFS.destroy();
|
gPackerFS.destroy();
|
||||||
// LUA BEGIN
|
|
||||||
// script.shutdown_lua();
|
|
||||||
// LUA END
|
|
||||||
console.shutdown();
|
console.shutdown();
|
||||||
algorithm.string_pool.shutdown();
|
algorithm.string_pool.shutdown();
|
||||||
|
|
||||||
|
|
@ -396,8 +373,6 @@ pub fn parallelJob(capture: anytype, async: bool, maxWorkerCount: ?u32) !void {
|
||||||
if (!async) {
|
if (!async) {
|
||||||
try jobManager.runLocally(capture, .{ .threadId = 0, .threadCount = baseWorkerCount });
|
try jobManager.runLocally(capture, .{ .threadId = 0, .threadCount = baseWorkerCount });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatchJob(capture: anytype) !void {
|
pub fn dispatchJob(capture: anytype) !void {
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ pub const ModuleLoader = struct {
|
||||||
arena: std.heap.ArenaAllocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
|
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
|
||||||
watchInitialized: bool = false,
|
watchInitialized: bool = false,
|
||||||
|
watchInitializeFn: ?*const fn () void = null,
|
||||||
|
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
||||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
|
@ -150,9 +151,12 @@ pub const ModuleLoader = struct {
|
||||||
const loaded = try self.arena.allocator().create(LoadedModule);
|
const loaded = try self.arena.allocator().create(LoadedModule);
|
||||||
|
|
||||||
if (self.watchInitialized == false) {
|
if (self.watchInitialized == false) {
|
||||||
core.fs().watchPath("zig-out/modules/");
|
// core.fs().watchPath("zig-out/modules/");
|
||||||
|
if (self.watchInitializeFn) |watchInitializeFn| {
|
||||||
|
watchInitializeFn();
|
||||||
self.watchInitialized = true;
|
self.watchInitialized = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loaded.* = LoadedModule{
|
loaded.* = LoadedModule{
|
||||||
.baseModulePath = try std.fmt.allocPrint(self.arena.allocator(), "zig-out/modules/{s}", .{libFileName}),
|
.baseModulePath = try std.fmt.allocPrint(self.arena.allocator(), "zig-out/modules/{s}", .{libFileName}),
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const logging = @import("logging.zig");
|
|
||||||
|
|
||||||
pub fn writeToFile(data: []const u8, path: []const u8) !void {
|
|
||||||
const file = try std.fs.cwd().createFile(
|
|
||||||
path,
|
|
||||||
.{
|
|
||||||
.read = true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const bytes_written = try file.writeAll(data);
|
|
||||||
_ = bytes_written;
|
|
||||||
logging.engine_log("written: bytes to {s}", .{path});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn splitIntoLines(file_contents: []const u8) std.mem.SplitIterator(u8) {
|
|
||||||
// find a \n and see if it has \r\n
|
|
||||||
var index: u32 = 0;
|
|
||||||
while (index < file_contents.len) : (index += 1) {
|
|
||||||
if (file_contents[index] == '\n') {
|
|
||||||
if (index > 0) {
|
|
||||||
if (file_contents[index - 1] == '\r') {
|
|
||||||
return std.mem.split(u8, file_contents, "\r\n");
|
|
||||||
} else {
|
|
||||||
return std.mem.split(u8, file_contents, "\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return std.mem.split(u8, file_contents, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std.mem.split(u8, file_contents, "\n");
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
|
|
||||||
moveAxis = CreateInput2DAxis()
|
|
||||||
moveAxis:addKey(Keys.W, 1.0, Axis.Y)
|
|
||||||
moveAxis:addKey(Keys.S, -1.0, Axis.Y)
|
|
||||||
|
|
||||||
moveAxis:addKey(Keys.A, -1.0, Axis.X)
|
|
||||||
moveAxis:addKey(Keys.D, 1.0, Axis.X)
|
|
||||||
moveAxis:addListener(balls, )
|
|
||||||
|
|
||||||
Input.addBinding("move", moveAxis, true)
|
|
||||||
|
|
||||||
Input.removeBinding("move")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
|
|
||||||
tickables = {}
|
|
||||||
properties = {}
|
|
||||||
|
|
||||||
local function registerTick(object, f)
|
|
||||||
table.insert(tickables, {obj = object, func = f})
|
|
||||||
end
|
|
||||||
|
|
||||||
function __TickScripts(deltaTime)
|
|
||||||
for index, entry in ipairs(tickables) do
|
|
||||||
entry.func(entry.obj, deltaTime)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function __RegisterEntityProperty(userdata)
|
|
||||||
properties[userdata] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetProperty(entity, property)
|
|
||||||
properties[entity] = property
|
|
||||||
end
|
|
||||||
|
|
||||||
function GetProperty(entity)
|
|
||||||
return properties[entity]
|
|
||||||
end
|
|
||||||
|
|
||||||
function GetObject(entity)
|
|
||||||
return properties[entity]
|
|
||||||
end
|
|
||||||
|
|
||||||
Core = {
|
|
||||||
registerTick = registerTick;
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
print("Hello from lua.")
|
|
||||||
|
|
||||||
|
|
@ -1,14 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const misc = @import("misc.zig");
|
|
||||||
const zm = @import("zmath");
|
const zm = @import("zmath");
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
|
|
||||||
// LUA BEGIN feel like I should mark up the parts of the engine that need to be
|
|
||||||
// sliced out should i ever decide I'm sick of lua
|
|
||||||
const lua = @import("lua");
|
|
||||||
const pod = lua.pod;
|
|
||||||
// LUA END
|
|
||||||
|
|
||||||
// vector versions.
|
// vector versions.
|
||||||
pub const f32x4 = @Vector(4, f32); // __m128_int
|
pub const f32x4 = @Vector(4, f32); // __m128_int
|
||||||
pub const f32x8 = @Vector(8, f32); // __m256_int
|
pub const f32x8 = @Vector(8, f32); // __m256_int
|
||||||
|
|
@ -72,23 +65,7 @@ pub fn Vector2Type(comptime T: type, comptime typeName: []const u8) type {
|
||||||
x: T = 0,
|
x: T = 0,
|
||||||
y: T = 0,
|
y: T = 0,
|
||||||
|
|
||||||
// LUA BEGIN
|
pub const VectorTypeName = typeName;
|
||||||
pub const PodDataTable: pod.DataTable = .{
|
|
||||||
.name = typeName,
|
|
||||||
.funcs = &.{
|
|
||||||
"fmul",
|
|
||||||
"dot",
|
|
||||||
"length",
|
|
||||||
"normalize",
|
|
||||||
},
|
|
||||||
.operators = .{
|
|
||||||
.add = "add",
|
|
||||||
.sub = "sub",
|
|
||||||
.mul = "vmul",
|
|
||||||
.eq = "equals",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// LUA END
|
|
||||||
|
|
||||||
pub const Ones = @This(){ .x = 1, .y = 1 };
|
pub const Ones = @This(){ .x = 1, .y = 1 };
|
||||||
pub const Zeroes = @This(){ .x = 0, .y = 0 };
|
pub const Zeroes = @This(){ .x = 0, .y = 0 };
|
||||||
|
|
@ -232,6 +209,8 @@ pub fn Vector3Type(comptime T: type, comptime typeName: []const u8) type {
|
||||||
y: T = 0,
|
y: T = 0,
|
||||||
z: T = 0,
|
z: T = 0,
|
||||||
|
|
||||||
|
pub const VectorTypeName = typeName;
|
||||||
|
|
||||||
pub const Ones = @This(){ .x = 1, .y = 1, .z = 1 };
|
pub const Ones = @This(){ .x = 1, .y = 1, .z = 1 };
|
||||||
pub const Zeroes = @This(){ .x = 0, .y = 0, .z = 0 };
|
pub const Zeroes = @This(){ .x = 0, .y = 0, .z = 0 };
|
||||||
|
|
||||||
|
|
@ -239,24 +218,6 @@ pub fn Vector3Type(comptime T: type, comptime typeName: []const u8) type {
|
||||||
pub const Right = @This(){ .x = 1 };
|
pub const Right = @This(){ .x = 1 };
|
||||||
pub const Forward = @This(){ .z = 1 };
|
pub const Forward = @This(){ .z = 1 };
|
||||||
|
|
||||||
// LUA BEGIN
|
|
||||||
pub const PodDataTable: pod.DataTable = .{
|
|
||||||
.name = typeName,
|
|
||||||
.funcs = &.{
|
|
||||||
"fmul",
|
|
||||||
"dot",
|
|
||||||
"length",
|
|
||||||
"normalize",
|
|
||||||
},
|
|
||||||
.operators = .{
|
|
||||||
.add = "add",
|
|
||||||
.sub = "sub",
|
|
||||||
.mul = "vmul",
|
|
||||||
.eq = "equals",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// LUA END
|
|
||||||
|
|
||||||
pub inline fn new(x: T, y: T, z: T) @This() {
|
pub inline fn new(x: T, y: T, z: T) @This() {
|
||||||
return .{
|
return .{
|
||||||
.x = x,
|
.x = x,
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
// Random misc. utilities that aren't /totally/ categorized right now.
|
|
||||||
|
|
||||||
const logging = @import("logging.zig");
|
|
||||||
|
|
||||||
// Creates a for-loopable range between [0, n)
|
|
||||||
pub fn count(comptime n: anytype) [n]u0 {
|
|
||||||
return comptime [1]u0{0} ** n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a for-loopable range between [start, end).
|
|
||||||
// reccomended for use with inline FORs
|
|
||||||
pub fn range(comptime start: usize, comptime end: anytype) [end - start]@TypeOf(start) {
|
|
||||||
comptime var r = [1]@TypeOf(start){start} ** (end - start);
|
|
||||||
|
|
||||||
comptime {
|
|
||||||
for (r, 0..) |val, i| {
|
|
||||||
r[i] = val + i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return comptime r;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn slice_to_cstr(str: []const u8) ?[*:0]const u8 {
|
|
||||||
return @as(?[*:0]const u8, @ptrCast(str.ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn buf_to_cstr(str: anytype) ?[*:0]const u8 {
|
|
||||||
return @as(?[*:0]const u8, @ptrCast(&str[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const CStr = [*:0]const u8;
|
|
||||||
|
|
||||||
pub fn debug_struct(preamble: []const u8, s: anytype) void {
|
|
||||||
logging.graphics_log("{s}:", .{preamble});
|
|
||||||
logging.graphics_log(" {any}", .{s});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn p_to_av(a: anytype) [*]@TypeOf(a.*) {
|
|
||||||
return @as([*]@TypeOf(a.*), @ptrCast(a));
|
|
||||||
}
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
||||||
// scripting integration using lua
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
pub const lua = @import("lua");
|
|
||||||
const core = @import("core.zig");
|
|
||||||
const startup_script = @embedFile("lua/startup.lua");
|
|
||||||
const core_script = @embedFile("lua/core.lua");
|
|
||||||
const ecs = @import("ecs.zig");
|
|
||||||
const ComponentRef = @import("script/ComponentRef.zig");
|
|
||||||
const ComponentRegistration = @import("script/ComponentRegistration.zig");
|
|
||||||
|
|
||||||
pub const script_bindings = @import("script_bindings.zig");
|
|
||||||
|
|
||||||
const c = lua.c;
|
|
||||||
|
|
||||||
pub var gLuaState: lua.LuaState = undefined;
|
|
||||||
pub var gLuaAllocator: std.mem.Allocator = undefined;
|
|
||||||
|
|
||||||
pub fn setupLuaFromModule(pstate: *anyopaque, p_lua_allocator: *anyopaque) void {
|
|
||||||
gLuaAllocator = core.startup_getAllocator(p_lua_allocator);
|
|
||||||
gLuaState.l = @ptrCast(pstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
const luaRegLibs: []const c.luaL_Reg = &.{
|
|
||||||
.{ .name = "print", .func = printWrapper },
|
|
||||||
.{ .name = null, .func = null },
|
|
||||||
};
|
|
||||||
|
|
||||||
// binds the default print() function in lua to print to the console
|
|
||||||
fn printWrapper(l: ?*lua.c.lua_State) callconv(.c) i32 {
|
|
||||||
const state: lua.LuaState = .{ .l = l };
|
|
||||||
const argc = state.getTop();
|
|
||||||
|
|
||||||
if (core.getLogger() == null) {
|
|
||||||
core.printRaw("> ", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc >= 1) {
|
|
||||||
core.printRaw("[SCRIPT ]: ", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
var i: i32 = 1;
|
|
||||||
while (i <= argc) : (i += 1) {
|
|
||||||
if (state.isString(i)) {
|
|
||||||
if (i > 1) {
|
|
||||||
core.printRaw(" ", .{});
|
|
||||||
}
|
|
||||||
core.printRaw("{s}", .{state.toString(i)});
|
|
||||||
} else if (state.isUserdata(i)) {
|
|
||||||
const s = state.toStringL(i);
|
|
||||||
state.pop(1);
|
|
||||||
core.printRaw("{s}", .{s});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
core.printRaw("\n", .{});
|
|
||||||
state.pop(argc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialization of the lua scripting interface.
|
|
||||||
// this interface is only threadsafe to operate on from the main systems thread (at this time).
|
|
||||||
pub fn start_lua(allocator: std.mem.Allocator) !void {
|
|
||||||
gLuaAllocator = allocator;
|
|
||||||
gLuaState = try lua.LuaState.init(.{});
|
|
||||||
try lua.pod.setupFormatBuffer(allocator);
|
|
||||||
|
|
||||||
// overload and hook into global functions
|
|
||||||
_ = gLuaState.getGlobal("_G");
|
|
||||||
c.luaL_setfuncs(gLuaState.l, luaRegLibs.ptr, 0);
|
|
||||||
gLuaState.pop(1);
|
|
||||||
|
|
||||||
try lua.pod.registerPodType(&gLuaState, ecs.Entity);
|
|
||||||
try lua.pod.registerPodType(&gLuaState, ComponentRegistration);
|
|
||||||
|
|
||||||
try script_bindings.registerTypes();
|
|
||||||
|
|
||||||
try gLuaState.loadString(startup_script);
|
|
||||||
try gLuaState.pcall();
|
|
||||||
|
|
||||||
try gLuaState.loadString(core_script);
|
|
||||||
try gLuaState.pcall();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn createLuaComponentDefinitions(globalName: []const u8, container: ecs.EcsContainerRef, luaNew: anytype) !void {
|
|
||||||
const reg = try gLuaState.newZigUserdata(ComponentRegistration);
|
|
||||||
reg.ref = container;
|
|
||||||
reg.name = globalName;
|
|
||||||
reg.luaNew = luaNew;
|
|
||||||
try gLuaState.setGlobal(globalName);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn registerComponent(comptime Component: type, container: ecs.EcsContainerRef) !void {
|
|
||||||
const ReferenceType = ComponentRef.ComponentReferenceType(Component);
|
|
||||||
try createLuaComponentDefinitions(@ptrCast(Component.ComponentName), container, ReferenceType.luaNew);
|
|
||||||
try ReferenceType.registerType(getState());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shutdown_lua() void {
|
|
||||||
lua.pod.shutdownFormatBuffer();
|
|
||||||
gLuaState.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getState() *lua.LuaState {
|
|
||||||
return &gLuaState;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn findScriptBasepath(s: []const u8) []const u8 {
|
|
||||||
var i: usize = s.len - 1;
|
|
||||||
|
|
||||||
while (i > 0) : (i -= 1) {
|
|
||||||
if (s[i] == '\\' or s[i] == '/') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s[i] == '\\' or s[i] == '/') {
|
|
||||||
return s[i + 1 ..];
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn loadTypes(scriptPath: []const u8) !void {
|
|
||||||
// 1. scan filesystem for all files under the script path
|
|
||||||
var fileList = try core.fs().listAllSubpaths(gLuaAllocator, scriptPath);
|
|
||||||
defer fileList.deinit();
|
|
||||||
for (fileList.data.items, 0..) |f, i| {
|
|
||||||
// 2. enforce naming scheme for each script.
|
|
||||||
const basePath = findScriptBasepath(f);
|
|
||||||
|
|
||||||
// core.engine_log("checking script file: {s} path:{s} base {s}", .{ f, fileList.sources.items[i], basePath });
|
|
||||||
// 3. for each one, load the script and assign them based on name.
|
|
||||||
if (std.ascii.isUpper(basePath[0])) {
|
|
||||||
core.engine_log("loading script file: {s} path:{s}", .{ f, fileList.sources.items[i] });
|
|
||||||
const scriptFile = try core.fs().loadFile(f);
|
|
||||||
defer core.fs().unmap(scriptFile);
|
|
||||||
try gLuaState.loadString(scriptFile.bytes);
|
|
||||||
try gLuaState.pcall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn runScriptFile(scriptPath: []const u8) !void {
|
|
||||||
const scriptFile = try core.fs().loadFile(scriptPath);
|
|
||||||
defer core.fs().unmap(scriptFile);
|
|
||||||
try gLuaState.loadString(scriptFile.bytes);
|
|
||||||
try gLuaState.pcall();
|
|
||||||
}
|
|
||||||
|
|
@ -1,258 +0,0 @@
|
||||||
// lwdt can't have meta tables so I'm going to create component references
|
|
||||||
//
|
|
||||||
// the way this works is
|
|
||||||
// - entities are created as POD types
|
|
||||||
// - entities can get components added to them via entity:addComponent
|
|
||||||
// - this returns a ComponentReference
|
|
||||||
// - you can also get components from an entity via enity:get()
|
|
||||||
// - this also returns a ComponentReference
|
|
||||||
//
|
|
||||||
// - ComponentReferences allow you to modify data on a component or call functions on them
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// How the registration works
|
|
||||||
//
|
|
||||||
// - define component
|
|
||||||
// - ecs.zig defineComponent
|
|
||||||
// - ComponentRef.zig - ReferenceType
|
|
||||||
// - addComponentRegistration - script.zig
|
|
||||||
// - ComponentRef - ReferenceType.registerType
|
|
||||||
|
|
||||||
// this represents the lua side of the object
|
|
||||||
pub fn ComponentReferenceType(comptime T: type) type {
|
|
||||||
return struct {
|
|
||||||
ptr: *T = undefined,
|
|
||||||
|
|
||||||
// used for resolving deltas.
|
|
||||||
handle: core.ObjectHandle = undefined,
|
|
||||||
stateCount: u32 = 0,
|
|
||||||
containerRef: ecs.EcsContainerRef = undefined,
|
|
||||||
|
|
||||||
pub const MetatableName = T.ComponentName;
|
|
||||||
|
|
||||||
// argc = 1,
|
|
||||||
// 1. a componentRegistration userdata
|
|
||||||
// can only be called from entity.luaAddComponent
|
|
||||||
pub fn luaNew(state: lua.LuaState, handle: core.ObjectHandle, ptr: ?*anyopaque) void {
|
|
||||||
const ud = state.newZigUserdata(@This()) catch return;
|
|
||||||
const containerRef = ecs.getTypeContainer(T);
|
|
||||||
|
|
||||||
ud.* = .{
|
|
||||||
.handle = handle,
|
|
||||||
.containerRef = containerRef,
|
|
||||||
.stateCount = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// std.debug.print("luaNew ComponentReferenceType: {x}\n", .{@intFromPtr(ud)});
|
|
||||||
// std.debug.print("luaNew ContainerRef: {x}\n", .{@intFromPtr(containerRef.ptr)});
|
|
||||||
// std.debug.print("luaNew " ++ @typeName(T) ++ " ud.ptr = {x}\n", .{@intFromPtr(ptr)});
|
|
||||||
|
|
||||||
if (ptr) |p| {
|
|
||||||
ud.ptr = @ptrCast(@alignCast(p));
|
|
||||||
ud.stateCount = containerRef.vtable.getStateCount(containerRef.ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (@hasDecl(@TypeOf(T.BaseContainer.*), "IsMultiset")) {
|
|
||||||
// ... there are several things that need to be reworked here...
|
|
||||||
ud.ptr = @ptrCast(@alignCast(@as(*anyopaque, @ptrCast(&ud.handle))));
|
|
||||||
// std.debug.print("luaNew " ++ @typeName(T) ++ " v = {any}\n", .{ud.ptr.getPosition()});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolve(self: *@This()) void {
|
|
||||||
const ref = self.containerRef;
|
|
||||||
// std.debug.print("self: {x}\n", .{@intFromPtr(self)});
|
|
||||||
// std.debug.print("ptr: {x}\n", .{@intFromPtr(ref.ptr)});
|
|
||||||
if (@hasDecl(@TypeOf(T.BaseContainer.*), "IsMultiset")) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
if (ref.vtable.getStateCount(ref.ptr) != self.stateCount) {
|
|
||||||
self.ptr = @ptrCast(@alignCast(ref.vtable.get(ref.ptr, self.handle)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(self: *@This()) *T {
|
|
||||||
self.resolve();
|
|
||||||
return self.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn luaToString(state: lua.LuaState) i32 {
|
|
||||||
// oh god... this isn't good
|
|
||||||
// I think i've been treating this component ref as the user type
|
|
||||||
// huge failure of type resolution
|
|
||||||
if (state.toUserdata(@This(), 1)) |self| {
|
|
||||||
self.resolve();
|
|
||||||
Buffer.clearRetainingCapacity();
|
|
||||||
|
|
||||||
var writer = Buffer.writer();
|
|
||||||
writer.print("{s}{{", .{MetatableName}) catch return 0;
|
|
||||||
|
|
||||||
inline for (std.meta.fields(T), 0..) |field, i| {
|
|
||||||
if (i == 0) {
|
|
||||||
writer.print(" {s} = ", .{field.name}) catch return 0;
|
|
||||||
} else {
|
|
||||||
writer.print(", {s} = ", .{field.name}) catch return 0;
|
|
||||||
}
|
|
||||||
switch (field.type) {
|
|
||||||
f32, i32, u32, f64, i64, u64 => {
|
|
||||||
writer.print("{d}", .{@field(self.ptr, field.name)}) catch return 0;
|
|
||||||
},
|
|
||||||
[]const u8 => {
|
|
||||||
writer.print("\"{s}\"", .{@field(self.ptr, field.name)}) catch return 0;
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
writer.print("<unknown type {s}>", .{@typeName(field.type)}) catch return 0;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.print(" }}" ++ "\x00", .{}) catch return 0;
|
|
||||||
state.pop(1);
|
|
||||||
state.pushString(Buffer.items) catch return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn luaIndex(state: lua.LuaState) i32 {
|
|
||||||
if (state.toUserdata(@This(), 1)) |self| {
|
|
||||||
if (state.isString(2)) {
|
|
||||||
_ = self;
|
|
||||||
const argument = state.toString(2);
|
|
||||||
// core.engine_log(@typeName(@This()) ++ " got indexed. 0x{x}", .{self.handle.index});
|
|
||||||
|
|
||||||
// check metatable
|
|
||||||
if (state.getMetafield(1, @ptrCast(argument))) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn makeTypeTable() lua.LibSpec {
|
|
||||||
const methods = blk: {
|
|
||||||
comptime var m: lua.LibSpec = &.{};
|
|
||||||
m = m ++ .{lua.luaL_Reg{ .name = "__index", .func = lua.CWrap(luaIndex) }};
|
|
||||||
m = m ++ .{lua.luaL_Reg{ .name = "__tostring", .func = lua.CWrap(luaToString) }};
|
|
||||||
|
|
||||||
inline for (T.ScriptExports) |name| {
|
|
||||||
m = m ++ .{lua.luaL_Reg{ .name = @as([*c]const u8, @ptrCast(name)), .func = ComponentFuncWrapper(@field(T, name), T) }};
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk m ++ .{lua.luaL_Reg{ .name = null, .func = null }};
|
|
||||||
};
|
|
||||||
|
|
||||||
return methods;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn registerType(state: *lua.LuaState) !void {
|
|
||||||
core.engine_log("creating lua metatable {s}", .{MetatableName});
|
|
||||||
|
|
||||||
const methods = comptime makeTypeTable();
|
|
||||||
|
|
||||||
try state.newMetatable(@ptrCast(MetatableName));
|
|
||||||
try state.setFuncs(methods, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ComponentFuncWrapper(comptime baseFunc: anytype, comptime baseType: type) lua.LuaCFunc {
|
|
||||||
return lua.CWrap(FuncWrapper(baseFunc, baseType).wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn FuncWrapper(comptime baseFunc: anytype, comptime baseType: type) type {
|
|
||||||
return struct {
|
|
||||||
pub fn wrapper(state: lua.LuaState) i32 {
|
|
||||||
const Args = std.meta.ArgsTuple(@TypeOf(baseFunc));
|
|
||||||
|
|
||||||
var args: Args = undefined;
|
|
||||||
inline for (std.meta.fields(Args), 0..) |field, index| {
|
|
||||||
// std.debug.print("typename = {s}\n", .{@typeName(field.type)});
|
|
||||||
switch (field.type) {
|
|
||||||
f32 => {
|
|
||||||
args[index] = @as(f32, @floatCast(state.toNumber(index + 1)));
|
|
||||||
},
|
|
||||||
f64 => {
|
|
||||||
args[index] = state.toNumber(index + 1);
|
|
||||||
},
|
|
||||||
i32 => {
|
|
||||||
args[index] = @intFromFloat(state.toNumber(index + 1));
|
|
||||||
},
|
|
||||||
[]const u8 => {
|
|
||||||
args[index] = state.toString(index + 1);
|
|
||||||
},
|
|
||||||
// I'll be honest how the hell does this work?
|
|
||||||
//
|
|
||||||
// the pointer being passed in here isn't the actual resulting type...
|
|
||||||
// it's the reference type
|
|
||||||
*baseType => {
|
|
||||||
const ref = state.toUserdata(ComponentReferenceType(baseType), index + 1).?;
|
|
||||||
ref.resolve();
|
|
||||||
args[index] = ref.ptr;
|
|
||||||
},
|
|
||||||
baseType => {
|
|
||||||
const ref = state.toUserdata(ComponentReferenceType(baseType), index + 1).?;
|
|
||||||
ref.resolve();
|
|
||||||
args[index] = ref.ptr.*;
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
// if(isComponentType(field.type)) {
|
|
||||||
// const ref = state.toUserdata(field.type, index + 1).?;
|
|
||||||
// ref.resolve();
|
|
||||||
// args[index] = ref.ptr.*;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
lua.debugPrints(true);
|
|
||||||
args[index] = (state.toUserdata(field.type, index + 1) orelse {
|
|
||||||
std.debug.print("argument error in index: {d}\n", .{index});
|
|
||||||
state.emitError("something's weird with this argument\n");
|
|
||||||
@panic("lmao");
|
|
||||||
}).*;
|
|
||||||
lua.debugPrints(false);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.pop(@intCast(args.len));
|
|
||||||
|
|
||||||
//const rv = @call(.always_inline, baseFunc, args);
|
|
||||||
const rv = @call(.auto, baseFunc, args);
|
|
||||||
switch (@TypeOf(rv)) {
|
|
||||||
i32, u32, i64, u64 => {
|
|
||||||
state.pushNumber(@floatFromInt(rv));
|
|
||||||
},
|
|
||||||
f32, f64 => {
|
|
||||||
state.pushNumber(@floatCast(rv));
|
|
||||||
},
|
|
||||||
void => {
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
const ud = state.newZigUserdata(@TypeOf(rv)) catch @panic("not implemented");
|
|
||||||
ud.* = rv;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var Buffer: std.ArrayList(u8) = undefined;
|
|
||||||
|
|
||||||
pub fn setupFormatBuffer(allocator: std.mem.Allocator) !void {
|
|
||||||
Buffer = std.ArrayList(u8).init(allocator);
|
|
||||||
}
|
|
||||||
pub fn shutdownFormatBuffer() void {
|
|
||||||
Buffer.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std = @import("std");
|
|
||||||
const core = @import("../core.zig");
|
|
||||||
const ecs = @import("../ecs.zig");
|
|
||||||
const lua = @import("lua");
|
|
||||||
const pod = lua.pod;
|
|
||||||
const scene = @import("../scene.zig");
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
ref: ecs.EcsContainerRef = undefined,
|
|
||||||
name: []const u8 = undefined,
|
|
||||||
luaNew: *const fn (state: lua.LuaState, core.ObjectHandle, ?*anyopaque) void = undefined,
|
|
||||||
|
|
||||||
pub const PodDataTable: pod.DataTable = .{
|
|
||||||
.name = "ComponentRegistration",
|
|
||||||
.banInstantiation = true,
|
|
||||||
.toStringOverride = lua.CWrap(toString),
|
|
||||||
};
|
|
||||||
|
|
||||||
// I should really move all the registration to this file.
|
|
||||||
pub fn toString(state: lua.LuaState) i32 {
|
|
||||||
var workBuffer: [256]u8 = undefined;
|
|
||||||
const ud = state.toUserdata(@This(), 1).?;
|
|
||||||
state.pop(1);
|
|
||||||
const str = std.fmt.bufPrintZ(&workBuffer, "Component Data Table: {s} 0x{x}", .{ ud.name, ud.ref.ptr }) catch return 0;
|
|
||||||
state.pushString(str) catch return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn createComponent(self: @This(), handle: core.ObjectHandle) ?*anyopaque {
|
|
||||||
const ref = self.ref;
|
|
||||||
const rv = ref.vtable.createWithHandle(ref.ptr, handle);
|
|
||||||
// std.debug.print("createComponent: {p}\n", .{rv});
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lua = @import("lua");
|
|
||||||
const ecs = @import("../ecs.zig");
|
|
||||||
const std = @import("std");
|
|
||||||
const core = @import("../core.zig");
|
|
||||||
const pod = lua.pod;
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
const luaRegLibs: []const lua.c.luaL_Reg = &.{
|
|
||||||
.{ .name = "registerTick", .func = lua.CWrap(registerTick) },
|
|
||||||
.{ .name = null, .func = null },
|
|
||||||
};
|
|
||||||
|
|
||||||
// register core types and subsystems into the scripting engine
|
|
||||||
pub fn registerTypes() !void {
|
|
||||||
// transform POD type
|
|
||||||
|
|
||||||
const state = script.getState();
|
|
||||||
try lua.pod.registerPodType(state, core.Vector);
|
|
||||||
try lua.pod.registerPodType(state, core.Vectorf);
|
|
||||||
try lua.pod.registerPodType(state, core.Vector2);
|
|
||||||
try lua.pod.registerPodType(state, core.Vector2f);
|
|
||||||
// try lua.pod.registerPodType(state, core.Transform);
|
|
||||||
|
|
||||||
// lua.pod.registerPodType(state, core.Vector4, "Vector4");
|
|
||||||
try state.createLibrary("Systems", luaRegLibs);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn registerTick(l: lua.LuaState) i32 {
|
|
||||||
// two arguments first one is going to be userdata entity
|
|
||||||
// second one is going to be a lua function.
|
|
||||||
_ = l;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const ScriptTicks = struct {
|
|
||||||
allocator: std.mem.Allocator,
|
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.ScriptTicks");
|
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
|
||||||
const self = try allocator.create(@This());
|
|
||||||
self.* = .{
|
|
||||||
.allocator = allocator,
|
|
||||||
};
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tick(self: *@This(), deltaTime: f64) void {
|
|
||||||
_ = self;
|
|
||||||
const state = script.getState();
|
|
||||||
_ = state.getGlobal("__TickScripts");
|
|
||||||
state.pushNumber(deltaTime);
|
|
||||||
state.pcallStack(1) catch {
|
|
||||||
core.engine_logs("could not execute lua script");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
|
||||||
self.allocator.destroy(self);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const lua = @import("lua");
|
|
||||||
const std = @import("std");
|
|
||||||
const script = @import("script.zig");
|
|
||||||
const core = @import("core.zig");
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn dupeZ(comptime T: type, allocator: std.mem.Allocator, source: []const T) ![]T {
|
|
||||||
var buff: []T = try allocator.alloc(T, source.len + 1);
|
|
||||||
for (source, 0..source.len) |s, i| {
|
|
||||||
buff[i] = s;
|
|
||||||
}
|
|
||||||
buff[source.len] = 0;
|
|
||||||
return buff;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dupe(comptime T: type, allocator: std.mem.Allocator, source: []const T) ![]T {
|
|
||||||
var buff: []T = try allocator.alloc(T, source.len);
|
|
||||||
for (source, 0..) |s, i| {
|
|
||||||
buff[i] = s;
|
|
||||||
}
|
|
||||||
return buff;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn implement_func_for_tagged_union_nonull(
|
|
||||||
self: anytype,
|
|
||||||
comptime funcName: []const u8,
|
|
||||||
comptime returnType: type,
|
|
||||||
args: anytype,
|
|
||||||
) returnType {
|
|
||||||
const Self = @TypeOf(self);
|
|
||||||
inline for (@typeInfo(std.meta.Tag(Self)).Enum.fields) |field| {
|
|
||||||
if (@as(std.meta.Tag(Self), @enumFromInt(field.value)) == self) {
|
|
||||||
if (@hasDecl(@TypeOf(@field(self, field.name)), funcName)) {
|
|
||||||
return @field(@field(self, field.name), funcName)(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
@ -46,7 +46,7 @@ pub fn main() !void {
|
||||||
core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)});
|
core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)});
|
||||||
}
|
}
|
||||||
|
|
||||||
panickers.attachSegfaultHandler();
|
// panickers.attachSegfaultHandler();
|
||||||
try realMain.main();
|
try realMain.main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
// taken from lua 5.1's source code
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Dbghelp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
bool gTakeFullDump = false;
|
||||||
|
|
||||||
|
void make_minidump(EXCEPTION_POINTERS* e)
|
||||||
|
{
|
||||||
|
auto hDbgHelp = LoadLibraryA("dbghelp");
|
||||||
|
if(hDbgHelp == nullptr)
|
||||||
|
return;
|
||||||
|
auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
|
||||||
|
if(pMiniDumpWriteDump == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
char name[MAX_PATH];
|
||||||
|
{
|
||||||
|
auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
|
||||||
|
SYSTEMTIME t;
|
||||||
|
GetSystemTime(&t);
|
||||||
|
wsprintfA(nameEnd - strlen(".exe"),
|
||||||
|
"_%4d%02d%02d_%02d%02d%02d.dmp",
|
||||||
|
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
|
||||||
|
printf("creating minidump... %s \n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
if(hFile == INVALID_HANDLE_VALUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
|
||||||
|
exceptionInfo.ThreadId = GetCurrentThreadId();
|
||||||
|
exceptionInfo.ExceptionPointers = e;
|
||||||
|
exceptionInfo.ClientPointers = FALSE;
|
||||||
|
|
||||||
|
auto dumped = pMiniDumpWriteDump(
|
||||||
|
GetCurrentProcess(),
|
||||||
|
GetCurrentProcessId(),
|
||||||
|
hFile,
|
||||||
|
gTakeFullDump ? MINIDUMP_TYPE(MiniDumpWithFullMemory | MiniDumpIgnoreInaccessibleMemory| MiniDumpScanMemory | MiniDumpWithIndirectlyReferencedMemory) : MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
|
||||||
|
e ? &exceptionInfo : nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e)
|
||||||
|
{
|
||||||
|
make_minidump(e);
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void takeDump()
|
||||||
|
{
|
||||||
|
make_minidump(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupMiniDump(bool takeFullDump)
|
||||||
|
{
|
||||||
|
gTakeFullDump = takeFullDump;
|
||||||
|
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)make_minidump);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateAnException()
|
||||||
|
{
|
||||||
|
const char* str = "Hello";
|
||||||
|
char* mutable_str = const_cast<char*>(str);
|
||||||
|
mutable_str[0] = 'h'; // This will cause an access violation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
extern "C" {
|
||||||
|
void setupMiniDump(bool takeFullDump){}
|
||||||
|
void takeDump(){}
|
||||||
|
void generateAnException() {}
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,15 @@ const test_vert = @import("test.vert");
|
||||||
|
|
||||||
pub const nfd = @import("nfd");
|
pub const nfd = @import("nfd");
|
||||||
pub const file_dialogue = @import("file_dialogue.zig");
|
pub const file_dialogue = @import("file_dialogue.zig");
|
||||||
|
const watcher = @import("watcher");
|
||||||
|
|
||||||
// controls glfw and general windowing
|
// controls glfw and general windowing
|
||||||
// graphics depends on this one
|
// graphics depends on this one
|
||||||
|
|
||||||
|
pub extern fn setupMiniDump(takeFullDump: bool) callconv(.c) void;
|
||||||
|
pub extern fn generateAnException() callconv(.c) void;
|
||||||
|
pub extern fn takeDump() callconv(.c) void;
|
||||||
|
|
||||||
pub const windowing = @import("windowing.zig");
|
pub const windowing = @import("windowing.zig");
|
||||||
|
|
||||||
pub const Module: core.ModuleDescription = .{
|
pub const Module: core.ModuleDescription = .{
|
||||||
|
|
@ -49,6 +54,33 @@ pub fn getMouseVisible() bool {
|
||||||
gPlatformInstance.isCursorEnabled();
|
gPlatformInstance.isCursorEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn watchPath(path: []const u8) void {
|
||||||
|
watchPathPacker(core.fs(), path) catch {
|
||||||
|
core.engine_log("unable to set up watch on path", .{path});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watchPathPacker(self: *core.PackerFS, path: []const u8) !void {
|
||||||
|
// std.debug.print("self = {x}\n", .{@intFromPtr(self)});
|
||||||
|
|
||||||
|
std.fs.cwd().access(path, .{}) catch return;
|
||||||
|
// check the path exists before attempting to watch
|
||||||
|
|
||||||
|
const p = self.stringArena.allocator().dupeZ(u8, path) catch return;
|
||||||
|
const watch = watcher.createWatchPoint(
|
||||||
|
p,
|
||||||
|
core.PackerFS.watchCallback,
|
||||||
|
self,
|
||||||
|
) orelse {
|
||||||
|
return error.UnableToWatch;
|
||||||
|
};
|
||||||
|
_ = watch;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn watchModules() void {
|
||||||
|
watchPath("zig-out/modules/");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||||
_ = args;
|
_ = args;
|
||||||
_ = spec;
|
_ = spec;
|
||||||
|
|
@ -57,6 +89,8 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core.getModuleLoader().watchInitializedFn = watchModules;
|
||||||
|
|
||||||
const parameters = windowing.PlatformParams.init();
|
const parameters = windowing.PlatformParams.init();
|
||||||
|
|
||||||
gPlatformInstance = try core.createObject(windowing.PlatformInstance, .{}); //try allocator.create(windowing.PlatformInstance);
|
gPlatformInstance = try core.createObject(windowing.PlatformInstance, .{}); //try allocator.create(windowing.PlatformInstance);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ const dependencyList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
"assets",
|
"assets",
|
||||||
"sdl3",
|
"sdl3",
|
||||||
|
"spng",
|
||||||
"platform",
|
"platform",
|
||||||
"sys",
|
"sys",
|
||||||
"shaderTypes",
|
"shaderTypes",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
.shaderTypes = .{ .path = "../../lib/sdl3/shaderTypes" },
|
.shaderTypes = .{ .path = "../../lib/sdl3/shaderTypes" },
|
||||||
.zgltf = .{ .path = "../../lib/zgltf" },
|
.zgltf = .{ .path = "../../lib/zgltf" },
|
||||||
.objLoader = .{ .path = "../../lib/objLoader" },
|
.objLoader = .{ .path = "../../lib/objLoader" },
|
||||||
|
|
||||||
|
.spng = .{ .path = "../../lib/spng" },
|
||||||
},
|
},
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const spng = @import("spng");
|
const spng = @import("spng");
|
||||||
|
|
||||||
const core = @import("core.zig");
|
const core = @import("core");
|
||||||
|
|
||||||
pub const PngContents = struct {
|
pub const PngContents = struct {
|
||||||
path: []const u8,
|
path: []const u8,
|
||||||
|
|
@ -20,6 +20,9 @@ pub const renderer = @import("sgpu/renderer.zig");
|
||||||
pub const context = renderer.context; // context getter func
|
pub const context = renderer.context; // context getter func
|
||||||
pub const Renderer = renderer.Renderer;
|
pub const Renderer = renderer.Renderer;
|
||||||
|
|
||||||
|
pub const spng = @import("spng");
|
||||||
|
pub const png = @import("png.zig");
|
||||||
|
|
||||||
pub const MeshPool = renderer.MeshPool;
|
pub const MeshPool = renderer.MeshPool;
|
||||||
|
|
||||||
pub const getMesh = renderer.getMesh;
|
pub const getMesh = renderer.getMesh;
|
||||||
|
|
|
||||||
|
|
@ -323,8 +323,6 @@ pub const DebugPrimitive = struct {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
unreachable;
|
unreachable;
|
||||||
|
|
||||||
// return core.implement_func_for_tagged_union_nonull(self.primitive, "resolve", core.Transform, .{});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ pub fn uploadCubeFromPaths(self: *@This(), name: core.Name, paths: []const []con
|
||||||
return error.CubeNeedsSixFaces;
|
return error.CubeNeedsSixFaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cubeList = std.ArrayList(core.png.PngContents){}; //std.ArrayList(core.png.PngContents).init(self.allocator);
|
var cubeList = std.ArrayList(rend.png.PngContents){};
|
||||||
defer cubeList.deinit(self.allocator);
|
defer cubeList.deinit(self.allocator);
|
||||||
|
|
||||||
var gpuTexture: *gpu.GPUTexture = undefined;
|
var gpuTexture: *gpu.GPUTexture = undefined;
|
||||||
|
|
@ -262,7 +262,7 @@ pub fn uploadTextureFromBytes(self: *@This(), name: *core.Name, opts: UploadText
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uploadTextureFromPath(self: *@This(), name: core.Name, path: []const u8) !*Texture {
|
pub fn uploadTextureFromPath(self: *@This(), name: core.Name, path: []const u8) !*Texture {
|
||||||
var png = try core.png.PngContents.initFromFS(core.fs(), self.allocator, path);
|
var png = try rend.png.PngContents.initFromFS(core.fs(), self.allocator, path);
|
||||||
defer png.deinit();
|
defer png.deinit();
|
||||||
|
|
||||||
const cmd = self.device.acquireGPUCommandBuffer();
|
const cmd = self.device.acquireGPUCommandBuffer();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
_ = static_build;
|
||||||
|
|
||||||
|
const mod = b.addModule("watcher", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.root_source_file = b.path("src/watcher.zig"),
|
||||||
|
.link_libc = true,
|
||||||
|
.link_libcpp = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
mod.addCSourceFile(.{ .file = b.path("src/watcher.cpp") });
|
||||||
|
|
||||||
|
if (target.result.os.tag == .macos) {
|
||||||
|
mod.linkFramework("CoreFoundation", .{});
|
||||||
|
mod.linkFramework("CoreServices", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.addIncludePath(b.path("src/include"));
|
||||||
|
|
||||||
|
const test_exe = b.addTest(.{
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.root_source_file = b.path("tests/test.zig"),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
test_exe.root_module.addImport("watcher", mod);
|
||||||
|
|
||||||
|
const test_step = b.step("test", "runs sample unit tests for watcher");
|
||||||
|
test_step.dependOn(&b.addRunArtifact(test_exe).step);
|
||||||
|
|
||||||
|
b.installArtifact(test_exe);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
.{
|
||||||
|
.name = .filewatch,
|
||||||
|
.version = "0.0.0",
|
||||||
|
.dependencies = .{},
|
||||||
|
.paths = .{
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
.fingerprint = 0x84d25253a649dc52,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
extern "C" void* createWatchPoint(
|
||||||
|
const char* watchPath,
|
||||||
|
void(*cb)(const char*, void*),
|
||||||
|
void* ctx
|
||||||
|
){
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
const watcher = @import("watcher");
|
||||||
|
|
||||||
|
test "compile test" {}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// taken from lua 5.1's source code
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <Dbghelp.h>
|
#include <Dbghelp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ pub const TimingScope = struct {
|
||||||
|
|
||||||
pub inline fn init(c: *ScopesContext) @This() {
|
pub inline fn init(c: *ScopesContext) @This() {
|
||||||
return .{
|
return .{
|
||||||
.startTsc = rdtsc(),
|
.startTsc = timestampTicks(),
|
||||||
.context = c,
|
.context = c,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ pub const TimingScope = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn end(self: *@This()) void {
|
pub inline fn end(self: *@This()) void {
|
||||||
self.endTsc = rdtsc();
|
self.endTsc = timestampTicks();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,8 @@ pub fn build(b: *std.Build) void {
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/packer.zig"),
|
.root_source_file = b.path("src/packer.zig"),
|
||||||
.link_libc = true,
|
|
||||||
.link_libcpp = true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.addIncludePath(b.path("src/include"));
|
|
||||||
mod.addCSourceFile(.{ .file = b.path("src/watcher.cpp"), .flags = &.{} });
|
|
||||||
|
|
||||||
const p2mod = p2dep.module("p2");
|
const p2mod = p2dep.module("p2");
|
||||||
mod.addImport("p2", p2mod);
|
mod.addImport("p2", p2mod);
|
||||||
|
|
||||||
|
|
@ -27,7 +22,6 @@ pub fn build(b: *std.Build) void {
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("tests/test.zig"),
|
.root_source_file = b.path("tests/test.zig"),
|
||||||
// .link_libc = true,
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
test_exe.root_module.addImport("packer", mod);
|
test_exe.root_module.addImport("packer", mod);
|
||||||
|
|
|
||||||
|
|
@ -178,24 +178,6 @@ pub const PackerFS = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn watchPath(self: *@This(), path: []const u8) void {
|
|
||||||
// std.debug.print("self = {x}\n", .{@intFromPtr(self)});
|
|
||||||
|
|
||||||
// check the path exists before attempting to watch
|
|
||||||
std.fs.cwd().access(path, .{}) catch return;
|
|
||||||
|
|
||||||
const p = self.stringArena.allocator().dupeZ(u8, path) catch return;
|
|
||||||
const watch = watcher.createWatchPoint(
|
|
||||||
p,
|
|
||||||
watchCallback,
|
|
||||||
self,
|
|
||||||
) orelse {
|
|
||||||
std.debug.print("Unable to create watch point, {s}\n", .{p});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
_ = watch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: implement load memory to file then-map setup.
|
// todo: implement load memory to file then-map setup.
|
||||||
// for systems which do not support mmap
|
// for systems which do not support mmap
|
||||||
|
|
||||||
|
|
@ -525,5 +507,3 @@ pub const PackerFS = struct {
|
||||||
return .{ .allocator = allocator, .data = rv, .sources = sourcePath };
|
return .{ .allocator = allocator, .data = rv, .sources = sourcePath };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const watcher = @import("watcher.zig");
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue