adding file reloading
This commit is contained in:
parent
63fe7961b1
commit
1ee804355c
|
|
@ -248,5 +248,7 @@ pub const console = @import("console.zig");
|
||||||
|
|
||||||
pub const configVars = @import("configVars.zig");
|
pub const configVars = @import("configVars.zig");
|
||||||
|
|
||||||
|
pub const loopDelay = engine.loopDelay;
|
||||||
|
|
||||||
pub const getConfigVar = configVars.getConfigVar;
|
pub const getConfigVar = configVars.getConfigVar;
|
||||||
pub const configVar = configVars.configVar;
|
pub const configVar = configVars.configVar;
|
||||||
|
|
|
||||||
|
|
@ -388,4 +388,20 @@ pub const NeonObjectParams = struct {
|
||||||
isCore: bool = false,
|
isCore: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Src = std.builtin.SourceLocation;
|
||||||
|
pub fn loopDelay(comptime src: Src, interval: f64, dt: f64, comptime S: type, capture: S) void {
|
||||||
|
const C = struct {
|
||||||
|
pub const s = src;
|
||||||
|
pub var __timeleft: f64 = 0.0;
|
||||||
|
pub var __interval: f64 = 0.0;
|
||||||
|
};
|
||||||
|
C.__interval -= dt;
|
||||||
|
|
||||||
|
if (C.__timeleft <= 0.0) {
|
||||||
|
S.func(capture);
|
||||||
|
while (C.__timeleft < 0)
|
||||||
|
C.__timeleft += interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "comptime registration implementation" {}
|
test "comptime registration implementation" {}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// modules for managing loading dynamic libraries
|
||||||
|
//
|
||||||
|
// i want hot swapping
|
||||||
|
//
|
||||||
|
// 1. add a folder to the watch list
|
||||||
|
|
||||||
|
pub const FileWatchEntry = struct {
|
||||||
|
path: []const u8,
|
||||||
|
stamp: i128 = 0,
|
||||||
|
cbCtx: ?*anyopaque,
|
||||||
|
|
||||||
|
loadCallback: *const fn (*@This(), ?*anyopaque) void,
|
||||||
|
|
||||||
|
// staging path is under .cache/modules/<module hash>/
|
||||||
|
pub fn copyToStaging(self: *@This()) !void {
|
||||||
|
const fileName = p2.
|
||||||
|
const dir = try std.fs.cwd().makePath();
|
||||||
|
std.fs.cwd().copyFile(self.path, dir, "", options: CopyFileOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn checkUpdateTime(self: *@This()) bool {
|
||||||
|
const stat = std.fs.cwd().statFile(self.path) catch false;
|
||||||
|
if (stat.mtime != self.stamp) {
|
||||||
|
self.stamp = stat.mtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ModuleLoader = struct {
|
||||||
|
backingAllocator: std.mem.Allocator,
|
||||||
|
arena: std.heap.ArenaAllocator,
|
||||||
|
allocator: std.mem.Allocator = undefined,
|
||||||
|
|
||||||
|
files: std.ArrayListUnmanaged(FileWatchEntry) = .{},
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.backingAllocator = allocator,
|
||||||
|
.arena = try std.heap.ArenaAllocator.init(allocator),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.allocator = self.arena.allocator();
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.arena.deinit();
|
||||||
|
self.backingAllocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn checkForFileUpdates(self: *@This()) void {
|
||||||
|
for (self.files.items) |*f| {
|
||||||
|
if (f.checkTime()) {
|
||||||
|
f.loadCallback(f.cbCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const p2 = @import("p2");
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// script objects.
|
||||||
|
|
||||||
|
pub const ObjectTable = extern struct {
|
||||||
|
create: *const fn (allocator: *anyopaque) callconv(.C) ?*anyopaque,
|
||||||
|
tick: *const fn (*anyopaque, f64) callconv(.C) void,
|
||||||
|
destroy: *const fn (p: *anyopaque) callconv(.C) ?*anyopaque,
|
||||||
|
};
|
||||||
|
|
||||||
|
// eg. in C
|
||||||
|
//
|
||||||
|
// object Struc
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ test "simple systems setup for core" {
|
||||||
try test_consoleCommands();
|
try test_consoleCommands();
|
||||||
try test_gameObjects(std.testing.allocator);
|
try test_gameObjects(std.testing.allocator);
|
||||||
|
|
||||||
try generateRandomSamples();
|
// try generateRandomSamples();
|
||||||
|
|
||||||
try memory.dumpTimeline("test-core-timeline.txt");
|
try memory.dumpTimeline("test-core-timeline.txt");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
allocator: std.mem.allocator,
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const backlog = @import("Backlog");
|
||||||
|
const core = backlog.core;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
allocator: std.mem.allocator,
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const backlog = @import("Backlog");
|
||||||
|
const core = backlog.core;
|
||||||
|
const rend = backlog.rend;
|
||||||
|
const ig = backlog.imgui.api;
|
||||||
|
|
@ -4627,6 +4627,11 @@ pub inline fn textFmt(comptime fmt: []const u8, args: anytype) !void {
|
||||||
textUnformatted(@ptrCast(buffer.ptr), buffer.ptr + buffer.len);
|
textUnformatted(@ptrCast(buffer.ptr), buffer.ptr + buffer.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn textf(comptime f: []const u8, args: anytype) void {
|
||||||
|
const buffer = std.fmt.bufPrint(&textFmtBuffer, f, args) catch return;
|
||||||
|
textUnformatted(@ptrCast(buffer.ptr), buffer.ptr + buffer.len);
|
||||||
|
}
|
||||||
|
|
||||||
// pub inline fn textV(fmt: [*c]const u8, args: list) void { //igTextV
|
// pub inline fn textV(fmt: [*c]const u8, args: list) void { //igTextV
|
||||||
// c.igTextV(fmt, args);
|
// c.igTextV(fmt, args);
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,16 @@ pub const Span = spans.Span;
|
||||||
|
|
||||||
pub const shell = @import("utils/shell.zig");
|
pub const shell = @import("utils/shell.zig");
|
||||||
|
|
||||||
|
pub fn sharedLibName(comptime s: []const u8) []const u8 {
|
||||||
|
const os_tag = @import("builtin").os.tag;
|
||||||
|
if (os_tag == .linux) {
|
||||||
|
return s ++ ".so";
|
||||||
|
} else if (os_tag == .macos) {
|
||||||
|
return s ++ ".dynlib";
|
||||||
|
} else {
|
||||||
|
return s ++ ".dll";
|
||||||
|
}
|
||||||
|
}
|
||||||
comptime {
|
comptime {
|
||||||
std.testing.refAllDecls(utils);
|
std.testing.refAllDecls(utils);
|
||||||
std.testing.refAllDecls(static_structures);
|
std.testing.refAllDecls(static_structures);
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,13 @@ 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);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -53,6 +53,16 @@ pub const Settings = struct {
|
||||||
contentFolderExtraPaths: []const []const u8 = &[_][]const u8{}, // By default, this will mount the content/ folder on disk.
|
contentFolderExtraPaths: []const []const u8 = &[_][]const u8{}, // By default, this will mount the content/ folder on disk.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const WatchCallback = struct {
|
||||||
|
func: *const fn ([]const u8, ?*anyopaque) void,
|
||||||
|
ctx: ?*anyopaque = null,
|
||||||
|
path: []const u8,
|
||||||
|
|
||||||
|
pub inline fn call(self: *@This(), path: []const u8) void {
|
||||||
|
self.func(path, self.ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const PackerFS = struct {
|
pub const PackerFS = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
fileHeaders: std.ArrayListUnmanaged(PackedFileEntry) = .{},
|
fileHeaders: std.ArrayListUnmanaged(PackedFileEntry) = .{},
|
||||||
|
|
@ -67,6 +77,8 @@ pub const PackerFS = struct {
|
||||||
|
|
||||||
lock: std.Thread.Mutex = .{},
|
lock: std.Thread.Mutex = .{},
|
||||||
|
|
||||||
|
fileWatchCallbacks: std.ArrayListUnmanaged(WatchCallback) = .{},
|
||||||
|
|
||||||
pub const PakMounting = struct {
|
pub const PakMounting = struct {
|
||||||
filePath: []const u8, // path to the file
|
filePath: []const u8, // path to the file
|
||||||
bytes: []align(8) u8 = undefined,
|
bytes: []align(8) u8 = undefined,
|
||||||
|
|
@ -114,6 +126,48 @@ pub const PackerFS = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn addFileChangedCallback(
|
||||||
|
self: *@This(),
|
||||||
|
path: []const u8,
|
||||||
|
cb: *const fn ([]const u8, ?*anyopaque) void,
|
||||||
|
ctx: ?*anyopaque,
|
||||||
|
) !void {
|
||||||
|
const x = WatchCallback{
|
||||||
|
.func = cb,
|
||||||
|
.ctx = ctx,
|
||||||
|
.path = path,
|
||||||
|
};
|
||||||
|
|
||||||
|
try self.fileWatchCallbacks.append(self.allocator, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn watchCallback(path: [*c]const u8, ctx: ?*anyopaque) callconv(.C) void {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
// std.debug.print("WE GOT OURSELFS A FUCKIN CALLBAKC FOR A PATH MOTHERF- {s} {p} {d}\n", .{ path, ctx.?, self.pakMountings.items.len });
|
||||||
|
|
||||||
|
for (self.fileWatchCallbacks.items) |*watch| {
|
||||||
|
// std.debug.print("checking {s} {s}\n", .{ watch.path, path });
|
||||||
|
if (std.mem.eql(u8, watch.path, std.mem.span(path))) {
|
||||||
|
watch.call(std.mem.span(path));
|
||||||
|
}
|
||||||
|
// std.debug.print("registered callback: {s}\n", .{watch.path});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn watchPath(self: *@This(), path: []const u8) void {
|
||||||
|
// std.debug.print("self = {x}\n", .{@intFromPtr(self)});
|
||||||
|
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
|
||||||
|
|
||||||
|
|
@ -164,6 +218,26 @@ pub const PackerFS = struct {
|
||||||
return @intCast(self.fileHeaders.items.len);
|
return @intCast(self.fileHeaders.items.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolveContentFile(self: *@This(), allocator: std.mem.Allocator, path: []const u8) !?[]u8 {
|
||||||
|
for (self.contentPaths.items) |contentPath| {
|
||||||
|
// std.debug.print("{s}\n", .{contentPath});
|
||||||
|
const fullPath = try std.fmt.allocPrint(self.stringArena.allocator(), "{s}/{s}", .{ contentPath, path });
|
||||||
|
defer self.stringArena.allocator().free(fullPath);
|
||||||
|
|
||||||
|
var exists: bool = true;
|
||||||
|
|
||||||
|
std.fs.cwd().access(fullPath, .{}) catch |err| {
|
||||||
|
exists = if (err == error.FileNotFound) false else true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
return try allocator.dupe(u8, fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fileExists(self: *@This(), path: []const u8) bool {
|
pub fn fileExists(self: *@This(), path: []const u8) bool {
|
||||||
self.lock.lock();
|
self.lock.lock();
|
||||||
defer self.lock.unlock();
|
defer self.lock.unlock();
|
||||||
|
|
@ -231,6 +305,7 @@ pub const PackerFS = struct {
|
||||||
return self.stringArena.allocator();
|
return self.stringArena.allocator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if skipLoading is set bytes will contain an empty path
|
||||||
fn loadFileDirect(self: *@This(), basePath: []const u8, path: []const u8) !?PackerBytesMapping {
|
fn loadFileDirect(self: *@This(), basePath: []const u8, path: []const u8) !?PackerBytesMapping {
|
||||||
// if we made it to this function we can assume that the file does not exist in existing pak mounting references.
|
// if we made it to this function we can assume that the file does not exist in existing pak mounting references.
|
||||||
// nor does it exist in self.fileHandlesByName
|
// nor does it exist in self.fileHandlesByName
|
||||||
|
|
@ -347,6 +422,7 @@ pub const PackerFS = struct {
|
||||||
self.contentPaths.deinit(self.allocator);
|
self.contentPaths.deinit(self.allocator);
|
||||||
self.stringArena.deinit();
|
self.stringArena.deinit();
|
||||||
self.lock.unlock();
|
self.lock.unlock();
|
||||||
|
self.fileWatchCallbacks.deinit(self.allocator);
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -414,3 +490,5 @@ pub const PackerFS = struct {
|
||||||
return .{ .allocator = allocator, .data = rv, .sources = sourcePath };
|
return .{ .allocator = allocator, .data = rv, .sources = sourcePath };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const watcher = @import("watcher.zig");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <FileWatch.hpp>
|
||||||
|
|
||||||
|
extern "C" void* createWatchPoint(
|
||||||
|
const char* watchPath,
|
||||||
|
void(*cb)(const char*, void*),
|
||||||
|
void* ctx
|
||||||
|
){
|
||||||
|
auto* watch = new filewatch::FileWatch<std::string>(
|
||||||
|
watchPath,
|
||||||
|
[cb, ctx] (const std::string& path, const filewatch::Event change_type) {
|
||||||
|
std::cout << event_to_string(change_type) << std::endl;
|
||||||
|
cb(path.c_str(), ctx);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return watch;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
pub const CallbackType = *const fn ([*c]const u8, ?*anyopaque) callconv(.C) void;
|
||||||
|
|
||||||
|
pub extern fn createWatchPoint(
|
||||||
|
[*c]const u8,
|
||||||
|
CallbackType,
|
||||||
|
?*anyopaque,
|
||||||
|
) callconv(.C) ?*anyopaque;
|
||||||
|
|
@ -116,3 +116,27 @@ test "packerfs_test" {
|
||||||
|
|
||||||
std.debug.print("littleEndian {any}", .{packer.littleEndian});
|
std.debug.print("littleEndian {any}", .{packer.littleEndian});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fileChangedCb(pathChanged: []const u8, ctx: ?*anyopaque) void {
|
||||||
|
_ = ctx;
|
||||||
|
std.debug.print("pathChanged {s}\n", .{pathChanged});
|
||||||
|
}
|
||||||
|
|
||||||
|
test "packer file watch" {
|
||||||
|
var fs = try PackerFS.init(std.testing.allocator, .{});
|
||||||
|
defer fs.destroy();
|
||||||
|
std.fs.cwd().deleteFile("test_output/test2.txt") catch {};
|
||||||
|
try fs.addContentPath("test_output");
|
||||||
|
|
||||||
|
fs.watchPath("test_output");
|
||||||
|
try fs.addFileChangedCallback("test2.txt", fileChangedCb, null);
|
||||||
|
|
||||||
|
var file = try std.fs.cwd().createFile("test_output/test2.txt", .{});
|
||||||
|
std.time.sleep(100000000);
|
||||||
|
|
||||||
|
std.debug.print("writing to file\n", .{});
|
||||||
|
// var file = try std.fs.cwd().openFile("test_output/test2.txt", .{ .mode = .read_write });
|
||||||
|
try file.writeAll("what the fuck bro");
|
||||||
|
std.time.sleep(400000000);
|
||||||
|
// std.time.sleep(5000000000);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,17 @@ pub fn build(b: *std.Build) void {
|
||||||
blbuild.addExtraModule(sampleGame, "videoplayer");
|
blbuild.addExtraModule(sampleGame, "videoplayer");
|
||||||
blbuild.addExtraModule(sampleGame, "doomplayer");
|
blbuild.addExtraModule(sampleGame, "doomplayer");
|
||||||
blbuild.addExtraModule(sampleGame, "bsp");
|
blbuild.addExtraModule(sampleGame, "bsp");
|
||||||
|
|
||||||
|
const sampleGameExtern = b.addSharedLibrary(.{
|
||||||
|
.root_source_file = b.path("sampleGame/externGame/externGame.zig"),
|
||||||
|
.link_libc = true,
|
||||||
|
.optimize = optimize,
|
||||||
|
.target = target,
|
||||||
|
.name = "externGame",
|
||||||
|
});
|
||||||
|
|
||||||
|
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
||||||
|
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||||
|
});
|
||||||
|
b.getInstallStep().dependOn(&installExtern.step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
pub export fn add(a: i32, b: i32) i32 {
|
||||||
|
return a + b + 32000;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
@ -28,7 +28,9 @@ rendererDebugger: *extras.RendererDebug = undefined,
|
||||||
|
|
||||||
tbMap: ?*bsp.maploader.TBMap = null,
|
tbMap: ?*bsp.maploader.TBMap = null,
|
||||||
|
|
||||||
fileWatch: f64 = 3.0,
|
addFunc: ?*const fn (i32, i32) callconv(.C) i32 = undefined,
|
||||||
|
|
||||||
|
modules: std.AutoHashMapUnmanaged(u32, []const u8) = .{},
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||||
|
|
||||||
|
|
@ -172,6 +174,14 @@ pub fn loadMap(self: *@This()) void {
|
||||||
core.engine_log("map loaded", .{});
|
core.engine_log("map loaded", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn moduleChangedCallback(pathChanged: []const u8, ctx: ?*anyopaque) void {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
|
||||||
|
core.engine_log("moduleChanged {s}", .{pathChanged});
|
||||||
|
var name = core.MakeName(pathChanged);
|
||||||
|
self.modules.put(self.allocator, name.handle(), name.utf8()) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
|
@ -180,6 +190,11 @@ 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");
|
||||||
|
|
||||||
|
core.fs().watchPath("zig-out/modules");
|
||||||
|
try core.fs().addFileChangedCallback(core.sharedLibName("externGame"), moduleChangedCallback, self);
|
||||||
|
|
||||||
|
try self.tryLoadExtern("externGame");
|
||||||
|
|
||||||
self.rendererDebugger = try extras.RendererDebug.create(self.allocator); //try core.createObject(extras.RendererDebug, .{});
|
self.rendererDebugger = try extras.RendererDebug.create(self.allocator); //try core.createObject(extras.RendererDebug, .{});
|
||||||
|
|
||||||
self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
|
self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
|
||||||
|
|
@ -361,17 +376,39 @@ pub fn getMouseMovement(self: *@This()) core.Vector2f {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tryLoadExtern(self: *@This(), gameName: []const u8) !void {
|
||||||
|
var buf = std.mem.zeroes([256]u8);
|
||||||
|
|
||||||
|
const os_tag = @import("builtin").os.tag;
|
||||||
|
|
||||||
|
var suffix: []const u8 = "dll";
|
||||||
|
if (os_tag == .linux) {
|
||||||
|
suffix = "so";
|
||||||
|
} else if (os_tag == .macos) {
|
||||||
|
suffix = "dynlib";
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = try std.fmt.bufPrint(&buf, "zig-out/bin/{s}.{s}", .{ gameName, suffix });
|
||||||
|
var lib = try std.DynLib.open(path);
|
||||||
|
// std.debug.print("path: {s}", .{path});
|
||||||
|
|
||||||
|
self.addFunc = lib.lookup(@TypeOf(self.addFunc.?), "add");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tick(self: *@This(), dt: f64) void {
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
const fdt: f32 = @floatCast(dt);
|
const fdt: f32 = @floatCast(dt);
|
||||||
|
|
||||||
_ = ig.dockSpaceOverViewport(ig.getMainViewport(), .{ .passthru_central_node = true }, null);
|
_ = ig.dockSpaceOverViewport(ig.getMainViewport(), .{ .passthru_central_node = true }, null);
|
||||||
|
|
||||||
self.loadMap2() catch unreachable;
|
// self.loadMap2() catch unreachable;
|
||||||
|
|
||||||
self.fileWatch -= dt;
|
core.loopDelay(@src(), 1.0, dt, struct {
|
||||||
if (self.fileWatch < 0) {
|
s: @TypeOf(self),
|
||||||
self.fileWatch = 3.0;
|
|
||||||
}
|
pub fn func(c: @This()) void {
|
||||||
|
c.s.tryLoadExtern("externGame") catch unreachable;
|
||||||
|
}
|
||||||
|
}, .{ .s = self });
|
||||||
|
|
||||||
const z1 = tracy.ZoneN(@src(), "inputDebugger");
|
const z1 = tracy.ZoneN(@src(), "inputDebugger");
|
||||||
if (!self.mouseLook) {
|
if (!self.mouseLook) {
|
||||||
|
|
@ -441,6 +478,15 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return;
|
ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return;
|
||||||
ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return;
|
ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return;
|
||||||
|
|
||||||
|
ig.textf("1 + 2 = {d}", .{self.addFunc.?(1, 2)});
|
||||||
|
|
||||||
|
{
|
||||||
|
ig.textf("modules dirty: ", .{});
|
||||||
|
var i = self.modules.iterator();
|
||||||
|
while (i.next()) |n| {
|
||||||
|
ig.textf("{s} pending reload", .{n.value_ptr.*});
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ig.smallButton("reload map")) {
|
if (ig.smallButton("reload map")) {
|
||||||
self.loadMap2() catch unreachable;
|
self.loadMap2() catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
@ -472,6 +518,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
|
self.modules.deinit(self.allocator);
|
||||||
self.rendererDebugger.destroy();
|
self.rendererDebugger.destroy();
|
||||||
DoomPlayer.DoomCanvas.cleanupDoom();
|
DoomPlayer.DoomCanvas.cleanupDoom();
|
||||||
self.fpcamera.destroy();
|
self.fpcamera.destroy();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue