1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
const std = @import("std");
const c = @import("c.zig");
const gl = @import("gl.zig");
const ctrl = @import("control.zig");
const util = @import("util.zig");
pub const Source = struct {
texture: gl.Texture,
deinit_fn: *const fn (self: *Source, allocator: std.mem.Allocator) void,
register_fn: ?*const fn (self: *Source, name: []const u8, control: *ctrl.ControlServer) void = null,
unregister_fn: ?*const fn (self: *Source, name: []const u8, control: *ctrl.ControlServer) void = null,
pub fn deinit(self: *Source, allocator: std.mem.Allocator) void {
self.deinit_fn(self, allocator);
}
pub fn register(self: *Source, name: []const u8, control: *ctrl.ControlServer) void {
if (self.register_fn) |register_fn| {
register_fn(self, name, control);
}
}
pub fn unregister(self: *Source, name: []const u8, control: *ctrl.ControlServer) void {
if (self.unregister_fn) |unregister_fn| {
unregister_fn(self, name, control);
}
}
};
pub const StreamFlags = struct {
freeze: bool = false,
step: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
pub fn register(self: *StreamFlags, name: []const u8, control: *ctrl.ControlServer) void {
control.add_method_for(StreamFlags, self, &.{ "/source", name, "freeze" }, "T", handle_freeze) catch unreachable;
control.add_method_for(StreamFlags, self, &.{ "/source", name, "freeze" }, "F", handle_freeze) catch unreachable;
control.add_method_for(StreamFlags, self, &.{ "/source", name, "step" }, "I", handle_step) catch unreachable;
control.add_method_for(StreamFlags, self, &.{ "/source", name, "step" }, "", handle_step) catch unreachable;
}
pub fn unregister(self: *const StreamFlags, name: []const u8, control: *ctrl.ControlServer) void {
_ = self;
control.del_method(&.{ "/source", name, "freeze" }, "T") catch unreachable;
control.del_method(&.{ "/source", name, "freeze" }, "F") catch unreachable;
control.del_method(&.{ "/source", name, "step" }, "") catch unreachable;
}
pub fn shouldStep(self: *StreamFlags) bool {
const step = !self.freeze or self.step.load(.acquire);
if (step) self.step.store(false, .release);
return step;
}
fn handle_freeze(self: *StreamFlags, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool {
_ = path;
_ = argv;
self.freeze = types[0] == 'T';
return true;
}
fn handle_step(self: *StreamFlags, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool {
_ = path;
_ = types;
_ = argv;
self.step.store(true, .monotonic);
return true;
}
};
|