aio: update aio, add LoopWithModules

AFAIK zig lacks a way of overriding module dependencies of dependencies.
LoopWithModules lets you use aio backend with vaxis using aio and coro
modules that are not included by vaxis, when this function is used
`include_aio` is not neccessary.
This commit is contained in:
Jari Vetoniemi 2024-07-08 08:40:21 +09:00 committed by Tim Culverhouse
parent 40e51ad054
commit 56757fadcc
4 changed files with 22 additions and 11 deletions

View file

@ -23,8 +23,8 @@
.lazy = true, .lazy = true,
}, },
.aio = .{ .aio = .{
.url = "git+https://github.com/Cloudef/zig-aio#407bb416136b61087cec2c561fa4b4103a44c5b1", .url = "git+https://github.com/Cloudef/zig-aio#b5a407344379508466c5dcbe4c74438a6166e2ca",
.hash = "12202405ca6dd40f314dba6472983fcbb388118ab7446d75065b1efb982d03f515d2", .hash = "1220a55aedabdd10578d0c514719ea39ae1bc6d7ed990f508dc100db7f0ccf391437",
.lazy = true, .lazy = true,
}, },
}, },

View file

@ -29,6 +29,7 @@ fn downloadTask(allocator: std.mem.Allocator, url: []const u8) ![]const u8 {
} }
fn audioTask(allocator: std.mem.Allocator) !void { fn audioTask(allocator: std.mem.Allocator) !void {
// signals end of audio in case there's a error
errdefer coro.yield(Audio.end) catch {}; errdefer coro.yield(Audio.end) catch {};
// var child = std.process.Child.init(&.{ "aplay", "-Dplug:default", "-q", "-f", "S16_LE", "-r", "8000" }, allocator); // var child = std.process.Child.init(&.{ "aplay", "-Dplug:default", "-q", "-f", "S16_LE", "-r", "8000" }, allocator);
@ -36,14 +37,13 @@ fn audioTask(allocator: std.mem.Allocator) !void {
child.stdin_behavior = .Pipe; child.stdin_behavior = .Pipe;
child.stdout_behavior = .Ignore; child.stdout_behavior = .Ignore;
child.stderr_behavior = .Ignore; child.stderr_behavior = .Ignore;
child.spawn() catch return; // no sound try child.spawn();
defer _ = child.kill() catch {}; defer _ = child.kill() catch {};
const sound = blk: { const sound = blk: {
var tpool: coro.ThreadPool = .{}; var tpool = try coro.ThreadPool.init(allocator, .{});
try tpool.start(allocator, .{});
defer tpool.deinit(); defer tpool.deinit();
break :blk try tpool.yieldForCompletition(downloadTask, .{ allocator, "https://keroserene.net/lol/roll.s16" }); break :blk try tpool.yieldForCompletition(downloadTask, .{ allocator, "https://keroserene.net/lol/roll.s16" }, .{});
}; };
defer allocator.free(sound); defer allocator.free(sound);
@ -57,11 +57,12 @@ fn audioTask(allocator: std.mem.Allocator) !void {
} }
// the audio is already fed to the player and the defer // the audio is already fed to the player and the defer
// would kill the child stay here chilling // would kill the child, so stay here chilling
coro.yield(Audio.end) catch {}; coro.yield(Audio.end) catch {};
} }
fn videoTask(writer: std.io.AnyWriter) !void { fn videoTask(writer: std.io.AnyWriter) !void {
// signals end of video
defer coro.yield(Video.end) catch {}; defer coro.yield(Video.end) catch {};
var socket: std.posix.socket_t = undefined; var socket: std.posix.socket_t = undefined;

View file

@ -164,6 +164,7 @@ pub fn Loop(comptime T: type) type {
}; };
} }
// Use return on the self.postEvent's so it can either return error union or void
pub fn handleEventGeneric(self: anytype, vx: *Vaxis, cache: *GraphemeCache, Event: type, event: anytype, paste_allocator: ?std.mem.Allocator) !void { pub fn handleEventGeneric(self: anytype, vx: *Vaxis, cache: *GraphemeCache, Event: type, event: anytype, paste_allocator: ?std.mem.Allocator) !void {
switch (builtin.os.tag) { switch (builtin.os.tag) {
.windows => { .windows => {
@ -298,7 +299,7 @@ pub fn handleEventGeneric(self: anytype, vx: *Vaxis, cache: *GraphemeCache, Even
.winsize => |winsize| { .winsize => |winsize| {
vx.state.in_band_resize = true; vx.state.in_band_resize = true;
if (@hasField(Event, "winsize")) { if (@hasField(Event, "winsize")) {
self.postEvent(.{ .winsize = winsize }); return self.postEvent(.{ .winsize = winsize });
} }
}, },
} }

View file

@ -1,16 +1,25 @@
const build_options = @import("build_options");
const builtin = @import("builtin"); const builtin = @import("builtin");
const std = @import("std"); const std = @import("std");
const aio = @import("aio");
const coro = @import("coro");
const vaxis = @import("main.zig"); const vaxis = @import("main.zig");
const handleEventGeneric = @import("Loop.zig").handleEventGeneric; const handleEventGeneric = @import("Loop.zig").handleEventGeneric;
const log = std.log.scoped(.vaxis_aio); const log = std.log.scoped(.vaxis_aio);
const Yield = enum { no_state, took_event }; const Yield = enum { no_state, took_event };
pub fn Loop(T: type) type {
if (!build_options.aio) {
@compileError(
\\build_options.aio is not enabled.
\\Use `LoopWithModules` instead to provide `aio` and `coro` modules from outside vaxis.
);
}
return LoopWithModules(T, @import("aio"), @import("coro"));
}
/// zig-aio based event loop /// zig-aio based event loop
/// <https://github.com/Cloudef/zig-aio> /// <https://github.com/Cloudef/zig-aio>
pub fn Loop(comptime T: type) type { pub fn LoopWithModules(T: type, aio: type, coro: type) type {
return struct { return struct {
const Event = T; const Event = T;