Skip to content
This repository was archived by the owner on Mar 28, 2026. It is now read-only.

Commit af34231

Browse files
committed
serialize parameters state with msgpack
1 parent f12dc24 commit af34231

3 files changed

Lines changed: 67 additions & 30 deletions

File tree

‎build.zig‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ pub fn build(b: *std.Build) !void {
7676
});
7777
}
7878

79+
if (b.lazyDependency("msgpack", .{
80+
.target = target,
81+
.optimize = optimize,
82+
})) |msgpack|
83+
clap_module.addImport("msgpack", msgpack.module("msgpack"));
84+
7985
const clap_tests = b.addTest(.{ .root_module = clap_module });
8086
const run_clap_tests = b.addRunArtifact(clap_tests);
8187
test_step.dependOn(&run_clap_tests.step);

‎build.zig.zon‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
.hash = "N-V-__8AABAqOwDxKlwerqbiBlg183KUY751DdoGwZ9N-ZuE",
1111
.lazy = true,
1212
},
13+
.msgpack = .{
14+
.url = "https://github.com/zigcc/zig-msgpack/archive/refs/tags/0.0.16.tar.gz",
15+
.hash = "zig_msgpack-0.0.14-evvueHImBQA5zzdD7c4Sl9yJ4JECWb4JaWgvbInsk7Zt",
16+
.lazy = true,
17+
},
1318
},
1419
.paths = .{
1520
"src",

‎src/clap/extensions/state.zig‎

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
// TODO: use some sort of actual binary serialization
2-
// libs to consider:
3-
// - https://github.com/ziglibs/s2s
4-
// - https://github.com/SeanTheGleaming/zig-serialization
5-
// - https://codeberg.org/hDS9HQLN/ztsl
6-
71
const c = @import("clap_c");
82
const clap = @import("clap");
3+
const msgpack = @import("msgpack");
94

105
const std = @import("std");
116
const log = std.log.scoped(.zigplug_clap_state);
@@ -75,27 +70,45 @@ const Reader = struct {
7570
}
7671
};
7772

78-
pub fn extension(comptime _: type) *const c.clap_plugin_state {
73+
pub fn extension(comptime Plugin: type) *const c.clap_plugin_state {
7974
const state = struct {
8075
pub fn save(clap_plugin: [*c]const c.clap_plugin, stream: [*c]const c.clap_ostream) callconv(.c) bool {
8176
const data = clap.Data.fromClap(clap_plugin);
77+
8278
var clap_writer = Writer.init(stream);
8379
const writer = &clap_writer.writer;
8480

85-
for (data.plugin.parameters.?.slice) |parameter| {
86-
switch (parameter.*) {
87-
inline else => |p| {
88-
const value = p.get();
89-
const bytes = std.mem.asBytes(&value);
90-
writer.writeAll(bytes) catch {
91-
log.err("failed to save parameter '{s}' = {}", .{ p.options.name, value });
81+
var reader = std.Io.Reader.failing;
82+
var packer = msgpack.packIO(&reader, writer);
83+
84+
var map = msgpack.Payload.mapPayload(data.plugin.allocator);
85+
defer map.free(data.plugin.allocator);
86+
87+
inline for (data.plugin.parameters.?.slice, std.meta.fields(Plugin.Parameters)) |parameter, field| {
88+
map.mapPut(field.name, switch (parameter.*) {
89+
.bool => |p| .boolToPayload(p.get()),
90+
.float => |p| .floatToPayload(p.get()),
91+
.int => |p| .intToPayload(p.get()),
92+
.uint => |p| .uintToPayload(p.get()),
93+
}) catch {
94+
switch (parameter.*) {
95+
inline else => |p| {
96+
log.err("failed to save parameter '{s}' = {any}", .{ p.options.name, p.get() });
9297
return false;
93-
};
94-
log.debug("saved parameter '{s}' = {any}", .{ p.options.name, value });
95-
},
98+
},
99+
}
100+
};
101+
102+
switch (parameter.*) {
103+
inline else => |p| log.debug("saved parameter '{s}' = {any}", .{ field.name, p.get() }),
96104
}
97105
}
98106

107+
packer.write(map) catch {
108+
log.err("failed to save parameters", .{});
109+
return false;
110+
};
111+
99112
return true;
100113
}
101114

@@ -104,21 +117,34 @@ pub fn extension(comptime _: type) *const c.clap_plugin_state {
104117
var clap_reader = Reader.init(stream);
105118
const reader = &clap_reader.reader;
106119

107-
for (data.plugin.parameters.?.slice) |parameter| switch (parameter.*) {
108-
inline else => |*p| {
109-
var value = p.get();
110-
const buffer = std.mem.asBytes(&value);
111-
reader.readSliceAll(buffer) catch {
112-
log.err("failed to load parameter '{s}'", .{p.options.name});
113-
return false;
114-
};
115-
p.set(value);
116-
117-
log.debug("loaded parameter '{s}' = {any}", .{ p.options.name, value });
118-
},
120+
var writer = std.Io.Writer.failing;
121+
var packer = msgpack.packIO(reader, &writer);
122+
123+
const decoded = packer.read(data.plugin.allocator) catch {
124+
log.err("failed to read parameters", .{});
125+
return false;
119126
};
127+
defer decoded.free(data.plugin.allocator);
128+
129+
inline for (data.plugin.parameters.?.slice, std.meta.fields(Plugin.Parameters)) |parameter, field| {
130+
if (decoded.mapGet(field.name) catch {
131+
log.err("failed to read parameter '{s}'", .{field.name});
132+
return false;
133+
}) |value| {
134+
switch (parameter.*) {
135+
.bool => |*p| p.set(value.bool),
136+
.float => |*p| p.set(value.float),
137+
.int => |*p| p.set(value.int),
138+
.uint => |*p| p.set(value.uint),
139+
}
140+
}
120141

121-
return false;
142+
switch (parameter.*) {
143+
inline else => |p| log.debug("read parameter '{s}' = {any}", .{ field.name, p.get() }),
144+
}
145+
}
146+
147+
return true;
122148
}
123149
};
124150

0 commit comments

Comments
 (0)