diff --git a/src/image.zig b/src/image.zig index 3e38903..1942f87 100644 --- a/src/image.zig +++ b/src/image.zig @@ -131,7 +131,6 @@ pub const Image = struct { /// Open a BMP image for later. pub fn open(allocator: *std.mem.Allocator, path: []const u8) !*Image { var in_fmt = mkSfInfo(); - var sndfile = try sopen(allocator, path, c.SFM_READ, &in_fmt); var image = try allocator.create(Image); @@ -149,6 +148,26 @@ pub const Image = struct { return image; } + pub fn clone(self: *Image) !*Image { + var in_fmt = mkSfInfo(); + // clone sndfile + var sndfile = try sopen(self.allocator, self.path, c.SFM_READ, &in_fmt); + var image = try allocator.create(Image); + + std.debug.assert(in_fmt.frames > i64(0)); + std.debug.assert(in_fmt.seekable == i32(1)); + + image.* = Image{ + .allocator = self.allocator, + .sndfile = sndfile, + .path = self.path, + .curpath = self.curpath, + .frames = @intCast(usize, in_fmt.frames), + }; + + return image; + } + pub fn close(self: *Image) void { //self.allocator.free(self.path); //self.allocator.free(self.curpath); diff --git a/src/main.zig b/src/main.zig index 671ed3f..be83ad6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,6 +8,13 @@ test "scritcher" { _ = @import("runner.zig"); } +fn wrapInCmdList(allocator: *std.mem.Allocator, cmd: langs.Command) !langs.CommandList { + var cmds = try langs.CommandList.init(allocator); + try cmds.append(cmd); + + return cmds; +} + pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { var stdout_file = try std.io.getStdOut(); const stdout = &stdout_file.outStream().stream; @@ -24,30 +31,38 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { // now have a 'repl' argument right before it. to counteract that, the // initial repl buffer contains 'load :1' instead. - var cmds = langs.CommandList.init(allocator); - defer cmds.deinit(); - var loadargs = langs.ArgList.init(allocator); defer loadargs.deinit(); try loadargs.append(":1"); - try cmds.append(langs.Command{ + var cmds = try wrapInCmdList(allocator, langs.Command{ .command = .Load, .args = loadargs, }); - // TODO start a runner and keep it hot + defer cmds.deinit(); // we keep // - a CommandList with the full commands we have right now // - a Command with the current last typed successful command + // - one runner that contains the current full state of the image + // as if the current cmds was ran over it (TODO better wording) + // - one runner that gets copied from the original on every new + // command the user issues + var lang = langs.Lang.init(allocator); defer lang.deinit(); var current: langs.Command = undefined; + var runner = runners.Runner.init(allocator); + defer runner.deinit(); + + // run the load command + try runner.runCommands(cmds, true); + while (true) { lang.reset(); try stdout.print("> "); @@ -60,6 +75,10 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { if (std.mem.eql(u8, line, "push")) { try cmds.append(current); + var cmds_wrapped = try wrapInCmdList(allocator, current); + defer cmds_wrapped.deinit(); + + try runner.runCommands(cmds_wrapped, true); continue; } else if (std.mem.eql(u8, line, "list")) { try printer.printList(cmds, stdout); @@ -75,6 +94,11 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { continue; }; current = cmds_parsed.at(0); + + var runner_clone = try runner.clone(); + defer runner_clone.deinit(); + + try runner_clone.runCommands(cmds_parsed, true); } } diff --git a/src/runner.zig b/src/runner.zig index a348f22..909a9b2 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -33,6 +33,10 @@ pub const Runner = struct { } } + pub fn clone(self: *Runner) *Runner { + return Runner{ .allocator = allocator, .image = try image.clone() }; + } + fn resolveArg(self: *Runner, load_path: []const u8) ![]const u8 { if (load_path[0] == ':') { // parse the index from 1 to end