moved filewatch out of packer, and moving spng to rend, and deleted a lot of dead code

This commit is contained in:
Peter Li 2025-11-01 15:13:42 -07:00
parent 08bad270e6
commit 180badad39
38 changed files with 212 additions and 783 deletions

View File

@ -2,14 +2,9 @@ const std = @import("std");
const dependencyList = [_][]const u8{
"p2",
"tracy",
"tracy", // usually doesnt have C deps... unless we're compiled with it on, in which case we only support static builds
"zmath",
"packer", // packer might need to be split into another setup that doesn't have 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",
"packer", // packer no longer has C deps.
};
pub fn build(b: *std.Build) void {

View File

@ -2,7 +2,7 @@
.name = .core,
.version = "0.0.0",
.dependencies = .{
.spng = .{ .path = "../../lib/spng" },
// .spng = .{ .path = "../../lib/spng" },
// .nfd = .{ .path = "../../lib/nfd" },
// with -Dtracy = false, this one pulls in no C dependencies
@ -12,7 +12,7 @@
.zmath = .{ .path = "../../lib/zmath" },
.packer = .{ .path = "../../lib/packer" },
.p2 = .{ .path = "../../lib/p2" },
.lua = .{ .path = "../../lib/lua" },
// .lua = .{ .path = "../../lib/lua" },
// .zgltf = .{ .path = "../../lib/zgltf" },
},
.paths = .{

View File

@ -25,7 +25,6 @@ pub const debugBox = debug_draw.debugBox;
pub const debugLine = debug_draw.debugLine;
// pub const script_bindings = script.script_bindings;
pub const misc = @import("misc.zig");
pub const engineTime = @import("engineTime.zig");
pub const engineObject = @import("engineObject.zig");
pub const EngineObjectVTable = engineObject.EngineObjectVTable;
@ -43,12 +42,8 @@ pub const ThreadContext = jobs.ThreadContext;
pub const JobManager = jobs.JobManager;
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 tracy = @import("tracy").t;
pub const png = @import("png.zig");
pub const colors = @import("colors.zig");
@ -141,8 +136,6 @@ pub const SceneSystem = scene.SceneSystem;
pub const Engine = engine.Engine;
pub const spng = @import("spng");
pub const MemoryTracker = @import("MemoryTracker.zig");
pub const DefaultSavePath = "Saved";
@ -173,14 +166,16 @@ pub const defaultHighlight = logging.defaultHighlight;
pub const packer = @import("packer");
pub const FileSystem = packer.PackerFS;
pub const PackerFS = packer.PackerFS;
pub const StackCompactor = stacks.StackCompactor;
var staticsInitialized = false;
var gEngine: *Engine = undefined;
pub const PackerFS = packer.PackerFS;
var gPackerFS: *PackerFS = undefined;
pub fn fs() *PackerFS {
return gPackerFS;
}
var fsInitialized: bool = false;
pub fn EngineObject(comptime T: type) type {
@ -217,8 +212,6 @@ pub const undefineComponentList = ecs.undefineComponentList;
pub const Entity = ecs.Entity;
pub const createEntity = ecs.createEntity;
pub const script = @import("script.zig");
pub const stacks = @import("stacks.zig");
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);
}
pub fn fs() *PackerFS {
return gPackerFS;
}
pub const Module = ModuleDescription{
.name = "core",
.enabledByDefault = true,
@ -295,15 +284,9 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
fatDump = true;
}
script.lua.setupMiniDump(fatDump);
_ = 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);
// load configs.
//const name = if (@hasField(@TypeOf(programSpec), "configName")) programSpec.configName else programSpec.name;
var name = map.get("name").?.string;
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 gEngine.createObject(script_bindings.ScriptTicks, .{ .can_tick = true });
_ = try createObject(GameObjectSystem, .{ .can_tick = true });
_ = 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 {
gEngine = __args.engine;
gPackerFS = __args.packerFS;
// script.setupLuaFromModule(__args.luaState, __args.luaAllocator);
algorithm.names.gRegistry = __args.nameRegistry;
logging.setupLoggingFromModule();
staticsInitialized = true;
@ -368,9 +348,6 @@ pub fn shutdown_module(_: std.mem.Allocator) void {
ecs.shutdown();
algorithm.destroyNameRegistry();
gPackerFS.destroy();
// LUA BEGIN
// script.shutdown_lua();
// LUA END
console.shutdown();
algorithm.string_pool.shutdown();
@ -386,22 +363,20 @@ pub fn parallelJob(capture: anytype, async: bool, maxWorkerCount: ?u32) !void {
const requestedWorkers = if (maxWorkerCount) |m| m else jobManager.numWorkers;
const baseWorkerCount = @min(requestedWorkers, @max(getEngine().jobManager.numWorkers - 2, 1));
const workerStart:u32 = if (async) 0 else 1;
const workerStart: u32 = if (async) 0 else 1;
for (workerStart .. baseWorkerCount) |workerId| {
try jobManager.newJob(capture, .{ .threadId = @intCast(workerId), .threadCount = baseWorkerCount});
for (workerStart..baseWorkerCount) |workerId| {
try jobManager.newJob(capture, .{ .threadId = @intCast(workerId), .threadCount = baseWorkerCount });
}
// start working on the job locally
if (!async) {
try jobManager.runLocally(capture, .{.threadId = 0, .threadCount = baseWorkerCount});
try jobManager.runLocally(capture, .{ .threadId = 0, .threadCount = baseWorkerCount });
}
}
pub fn dispatchJob(capture: anytype) !void {
try gEngine.jobManager.newJob(capture, .{.threadId = 0, .threadCount = 1});//0, 1, null);
try gEngine.jobManager.newJob(capture, .{ .threadId = 0, .threadCount = 1 }); //0, 1, null);
}
pub fn createObject(comptime T: type, params: engine.NeonObjectParams) !*T {

View File

@ -125,6 +125,7 @@ pub const ModuleLoader = struct {
arena: std.heap.ArenaAllocator,
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
watchInitialized: bool = false,
watchInitializeFn: ?*const fn () void = null,
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
pub fn create(allocator: std.mem.Allocator) !*@This() {
@ -150,8 +151,11 @@ pub const ModuleLoader = struct {
const loaded = try self.arena.allocator().create(LoadedModule);
if (self.watchInitialized == false) {
core.fs().watchPath("zig-out/modules/");
self.watchInitialized = true;
// core.fs().watchPath("zig-out/modules/");
if (self.watchInitializeFn) |watchInitializeFn| {
watchInitializeFn();
self.watchInitialized = true;
}
}
loaded.* = LoadedModule{

View File

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

View File

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

View File

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

View File

@ -1,2 +0,0 @@
print("Hello from lua.")

View File

@ -1,14 +1,7 @@
const std = @import("std");
const misc = @import("misc.zig");
const zm = @import("zmath");
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.
pub const f32x4 = @Vector(4, f32); // __m128_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,
y: T = 0,
// 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 const VectorTypeName = typeName;
pub const Ones = @This(){ .x = 1, .y = 1 };
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,
z: T = 0,
pub const VectorTypeName = typeName;
pub const Ones = @This(){ .x = 1, .y = 1, .z = 1 };
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 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() {
return .{
.x = x,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@ pub fn main() !void {
core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)});
}
panickers.attachSegfaultHandler();
// panickers.attachSegfaultHandler();
try realMain.main();
}

View File

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

View File

@ -0,0 +1,5 @@
extern "C" {
void setupMiniDump(bool takeFullDump){}
void takeDump(){}
void generateAnException() {}
}

View File

@ -4,10 +4,15 @@ const test_vert = @import("test.vert");
pub const nfd = @import("nfd");
pub const file_dialogue = @import("file_dialogue.zig");
const watcher = @import("watcher");
// controls glfw and general windowing
// 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 Module: core.ModuleDescription = .{
@ -49,6 +54,33 @@ pub fn getMouseVisible() bool {
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 {
_ = args;
_ = spec;
@ -57,6 +89,8 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
return;
}
core.getModuleLoader().watchInitializedFn = watchModules;
const parameters = windowing.PlatformParams.init();
gPlatformInstance = try core.createObject(windowing.PlatformInstance, .{}); //try allocator.create(windowing.PlatformInstance);

View File

@ -5,6 +5,7 @@ const dependencyList = [_][]const u8{
"core",
"assets",
"sdl3",
"spng",
"platform",
"sys",
"shaderTypes",

View File

@ -12,6 +12,8 @@
.shaderTypes = .{ .path = "../../lib/sdl3/shaderTypes" },
.zgltf = .{ .path = "../../lib/zgltf" },
.objLoader = .{ .path = "../../lib/objLoader" },
.spng = .{ .path = "../../lib/spng" },
},
.paths = .{
"",

View File

@ -2,7 +2,7 @@
const std = @import("std");
const spng = @import("spng");
const core = @import("core.zig");
const core = @import("core");
pub const PngContents = struct {
path: []const u8,

View File

@ -20,6 +20,9 @@ pub const renderer = @import("sgpu/renderer.zig");
pub const context = renderer.context; // context getter func
pub const Renderer = renderer.Renderer;
pub const spng = @import("spng");
pub const png = @import("png.zig");
pub const MeshPool = renderer.MeshPool;
pub const getMesh = renderer.getMesh;

View File

@ -323,8 +323,6 @@ pub const DebugPrimitive = struct {
},
}
unreachable;
// return core.implement_func_for_tagged_union_nonull(self.primitive, "resolve", core.Transform, .{});
}
};

View File

@ -65,7 +65,7 @@ pub fn uploadCubeFromPaths(self: *@This(), name: core.Name, paths: []const []con
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);
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 {
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();
const cmd = self.device.acquireGPUCommandBuffer();

40
lib/filewatch/build.zig vendored Normal file
View File

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

9
lib/filewatch/build.zig.zon vendored Normal file
View File

@ -0,0 +1,9 @@
.{
.name = .filewatch,
.version = "0.0.0",
.dependencies = .{},
.paths = .{
"",
},
.fingerprint = 0x84d25253a649dc52,
}

7
lib/filewatch/src/watcherstub.cpp vendored Normal file
View File

@ -0,0 +1,7 @@
extern "C" void* createWatchPoint(
const char* watchPath,
void(*cb)(const char*, void*),
void* ctx
){
return nullptr;
}

3
lib/filewatch/tests/test.zig vendored Normal file
View File

@ -0,0 +1,3 @@
const watcher = @import("watcher");
test "compile test" {}

View File

@ -1,3 +1,4 @@
// taken from lua 5.1's source code
#include <Windows.h>
#include <Dbghelp.h>
#include <stdio.h>

View File

@ -59,7 +59,7 @@ pub const TimingScope = struct {
pub inline fn init(c: *ScopesContext) @This() {
return .{
.startTsc = rdtsc(),
.startTsc = timestampTicks(),
.context = c,
};
}
@ -76,7 +76,7 @@ pub const TimingScope = struct {
}
pub inline fn end(self: *@This()) void {
self.endTsc = rdtsc();
self.endTsc = timestampTicks();
}
};

View File

@ -12,13 +12,8 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
.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");
mod.addImport("p2", p2mod);
@ -27,7 +22,6 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
.root_source_file = b.path("tests/test.zig"),
// .link_libc = true,
}),
});
test_exe.root_module.addImport("packer", mod);

View File

@ -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.
// for systems which do not support mmap
@ -525,5 +507,3 @@ pub const PackerFS = struct {
return .{ .allocator = allocator, .data = rv, .sources = sourcePath };
}
};
const watcher = @import("watcher.zig");