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