aboutsummaryrefslogtreecommitdiffstats
path: root/src/control.zig
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-10-19 14:38:49 +0000
committers-ol <s+removethis@s-ol.nu>2025-10-19 14:38:49 +0000
commitbc1e00a5e28cc198981cb59ffe9164b0c62175d1 (patch)
tree31d89ee2c7e363281ed67f770ac2f8760df8c029 /src/control.zig
parentadd toggleable crop mode (diff)
downloadglsl-view-bc1e00a5e28cc198981cb59ffe9164b0c62175d1.tar.gz
glsl-view-bc1e00a5e28cc198981cb59ffe9164b0c62175d1.zip
add BufferedStreamSource
Diffstat (limited to 'src/control.zig')
-rw-r--r--src/control.zig69
1 files changed, 58 insertions, 11 deletions
diff --git a/src/control.zig b/src/control.zig
index f547a4b..4a29309 100644
--- a/src/control.zig
+++ b/src/control.zig
@@ -6,7 +6,14 @@ const cfg = @import("config.zig");
const util = @import("util.zig");
const build_config = @import("build_config");
-fn verify_args(expected: u8, got: []const u8) !void {
+fn verify_args(expected: []const u8, got: []const u8) !void {
+ if (!std.mem.eql(u8, expected, got)) {
+ std.debug.print("expected '{s}' but got {s}\n", .{ expected, got });
+ return error.typeMismatch;
+ }
+}
+
+fn verify_args_all(expected: u8, got: []const u8) !void {
for (got) |typ| {
if (typ != expected) {
std.debug.print("expected '{c}' but got '{c}' element (args are {s})\n", .{ expected, typ, got });
@@ -26,19 +33,19 @@ fn set_one(
switch (T) {
f32 => {
- try verify_args('f', types);
+ try verify_args_all('f', types);
dest.* = argv[0].*.f;
},
f64 => {
- try verify_args('d', types);
+ try verify_args_all('d', types);
dest.* = argv[0].*.d;
},
i32 => {
- try verify_args('d', types);
+ try verify_args_all('d', types);
dest.* = argv[0].*.i;
},
u32 => {
- try verify_args('d', types);
+ try verify_args_all('d', types);
const val = argv[0].*.i;
if (val < 0)
return error.signDisallowed;
@@ -66,22 +73,22 @@ fn set_array(
switch (T) {
f32 => {
- try verify_args('f', types);
+ try verify_args_all('f', types);
for (dest, 0..) |*v, i|
v.* = argv[i].*.f;
},
f64 => {
- try verify_args('d', types);
+ try verify_args_all('d', types);
for (dest, 0..) |*v, i|
v.* = argv[i].*.d;
},
i32 => {
- try verify_args('i', types);
+ try verify_args_all('i', types);
for (dest, 0..) |*v, i|
v.* = argv[i].*.i;
},
u32 => {
- try verify_args('i', types);
+ try verify_args_all('i', types);
for (dest, 0..) |*v, i| {
const val = argv[i].*.i;
if (val < 0)
@@ -136,6 +143,7 @@ pub const ControlServer = struct {
if (build_config.have_ffmpeg) {
try self.add_method(&.{ "/source", "*", "video" }, null, handle_texture_video);
try self.add_method(&.{ "/source", "*", "stream" }, null, handle_texture_stream);
+ try self.add_method(&.{ "/source", "*", "buffered-stream" }, null, handle_texture_buffered_stream);
}
if (build_config.have_tsv) {
try self.add_method(&.{ "/source", "*", "tsv" }, "ss", handle_texture_tsv);
@@ -274,6 +282,22 @@ pub const ControlServer = struct {
}
}
+ if (std.mem.eql(u8, types, "s")) {
+ const param_stringZ: [*:0]const u8 = @ptrCast(&argv[0].*.s);
+ const param_string = std.mem.span(param_stringZ);
+ if (std.mem.startsWith(u8, param_string, "/source/")) {
+ var param_parts = std.mem.tokenizeScalar(u8, param_string, '/');
+ _ = param_parts.next(); // skip /source
+ const source_name = param_parts.next().?;
+ const param_name = param_parts.next().?;
+
+ const source = self.sources.get(source_name) orelse return error.texNotFound;
+ try source.updateUniform(param_name, value);
+ uniform.setShaderValue(self.cache.shader.*);
+ return true;
+ }
+ }
+
try switch (value) {
.FLOAT => |val| set_one(f32, val, argv, types),
.DOUBLE => |val| set_one(f64, val, argv, types),
@@ -347,7 +371,7 @@ pub const ControlServer = struct {
}
fn handle_texture_video(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool {
- try verify_args('s', types);
+ try verify_args_all('s', types);
var parts = std.mem.tokenizeScalar(u8, path, '/');
_ = parts.next();
@@ -368,7 +392,7 @@ pub const ControlServer = struct {
}
fn handle_texture_stream(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool {
- try verify_args('s', types);
+ try verify_args_all('s', types);
var parts = std.mem.tokenizeScalar(u8, path, '/');
_ = parts.next();
@@ -389,6 +413,29 @@ pub const ControlServer = struct {
return true;
}
+ fn handle_texture_buffered_stream(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool {
+ try verify_args("sis", types[0..3]);
+ try verify_args_all('s', types[3..]);
+
+ var parts = std.mem.tokenizeScalar(u8, path, '/');
+ _ = parts.next();
+ const name = parts.next() orelse unreachable;
+ if (self.sources.contains(name)) return error.textureNameTaken;
+
+ const texture_typeZ: [*:0]const u8 = @ptrCast(&argv[0].*.s);
+ const texture_type = std.meta.stringToEnum(gl.Texture.Type, std.mem.span(texture_typeZ)) orelse return error.invalidType;
+ const depth: i32 = argv[1].*.i;
+ const filenameZ: [*:0]const u8 = @ptrCast(&argv[2].*.s);
+ const formatZ: ?[*:0]const u8 = if (argv.len > 3) @ptrCast(&argv[3].*.s) else null;
+ const args = if (argv.len > 4) argv[4..] else &.{};
+
+ const ffmpeg = @import("ffmpeg.zig");
+ const source = try ffmpeg.BufferedStreamSource.init(self.cache.allocator, self.constants, texture_type, depth, filenameZ, formatZ, args);
+ try self.add_source(name, source);
+
+ return true;
+ }
+
fn handle_texture_tsv(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool {
_ = types;