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-
71const c = @import ("clap_c" );
82const clap = @import ("clap" );
3+ const msgpack = @import ("msgpack" );
94
105const std = @import ("std" );
116const 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