diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-06-08 09:09:11 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-06-08 09:09:11 +0000 |
| commit | cdf81cc4f3c017eff089138bab9fa49c85b7f1a2 (patch) | |
| tree | 92c46b0b70a11384e65daf40b16b177106274dea /src/control.zig | |
| parent | different OSC set layer (diff) | |
| download | glsl-view-cdf81cc4f3c017eff089138bab9fa49c85b7f1a2.tar.gz glsl-view-cdf81cc4f3c017eff089138bab9fa49c85b7f1a2.zip | |
error handling
Diffstat (limited to 'src/control.zig')
| -rw-r--r-- | src/control.zig | 181 |
1 files changed, 108 insertions, 73 deletions
diff --git a/src/control.zig b/src/control.zig index 2dd182e..822b044 100644 --- a/src/control.zig +++ b/src/control.zig @@ -5,26 +5,43 @@ const cfg = @import("config.zig"); const param_prefix = "/param/"; -fn set_array(comptime T: type, dest: []T, argc: c_int, argv: [*c][*c]c.lo_arg) void { - std.debug.assert(argc == dest.len); +fn verify_args(expected: u8, got: []const u8) !void { + for (got) |typ| { + if (typ != expected) + return error.typeMismatch; + } +} + +fn set_array(comptime T: type, dest: []T, argc: c_int, argv: [*c][*c]c.lo_arg, types: []const u8) !void { + if (argc != dest.len) + return error.sizeMismatch; + switch (T) { f32 => { + try verify_args('f', types); for (dest) |*v, i| v.* = argv[i].*.f; }, f64 => { + try verify_args('d', types); for (dest) |*v, i| v.* = argv[i].*.d; }, i32 => { + try verify_args('i', types); for (dest) |*v, i| v.* = argv[i].*.i; }, u32 => { - for (dest) |*v, i| + try verify_args('i', types); + for (dest) |*v, i| { + const val = argv[i].*.i; + if (val < 0) + return error.signDisallowed; v.* = @intCast(u32, argv[i].*.i); + } }, - else => {} + else => return error.invalidType, } } @@ -32,9 +49,12 @@ pub const ControlServer = struct { server: c.lo_server, cache: *gl.UniformCache, - pub fn init(allocator: *std.mem.Allocator, config: cfg.OSCConfig, cache: *gl.UniformCache) !*ControlServer { + pub fn init( + allocator: *std.mem.Allocator, + config: cfg.OSCConfig, + cache: *gl.UniformCache, + ) !*ControlServer { var self: *ControlServer = try allocator.create(ControlServer); - self.cache = cache; switch (config) { @@ -48,7 +68,10 @@ pub const ControlServer = struct { else => unreachable, }; - std.debug.warn("listening for OSC messages on {} port {}\n", .{ conf.protocol, conf.port }); + std.debug.warn( + "listening for OSC messages on {} port {}\n", + .{ conf.protocol, conf.port }, + ); self.server = c.lo_server_new_with_proto(port[0..], proto, handle_error); }, .URL => |url| { @@ -74,85 +97,97 @@ pub const ControlServer = struct { } fn handle_error(num: c_int, msg: [*c]const u8, where: [*c]const u8) callconv(.C) void { - std.debug.warn("OSC error {} @ {s}: {s}\n", .{ num, @ptrCast([*:0]const u8, where), @ptrCast([*:0]const u8, msg) }); + std.debug.warn( + "OSC error {} @ {s}: {s}\n", + .{ num, @ptrCast([*:0]const u8, where), @ptrCast([*:0]const u8, msg) }, + ); } - fn handle_method(_path: [*c]const u8, _types: [*c]const u8, argv: [*c][*c]c.lo_arg, argc: c_int, msg: c.lo_message, userdata: ?*c_void) callconv(.C) c_int { + fn set_uniform( + self: *ControlServer, + uniform_name: []const u8, + argv: [*c][*c]c.lo_arg, + argc: c_int, + types: []const u8, + ) !void { + var buffer: [256]u8 = undefined; + std.mem.copy(u8, buffer[0..], uniform_name); + buffer[uniform_name.len] = 0; + const name = buffer[0 .. uniform_name.len + 1]; + const uniform = (try self.cache.get(name)) orelse return error.notFound; + + try switch (uniform.value) { + .FLOAT => |*val| set_array(f32, @ptrCast([*]f32, val)[0..1], argc, argv, types), + .DOUBLE => |*val| set_array(f64, @ptrCast([*]f64, val)[0..1], argc, argv, types), + .INT => |*val| set_array(i32, @ptrCast([*]i32, val)[0..1], argc, argv, types), + .UNSIGNED_INT => |*val| set_array(u32, @ptrCast([*]u32, val)[0..1], argc, argv, types), + .BOOL => |*val| set_array(u32, @ptrCast([*]u32, val)[0..1], argc, argv, types), + .FLOAT_VEC2 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_VEC3 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_VEC4 => |*val| set_array(f32, val[0..], argc, argv, types), + .DOUBLE_VEC2 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_VEC3 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_VEC4 => |*val| set_array(f64, val[0..], argc, argv, types), + .INT_VEC2 => |*val| set_array(i32, val[0..], argc, argv, types), + .INT_VEC3 => |*val| set_array(i32, val[0..], argc, argv, types), + .INT_VEC4 => |*val| set_array(i32, val[0..], argc, argv, types), + .UNSIGNED_INT_VEC2 => |*val| set_array(u32, val[0..], argc, argv, types), + .UNSIGNED_INT_VEC3 => |*val| set_array(u32, val[0..], argc, argv, types), + .UNSIGNED_INT_VEC4 => |*val| set_array(u32, val[0..], argc, argv, types), + .BOOL_VEC2 => |*val| set_array(u32, val[0..], argc, argv, types), + .BOOL_VEC3 => |*val| set_array(u32, val[0..], argc, argv, types), + .BOOL_VEC4 => |*val| set_array(u32, val[0..], argc, argv, types), + .FLOAT_MAT2 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT3 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT4 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT2x3 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT2x4 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT3x2 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT3x4 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT4x2 => |*val| set_array(f32, val[0..], argc, argv, types), + .FLOAT_MAT4x3 => |*val| set_array(f32, val[0..], argc, argv, types), + .DOUBLE_MAT2 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT3 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT4 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT2x3 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT2x4 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT3x2 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT3x4 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT4x2 => |*val| set_array(f64, val[0..], argc, argv, types), + .DOUBLE_MAT4x3 => |*val| set_array(f64, val[0..], argc, argv, types), + else => error.uniformNotSupported, + }; + + uniform.setShaderValue(self.cache.shader.*); + } + + fn handle_method( + _path: [*c]const u8, + _types: [*c]const u8, + argv: [*c][*c]c.lo_arg, + argc: c_int, + msg: c.lo_message, + userdata: ?*c_void, + ) callconv(.C) c_int { const self = @ptrCast(*ControlServer, @alignCast(@alignOf(ControlServer), userdata.?)); const path = _path[0..c.strlen(_path)]; const types = _types[0..@intCast(u32, argc)]; - if (std.mem.startsWith(u8, path, "/param/")) { - if (!std.mem.endsWith(u8, path, "/set")) { - std.debug.warn("unhandled OSC message {s} ({s})\n", .{ path, types }); - return 1; - } - - const param_name = path["/param/".len .. path.len - "/set".len]; - var buffer: [256]u8 = undefined; - std.mem.copy(u8, buffer[0..], param_name); - buffer[param_name.len] = 0; - - const uniform = self.cache.get(buffer[0 .. param_name.len + 1]) - catch { return 0; } - orelse { return 0; }; - - switch (uniform.value) { - .FLOAT => |*val| val.* = argv[0].*.f, - .FLOAT_VEC2 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_VEC3 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_VEC4 => |*val| set_array(f32, val[0..], argc, argv), - .DOUBLE => |*val| val.* = argv[0].*.d, - .DOUBLE_VEC2 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_VEC3 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_VEC4 => |*val| set_array(f64, val[0..], argc, argv), - .INT => |*val| val.* = argv[0].*.i, - .INT_VEC2 => |*val| set_array(i32, val[0..], argc, argv), - .INT_VEC3 => |*val| set_array(i32, val[0..], argc, argv), - .INT_VEC4 => |*val| set_array(i32, val[0..], argc, argv), - .UNSIGNED_INT => |*val| val.* = @intCast(u32, argv[0].*.i), - .UNSIGNED_INT_VEC2 => |*val| set_array(u32, val[0..], argc, argv), - .UNSIGNED_INT_VEC3 => |*val| set_array(u32, val[0..], argc, argv), - .UNSIGNED_INT_VEC4 => |*val| set_array(u32, val[0..], argc, argv), - .BOOL => |*val| val.* = @intCast(u32, argv[0].*.i), - .BOOL_VEC2 => |*val| set_array(u32, val[0..], argc, argv), - .BOOL_VEC3 => |*val| set_array(u32, val[0..], argc, argv), - .BOOL_VEC4 => |*val| set_array(u32, val[0..], argc, argv), - .FLOAT_MAT2 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT3 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT4 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT2x3 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT2x4 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT3x2 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT3x4 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT4x2 => |*val| set_array(f32, val[0..], argc, argv), - .FLOAT_MAT4x3 => |*val| set_array(f32, val[0..], argc, argv), - .DOUBLE_MAT2 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT3 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT4 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT2x3 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT2x4 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT3x2 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT3x4 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT4x2 => |*val| set_array(f64, val[0..], argc, argv), - .DOUBLE_MAT4x3 => |*val| set_array(f64, val[0..], argc, argv), - else => { - std.debug.warn("unsupported types: {s}\n", .{types}); - return 0; - } - } - - uniform.setShaderValue(self.cache.shader.*); - return 0; + if (!std.mem.startsWith(u8, path, "/")) { + std.debug.warn("invalid OSC message {s} ({s})\n", .{ path, types }); + return 1; } - std.debug.warn("unhandled OSC message {s} ({s})\n", .{ path, types }); - return 1; + self.set_uniform(path[1..], argv, argc, types) catch |err| { + std.debug.warn("{}\n", .{err}); + }; + return 0; } fn handle_bundle_start(time: c.lo_timetag, userdata: ?*c_void) callconv(.C) c_int { return 1; } + fn handle_bundle_end(userdata: ?*c_void) callconv(.C) c_int { return 1; } |
