aboutsummaryrefslogtreecommitdiffstats
path: root/src/control.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/control.zig')
-rw-r--r--src/control.zig206
1 files changed, 117 insertions, 89 deletions
diff --git a/src/control.zig b/src/control.zig
index 0ea6712..72abf6f 100644
--- a/src/control.zig
+++ b/src/control.zig
@@ -16,11 +16,10 @@ fn verify_args(expected: u8, got: []const u8) !void {
fn set_one(
comptime T: type,
dest: *T,
- argc: c_int,
- argv: [*c][*c]c.lo_arg,
+ argv: [][*c]c.lo_arg,
types: []const u8,
) !void {
- if (argc != 1)
+ if (types.len != 1)
return error.sizeMismatch;
switch (T) {
@@ -50,11 +49,10 @@ fn set_one(
fn set_array(
comptime T: type,
dest: []T,
- argc: c_int,
- argv: [*c][*c]c.lo_arg,
+ argv: [][*c]c.lo_arg,
types: []const u8,
) !void {
- if (argc != dest.len)
+ if (types.len != dest.len)
return error.sizeMismatch;
switch (T) {
@@ -88,14 +86,12 @@ fn set_array(
fn set_texture(
progress: std.Progress.Node,
- project_root: std.fs.Dir,
dest: *?gl.Texture,
texture_type: gl.Texture.Type,
- argc: c_int,
- argv: [*c][*c]c.lo_arg,
+ argv: [][*c]c.lo_arg,
types: []const u8,
) !void {
- if (argc != 1 or types[0] != 's') return error.invalidType;
+ if (types.len != 1 or types[0] != 's') return error.invalidType;
if (dest.*) |old| {
old.destroy();
@@ -103,7 +99,7 @@ fn set_texture(
}
var buffer: [1024]u8 = undefined;
- const filepath = try project_root.realpathZ(@ptrCast(&argv[0].*.s), buffer[0..]);
+ const filepath = try std.fs.cwd().realpathZ(@ptrCast(&argv[0].*.s), buffer[0..]);
buffer[filepath.len] = 0;
dest.* = try video.loadVideo(progress, @ptrCast(filepath), texture_type);
@@ -111,7 +107,6 @@ fn set_texture(
pub const ControlServer = struct {
server: c.lo_server,
- reload_requested: bool,
cache: *gl.UniformCache,
config: *cfg.Config,
@@ -127,7 +122,6 @@ pub const ControlServer = struct {
var self: *ControlServer = try allocator.create(ControlServer);
self.* = .{
.server = null,
- .reload_requested = false,
.cache = cache,
.config = config,
@@ -135,31 +129,15 @@ pub const ControlServer = struct {
.allocator = allocator,
};
- switch (config.osc) {
- .Manual => |conf| {
- var port = [_]u8{0} ** 6;
- _ = std.fmt.formatIntBuf(port[0..], conf.port, 10, .lower, std.fmt.FormatOptions{});
- const proto: c_int = switch (conf.protocol) {
- .udp => c.LO_UDP,
- .tcp => c.LO_TCP,
- .unix => c.LO_UNIX,
- };
-
- std.debug.print(
- "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| {
- std.debug.print("listening for OSC messages at {s}\n", .{url});
- self.server = c.lo_server_new_from_url(url[0..].ptr, handle_error);
- },
- }
+ std.debug.print("listening for OSC messages at {s}\n", .{config.osc});
+ self.server = c.lo_server_new_from_url(config.osc.ptr, handle_error);
if (self.server == null)
return error.serverInitializationError;
- _ = c.lo_server_add_method(self.server, null, null, handle_method, @as(*anyopaque, @ptrCast(self)));
+
+ _ = c.lo_server_add_method(self.server, "/-/shader", "s", handle_shader, @as(*anyopaque, @ptrCast(self)));
+ // _ = c.lo_server_add_method(self.server, "/-/reload", "", handle_reload, @as(*anyopaque, @ptrCast(self)));
+ _ = c.lo_server_add_method(self.server, "/*", null, handle_uniform, @as(*anyopaque, @ptrCast(self)));
return self;
}
@@ -182,8 +160,7 @@ pub const ControlServer = struct {
fn set_uniform(
self: *ControlServer,
path: []const u8,
- argv: [*c][*c]c.lo_arg,
- argc: c_int,
+ argv: [][*c]c.lo_arg,
types: []const u8,
) !void {
var parts = std.mem.tokenizeScalar(u8, path, '/');
@@ -217,61 +194,61 @@ pub const ControlServer = struct {
}
try switch (value) {
- .FLOAT => |val| set_one(f32, val, argc, argv, types),
- .DOUBLE => |val| set_one(f64, val, argc, argv, types),
- .INT => |val| set_one(i32, val, argc, argv, types),
- .UNSIGNED_INT => |val| set_one(u32, val, argc, argv, types),
- .BOOL => |val| set_one(u32, val, 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),
+ .FLOAT => |val| set_one(f32, val, argv, types),
+ .DOUBLE => |val| set_one(f64, val, argv, types),
+ .INT => |val| set_one(i32, val, argv, types),
+ .UNSIGNED_INT => |val| set_one(u32, val, argv, types),
+ .BOOL => |val| set_one(u32, val, argv, types),
+ .FLOAT_VEC2 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_VEC3 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_VEC4 => |val| set_array(f32, val.*[0..], argv, types),
+ .DOUBLE_VEC2 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_VEC3 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_VEC4 => |val| set_array(f64, val.*[0..], argv, types),
+ .INT_VEC2 => |val| set_array(i32, val.*[0..], argv, types),
+ .INT_VEC3 => |val| set_array(i32, val.*[0..], argv, types),
+ .INT_VEC4 => |val| set_array(i32, val.*[0..], argv, types),
+ .UNSIGNED_INT_VEC2 => |val| set_array(u32, val.*[0..], argv, types),
+ .UNSIGNED_INT_VEC3 => |val| set_array(u32, val.*[0..], argv, types),
+ .UNSIGNED_INT_VEC4 => |val| set_array(u32, val.*[0..], argv, types),
+ .BOOL_VEC2 => |val| set_array(u32, val.*[0..], argv, types),
+ .BOOL_VEC3 => |val| set_array(u32, val.*[0..], argv, types),
+ .BOOL_VEC4 => |val| set_array(u32, val.*[0..], argv, types),
+ .FLOAT_MAT2 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT3 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT4 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT2x3 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT2x4 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT3x2 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT3x4 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT4x2 => |val| set_array(f32, val.*[0..], argv, types),
+ .FLOAT_MAT4x3 => |val| set_array(f32, val.*[0..], argv, types),
+ .DOUBLE_MAT2 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT3 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT4 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT2x3 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT2x4 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT3x2 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT3x4 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT4x2 => |val| set_array(f64, val.*[0..], argv, types),
+ .DOUBLE_MAT4x3 => |val| set_array(f64, val.*[0..], argv, types),
.SAMPLER_2D,
.SAMPLER_2D_SHADOW,
.INT_SAMPLER_2D,
.UNSIGNED_INT_SAMPLER_2D,
- => |val| set_texture(self.progress, self.config.project_root, val, .TEXTURE_2D, argc, argv, types),
+ => |val| set_texture(self.progress, val, .TEXTURE_2D, argv, types),
.SAMPLER_2D_ARRAY,
.SAMPLER_2D_ARRAY_SHADOW,
.INT_SAMPLER_2D_ARRAY,
.UNSIGNED_INT_SAMPLER_2D_ARRAY,
- => |val| set_texture(self.progress, self.config.project_root, val, .TEXTURE_2D_ARRAY, argc, argv, types),
+ => |val| set_texture(self.progress, val, .TEXTURE_2D_ARRAY, argv, types),
.SAMPLER_3D,
.INT_SAMPLER_3D,
.UNSIGNED_INT_SAMPLER_3D,
- => |val| set_texture(self.progress, self.config.project_root, val, .TEXTURE_3D, argc, argv, types),
+ => |val| set_texture(self.progress, val, .TEXTURE_3D, argv, types),
else => error.uniformNotSupported,
};
@@ -279,29 +256,80 @@ pub const ControlServer = struct {
uniform.setShaderValue(self.cache.shader.*);
}
- fn handle_method(
+ fn handle_shader(
+ path: [*c]const u8,
+ types: [*c]const u8,
+ argv: [*c][*c]c.lo_arg,
+ argc: c_int,
+ msg: c.lo_message,
+ userdata: ?*anyopaque,
+ ) callconv(.C) c_int {
+ const self: *ControlServer = @ptrCast(@alignCast(userdata.?));
+ const code: [*:0]const u8 = @ptrCast(&argv[0].*.s);
+
+ _ = path;
+ _ = types;
+ _ = argc;
+ _ = msg;
+
+ _ = e: {
+ self.cache.shader.loadString(std.mem.span(code)) catch |err| break :e err;
+ self.cache.refresh() catch |err| break :e err;
+ } catch |err| {
+ std.debug.print("{} while loading shader from OSC\n", .{err});
+ };
+
+ return 0;
+ }
+
+ fn handle_reload(
+ path: [*c]const u8,
+ types: [*c]const u8,
+ argv: [*c][*c]c.lo_arg,
+ argc: c_int,
+ msg: c.lo_message,
+ userdata: ?*anyopaque,
+ ) callconv(.C) c_int {
+ const self: *ControlServer = @ptrCast(@alignCast(userdata.?));
+
+ _ = path;
+ _ = types;
+ _ = argc;
+ _ = argv;
+ _ = msg;
+
+ _ = e: {
+ self.cache.shader.loadFile(self.config.fragment, 2048) catch |err| break :e err;
+ self.cache.refresh() catch |err| break :e err;
+ } catch |err| {
+ std.debug.print("{} while reloading shader from file\n", .{err});
+ };
+
+ return 0;
+ }
+
+ fn handle_uniform(
_path: [*c]const u8,
_types: [*c]const u8,
- argv: [*c][*c]c.lo_arg,
+ _argv: [*c][*c]c.lo_arg,
argc: c_int,
msg: c.lo_message,
userdata: ?*anyopaque,
) callconv(.C) c_int {
_ = msg;
- const self = @as(*ControlServer, @ptrCast(@alignCast(userdata.?)));
+ const self: *ControlServer = @ptrCast(@alignCast(userdata.?));
const path = _path[0..c.strlen(_path)];
- const types = _types[0..@as(u32, @intCast(argc))];
+ const argv: [][*c]c.lo_arg = _argv[0..@intCast(argc)];
+ const types = _types[0..@intCast(argc)];
- if (std.mem.eql(u8, path, "/-/reload")) {
- self.reload_requested = true;
- return 1;
- }
-
- self.set_uniform(path, argv, argc, types) catch |err| {
- std.debug.print("{} while processing {s}\n", .{ err, path });
+ self.set_uniform(path, argv, types) catch |err| {
+ if (err != error.notFound) {
+ std.debug.print("{} while processing {s}\n", .{ err, path });
+ }
return 1;
};
+
return 0;
}