const std = @import("std"); const testing = std.testing; const clap = @import("./clap.zig"); const shared = @import("./shared.zig"); // Plugin binding(s) const gmsynth = @import("./gmsynth.zig"); // Override logging with host logging if available pub const std_options = struct { pub fn logFn( comptime message_level: std.log.Level, comptime scope: @TypeOf(.enum_literal), comptime format: []const u8, args: anytype, ) void { // Try using every plugin's self hook to get host logging // if they all are not available, default to defaultLog switch (gmsynth.plugin_state) { .inited => |*self| { if (gmsynth.logFn(self, message_level, scope, format, args)) { return; } else |err| { switch (err) { // Avoid noisy logs by ignoring this very common error error.NoHostLogExtension => {}, else => std.debug.print("Failed to use gmsynth.logFn: {}\n", .{err}), } } }, else => {}, } std.log.defaultLog(message_level, scope, format, args); } }; export const clap_entry = clap.clap_plugin_entry_t{ .clap_version = shared.build_clap_version, .init = entry_init, .deinit = entry_deinit, .get_factory = entry_get_factory, }; fn entry_init(plugin_path: ?[*:0]const u8) callconv(.C) bool { _ = plugin_path; // std.debug.print("{?s}\n", .{plugin_path}); return true; } fn entry_deinit() callconv(.C) void { // Make sure that all shared allocations are deallocated // by the time the DSO is unloaded if (std.debug.runtime_safety) { _ = shared.gpa.detectLeaks(); } } fn entry_get_factory(factory_id: ?[*:0]const u8) callconv(.C) ?*const anyopaque { if (factory_id) |fid| { if (std.mem.eql(u8, std.mem.span(fid), &clap.CLAP_PLUGIN_FACTORY_ID)) { return &s_plugin_factory; } } return null; } const s_plugins = [_]shared.PluginEntry{ gmsynth.entry, }; const s_plugin_factory = clap.clap_plugin_factory_t{ .get_plugin_count = pf_get_plugin_count, .get_plugin_descriptor = pf_get_plugin_descriptor, .create_plugin = pf_plugin_create, }; fn pf_get_plugin_count(factory: ?*const clap.clap_plugin_factory) callconv(.C) u32 { _ = factory; return s_plugins.len; } fn pf_get_plugin_descriptor(factory: ?*const clap.clap_plugin_factory, index: u32) callconv(.C) *const clap.clap_plugin_descriptor_t { _ = factory; return s_plugins[index].desc; } fn pf_plugin_create( factory: ?*const clap.clap_plugin_factory, maybe_host: ?*const clap.clap_host_t, maybe_plugin_id: ?[*:0]const u8, ) callconv(.C) ?*const clap.clap_plugin_t { _ = factory; if (maybe_host) |host| { if (!clap.clap_version_is_compatible(host.clap_version)) { return null; } if (maybe_plugin_id) |plugin_id| { return for (s_plugins) |plugin_entry| { if (std.mem.eql(u8, std.mem.span(plugin_id), std.mem.span(plugin_entry.desc.id))) { break plugin_entry.create(host) catch |err| { std.log.err("Failed to create plugin '{s}': {}", .{ plugin_entry.desc.id, err }); return null; }; } } else null; } } return null; }