aboutsummaryrefslogtreecommitdiffstats
path: root/src/control.zig
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-06-08 09:09:11 +0000
committers-ol <s-ol@users.noreply.github.com>2020-06-08 09:09:11 +0000
commitcdf81cc4f3c017eff089138bab9fa49c85b7f1a2 (patch)
tree92c46b0b70a11384e65daf40b16b177106274dea /src/control.zig
parentdifferent OSC set layer (diff)
downloadglsl-view-cdf81cc4f3c017eff089138bab9fa49c85b7f1a2.tar.gz
glsl-view-cdf81cc4f3c017eff089138bab9fa49c85b7f1a2.zip
error handling
Diffstat (limited to 'src/control.zig')
-rw-r--r--src/control.zig181
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;
}