diff --git a/src/custom.zig b/src/custom.zig index f346fa0..a91bdd2 100644 --- a/src/custom.zig +++ b/src/custom.zig @@ -120,9 +120,8 @@ pub const Write = struct { allocator: *std.mem.Allocator, params: *plugins.ParamMap, ) Write { - const data = params.get("data").?; return Write{ - .data = data.value, + .data = params.get("data").?.value, }; } @@ -140,10 +139,10 @@ pub const Embed = struct { sndfile: *c.SNDFILE = undefined, buf: []f32 = undefined, - pub fn init(allocator: *std.mem.Allocator, filepath: []const u8) @This() { + pub fn init(allocator: *std.mem.Allocator, params: *plugins.ParmaMap) @This() { return Embed{ .allocator = allocator, - .filepath = filepath, + .filepath = params.get("path").?.value, }; } diff --git a/src/image.zig b/src/image.zig index 7f8deb4..d677afa 100644 --- a/src/image.zig +++ b/src/image.zig @@ -422,8 +422,7 @@ pub const Image = struct { self: *Image, comptime Plugin: type, position: plugins.Position, - comptime ExtraType: type, - extra: ExtraType, + extra: *ParamMap, ) !void { var plugin_opt: ?Plugin = Plugin.init(self.allocator, extra); if (plugin_opt == null) { diff --git a/src/lang.zig b/src/lang.zig index 03a6c52..cc8d58a 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -1,6 +1,7 @@ const std = @import("std"); const plugin = @import("plugin.zig"); +const custom = @import("custom.zig"); pub const ParseError = error{ OutOfMemory, @@ -12,6 +13,8 @@ pub const CommandType = enum { /// "LV2 Commands" are commands that receive split, index, and then receive /// any f64 arguments. lv2_command, + + custom_command, }; fn LV2Command( @@ -32,19 +35,19 @@ fn LV2Command( } fn CustomCommand( - comptime tag: Command.tag, - comptime plugin: type, - comptime parameters: type, + comptime tag: Command.Tag, + comptime Plugin: type, + comptime PluginParameters: type, ) type { return struct { pub const base_tag = tag; - pub const command_type = CommandType.plugin_command; - pub const plugin_type = plugin; + pub const command_type = CommandType.custom_command; + pub const plugin_type = Plugin; base: Command, split: usize, index: usize, - parameters: LV2Parameters, + parameters: PluginParameters, }; } @@ -188,13 +191,9 @@ pub const Command = struct { data: f32, }); - pub const Embed = struct { - pub const base_tag = Tag.embed; - base: Command, - split: usize, - index: usize, + pub const Embed = CustomCommand(Tag.write, custom.Embed, struct { path: []const u8, - }; + }); pub const Rotate = struct { pub const base_tag = Tag.rotate; @@ -521,7 +520,7 @@ pub const Lang = struct { // Based on the command struct fields, we can parse the arguments. var cmd = try self.allocator.create(command_struct); const is_lv2_command = switch (command_struct.base_tag) { - .noop, .load, .quicksave, .runqs => false, + .noop, .load, .quicksave, .runqs, .rotate => false, else => command_struct.command_type == .lv2_command, }; diff --git a/src/runner.zig b/src/runner.zig index e65bac0..a1bed65 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -190,26 +190,6 @@ pub const Runner = struct { _ = try proc.spawnAndWait(); } - fn noiseCmd(self: *Runner, pos: Position, map: *ParamMap) !void { - var image = try self.getImage(); - try image.runCustomPlugin(custom.RandomNoise, pos, *ParamMap, map); - } - - fn wildNoiseCmd(self: *Runner, pos: Position, map: *ParamMap) !void { - var image = try self.getImage(); - try image.runCustomPlugin(custom.WildNoise, pos, *ParamMap, map); - } - - fn writeCmd(self: *Runner, pos: Position, map: *ParamMap) !void { - var image = try self.getImage(); - try image.runCustomPlugin(custom.Write, pos, *ParamMap, map); - } - - fn embedCmd(self: *Runner, pos: Position, path: []const u8) !void { - var image = try self.getImage(); - try image.runCustomPlugin(custom.Embed, pos, []const u8, path); - } - fn rotateCmd( self: *Runner, deg: f32, @@ -244,6 +224,26 @@ pub const Runner = struct { try image.runPlugin(typ.lv2_url, pos, params); } + fn executePlugin(self: *@This(), command: var) !void { + const pos = plugin.Position{ + .split = command.split, + .index = command.index, + }; + + var params = ParamMap.init(self.allocator); + defer params.deinit(); + + inline for (@typeInfo(@TypeOf(command.parameters)).Struct.fields) |cmd_field| { + try params.put( + cmd_field.name, + @field(command.parameters, cmd_field.name), + ); + } + + var image = try self.getImage(); + try image.runCustomPlugin(typ.plugin_type, pos, map); + } + fn newRunCommandSingle( self: *@This(), cmd: lang.Command, @@ -261,6 +261,7 @@ pub const Runner = struct { const ctype = typ.command_type; switch (ctype) { .lv2_command => try self.executeLV2Command(command.*), + .plugin_command => try self.executePlugin(command.*), else => @panic("TODO support command type"), } } @@ -305,6 +306,8 @@ pub const Runner = struct { .saturator => try self.newRunCommandSingle(cmd, .saturator), .vintagedelay => try self.newRunCommandSingle(cmd, .vintagedelay), + .noise, .wildnoise, .write, .embed => |tag| try self.newRunCommandSingle(cmd, tag), + else => { std.debug.warn("TODO support {}\n", .{@tagName(cmd.tag)}); @panic("TODO support tag");