From 49557f32bc47075f12a0fde4ff2630850820be2f Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:01:31 +0100 Subject: [PATCH 1/9] Change drone CI script to test via zig build --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 0760faa..c995378 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,4 +5,4 @@ steps: - name: build & test image: euantorano/zig:0.9.1 commands: - - zig test src/main.zig + - zig build test From af1976b69cb73758afcdc1df15f2572d5c8cbf5b Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:32:16 +0100 Subject: [PATCH 2/9] Fix compilation errors --- src/main.zig | 2 +- src/sys.zig | 100 ++++++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/main.zig b/src/main.zig index 1d1152a..35e7637 100644 --- a/src/main.zig +++ b/src/main.zig @@ -38,7 +38,7 @@ fn run(event_loop: *sys.EventLoop, graphics: *sys.GraphicsContext) anyerror!void if ((try event_loop.readFile(file_access, buffer)) != file_size) return error.ScriptLoadFailure; - event_loop.log(buffer); + event_loop.log(.debug, buffer); } while (graphics.poll()) |_| { diff --git a/src/sys.zig b/src/sys.zig index f6016ef..6962431 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -8,7 +8,7 @@ const stack = @import("./stack.zig"); const std = @import("std"); /// -/// +/// A thread-safe platform abstraction over multiplexing system I/O processing and event handling. /// pub const EventLoop = opaque { /// @@ -23,7 +23,7 @@ pub const EventLoop = opaque { exit, close: struct { - file_system_path: *FileAccess, + file_access: *FileAccess, }, log: struct { @@ -33,7 +33,7 @@ pub const EventLoop = opaque { open: struct { mode: OpenMode, - path: *const FileSystem.Path, + file_system_path: *const FileSystem.Path, result: OpenError!*FileAccess = error.NotFound, }, @@ -138,13 +138,15 @@ pub const EventLoop = opaque { /// /// Closes access to the file referenced by `file_access` via `event_loop`. /// + /// *Note* that nothing happens to `file_access` if it is already closed. + /// pub fn close(event_loop: *EventLoop, file_access: *FileAccess) void { - var message = FileSystemMessage{ + var file_system_message = FileSystemMessage{ .frame = @frame(), .request = .{.close = .{.file_access = file_access}}, }; - suspend event_loop.enqueueFileSystemMessage(&message); + suspend event_loop.enqueueFileSystemMessage(&file_system_message); } /// @@ -174,7 +176,7 @@ pub const EventLoop = opaque { /// *Note* that `message` is not guaranteed to be partly, wholely, or at all written. /// pub fn log(event_loop: *EventLoop, kind: LogKind, message: []const u8) void { - var message = FileSystemMessage{ + var file_system_message = FileSystemMessage{ .frame = @frame(), .request = .{.log = .{ @@ -183,7 +185,7 @@ pub const EventLoop = opaque { }}, }; - suspend event_loop.enqueueFileSystemMessage(&message); + suspend event_loop.enqueueFileSystemMessage(&file_system_message); } /// @@ -199,24 +201,26 @@ pub const EventLoop = opaque { pub fn open(event_loop: *EventLoop, mode: OpenMode, file_system_path: FileSystem.Path) OpenError!*FileAccess { - var message = FileSystemMessage{ + var file_system_message = FileSystemMessage{ .frame = @frame(), - .request = .{ - .open = .{ - .mode = mode, - .file_system_path = &file_system_path, - }, - }, + .request = .{.open = .{ + .mode = mode, + .file_system_path = &file_system_path, + }}, }; - suspend event_loop.enqueueFileSystemMessage(&message); + suspend event_loop.enqueueFileSystemMessage(&file_system_message); - return message.request.open.result; + return file_system_message.request.open.result; } /// + /// [FileSystemMessage] processing function used by a dedicated worker thread, where `data` is + /// a type-erased reference to a [EventLoop]. /// + /// The processor returns `0` if it exited normally or any other value if an erroneous exit + /// occured. /// fn processFileSystemMessages(data: ?*anyopaque) callconv(.C) c_int { const implementation = Implementation.cast(@ptrCast(*EventLoop, data orelse unreachable)); @@ -266,20 +270,23 @@ pub const EventLoop = opaque { }, .close => |*close_request| { - // Don't care if this doesn't work. + // TODO: Use this result somehow. _ = ext.SDL_RWclose(@ptrCast(*ext.SDL_RWops, @alignCast( @alignOf(ext.SDL_RWops), close_request.file_access))); }, .read_file => |read_request| { + // TODO: Implement. _ = read_request; }, .seek_file => |seek_request| { + // TODO: Implement. _ = seek_request; }, .tell_file => |tell_request| { + // TODO: Implement. _ = tell_request; }, } @@ -304,29 +311,45 @@ pub const EventLoop = opaque { pub fn readFile(event_loop: *EventLoop, file_access: *FileAccess, buffer: []const u8) FileError!usize { - var message = FileSystemMessage{ + var file_system_message = FileSystemMessage{ .frame = @frame(), - .request = .{ - .read_file = .{ - .file_access = file_access, - .buffer = buffer, - }, - }, + .request = .{.read_file = .{ + .file_access = file_access, + .buffer = buffer, + }}, }; - suspend event_loop.enqueueFileSystemMessage(&message); + suspend event_loop.enqueueFileSystemMessage(&file_system_message); - return message.request.read_file.result; + return file_system_message.request.read_file.result; } /// + /// Attempts to tell the current file cursor position for the file referenced by `file_access`. /// + /// Returns the number of bytes into the file that the cursor is relative to its beginning or a + /// [FileError] if the file failed to be queried. + /// + pub fn queryFile(event_loop: *EventLoop, file_access: *FileAccess) FileError!usize { + var file_system_message = FileSystemMessage{ + .frame = @frame(), + .request = .{.tell_file = .{.file_access = file_access}}, + }; + + suspend event_loop.enqueueFileSystemMessage(&file_system_message); + + return file_system_message.request.tell_file.result; + } + + /// + /// Attempts to seek the file cursor through the file referenced by `file_access` from `origin` + /// to `offset` via `event_loop`, returning a [FileError] if the file failed to be sought. /// pub fn seekFile(event_loop: *EventLoop, file_access: *FileAccess, origin: SeekOrigin, offset: usize) FileError!void { - var message = FileSystemMessage{ + var file_system_message = FileSystemMessage{ .frame = @frame(), .request = .{ @@ -338,23 +361,9 @@ pub const EventLoop = opaque { }, }; - suspend event_loop.enqueueFileSystemMessage(&message); + suspend event_loop.enqueueFileSystemMessage(&file_system_message); - return message.request.seek_file.result; - } - - /// - /// - /// - pub fn tellFile(event_loop: *EventLoop, file_access: *FileAccess) FileError!usize { - var message = FileSystemMessage{ - .frame = @frame(), - .request = .{.tell_file = .{.file_access = file_access}}, - }; - - suspend event_loop.enqueueFileSystemMessage(&message); - - return message.request.tell_file.result; + return file_system_message.request.seek_file.result; } }; @@ -391,14 +400,15 @@ pub const FileError = error { }; /// -/// +/// Platform-agnostic mechanism for working with an abstraction of the underlying file-system(s) +/// available to the application in a sandboxed environment. /// pub const FileSystem = enum { data, user, /// - /// Platform-agnostic mechanism for referencing files and directories on a [FileSystem] + /// Platform-agnostic mechanism for referencing files and directories on a [FileSystem]. /// pub const Path = struct { file_system: FileSystem, From 774536fd5855e353227babc1e4a84bd045e44bd2 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:45:22 +0100 Subject: [PATCH 3/9] Update references to old tellFile function --- src/sys.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sys.zig b/src/sys.zig index 6962431..b880fef 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -377,11 +377,11 @@ pub const FileAccess = opaque { /// pub fn size(file_access: *FileAccess, event_loop: *EventLoop) FileError!usize { // Save cursor to return to it later. - const origin_cursor = try event_loop.tellFile(file_access); + const origin_cursor = try event_loop.queryFile(file_access); try event_loop.seekFile(file_access, .tail, 0); - const ending_cursor = try event_loop.tellFile(file_access); + const ending_cursor = try event_loop.queryFile(file_access); // Return to original cursor. try event_loop.seekFile(file_access, .head, origin_cursor); From e01b19cd680fb59470025cbc3baad7adf2c5f5c6 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:50:28 +0100 Subject: [PATCH 4/9] Fix compilation errors in I/O module --- src/io.zig | 75 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/src/io.zig b/src/io.zig index 88e1caa..58a3c38 100644 --- a/src/io.zig +++ b/src/io.zig @@ -10,7 +10,7 @@ pub const Writer = struct { writeContext: fn (*anyopaque, []const u8) usize, /// - /// + /// Radices supported by [writeInt]. /// pub const Radix = enum { binary, @@ -79,39 +79,45 @@ pub const Writer = struct { const Int = @TypeOf(value); const type_info = @typeInfo(Int); - if (type_info != .Int) @compileError("value must be of type int"); + switch (type_info) { + .Int => { + if (value == 0) return writer.writeByte('0'); - if (value == 0) return writer.writeByte('0'); + // TODO: Unhardcode this as it will break with large ints. + var buffer = std.mem.zeroes([28]u8); + var buffer_count = @as(usize, 0); + var n1 = value; - // TODO: Unhardcode this as it will break with large ints. - var buffer = std.mem.zeroes([28]u8); - var buffer_count = @as(usize, 0); - var n1 = value; + if ((type_info.Int.signedness == .signed) and (value < 0)) { + // Negative value. + n1 = -value; + buffer[0] = '-'; + buffer_count += 1; + } - if ((type_info.Int.signedness == .signed) and (value < 0)) { - // Negative value. - n1 = -value; - buffer[0] = '-'; - buffer_count += 1; + while (n1 != 0) { + const base = @enumToInt(radix); + + buffer[buffer_count] = @intCast(u8, (n1 % base) + '0'); + n1 = (n1 / base); + buffer_count += 1; + } + + for (buffer[0 .. (buffer_count / 2)]) |_, i| + std.mem.swap(u8, &buffer[i], &buffer[buffer_count - i - 1]); + + return (writer.write(buffer[0 .. buffer_count]) == buffer_count); + }, + + // Cast comptime int into known-size integer and try again. + .ComptimeInt => return writer. + writeInt(radix, @intCast(std.math.IntFittingRange(value, value), value)), + + else => @compileError("value must be of type int"), } - - while (n1 != 0) { - const base = @enumToInt(radix); - - buffer[buffer_count] = @intCast(u8, (n1 % base) + '0'); - n1 = (n1 / base); - buffer_count += 1; - } - - for (buffer[0 .. (buffer_count / 2)]) |_, i| - std.mem.swap(u8, &buffer[i], &buffer[buffer_count - i - 1]); - - return (writer.write(buffer[0 .. buffer_count]) == buffer_count); } }; -var null_context = @as(usize, 0); - /// /// Writer that silently throws consumed data away and never fails. /// @@ -119,13 +125,10 @@ var null_context = @as(usize, 0); /// sent somewhere for whatever reason. /// pub const null_writer = Writer{ - .context = (&null_context), - - .operation = struct { - fn write(context: *anyopaque, buffer: []const u8) usize { - // Validate context canary value. - std.debug.assert(@ptrCast(*usize, @alignCast(@alignOf(usize), context)).* == 0); + .context = undefined, + .writeContext = struct { + fn write(_: *anyopaque, buffer: []const u8) usize { return buffer.len; } }.write, @@ -137,9 +140,9 @@ test { { const sequence = "foo"; - testing.expectEqual(null_writer.write(sequence), sequence.len); + try testing.expectEqual(null_writer.write(sequence), sequence.len); } - testing.expect(null_writer.writeByte(0)); - testing.expect(null_writer.writeInt(.decimal, 420)); + try testing.expect(null_writer.writeByte(0)); + try testing.expect(null_writer.writeInt(.decimal, 420)); } From a36b3bc3216f170025d5b6ee7b468ce43127d19f Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:58:33 +0100 Subject: [PATCH 5/9] Fix inconsistent test naming --- src/stack.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stack.zig b/src/stack.zig index 4f3b6b3..3f8284a 100755 --- a/src/stack.zig +++ b/src/stack.zig @@ -91,7 +91,7 @@ pub const FixedPushError = error { Overflow, }; -test "fixed stack" { +test { const testing = std.testing; var buffer = std.mem.zeroes([4]u8); var stack = Fixed(u8){.buffer = &buffer}; From c4775e27d83b67746d1ad70cfdd5d68245b344bc Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:58:38 +0100 Subject: [PATCH 6/9] Fix tests not running. --- src/main.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.zig b/src/main.zig index 35e7637..4108ff8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -15,7 +15,10 @@ pub fn main() anyerror!void { } test { - + _ = io; + _ = stack; + _ = std; + _ = sys; } fn run(event_loop: *sys.EventLoop, graphics: *sys.GraphicsContext) anyerror!void { From 074a62807b41983325bcd507e4b77b2763906117 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 22:58:58 +0100 Subject: [PATCH 7/9] Fix CI not running tests after building them --- .drone.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.drone.yml b/.drone.yml index c995378..1c0eedd 100644 --- a/.drone.yml +++ b/.drone.yml @@ -6,3 +6,4 @@ steps: image: euantorano/zig:0.9.1 commands: - zig build test + - ./zig-cache/o/b57ef32c79a05339fbe4a8eb648ff6df/test main.zig From c91630d6da62adae7cc7159191745e7637ba7bd9 Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 23:04:57 +0100 Subject: [PATCH 8/9] Run test binary over manually invoking zig test in VS Code settings --- .vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2a24dae..016ab6a 100755 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -44,7 +44,7 @@ { "label": "Test", "type": "shell", - "command": "zig test src/main.zig", + "command": "$(find zig-cache -name test) src/main.zig", "group": { "kind": "test", "isDefault": true From 37bd0f10ac29679f5a1e319a3c3cc236db745e3b Mon Sep 17 00:00:00 2001 From: kayomn Date: Mon, 3 Oct 2022 23:05:43 +0100 Subject: [PATCH 9/9] Fix CI being unable to find test --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 1c0eedd..f9941e1 100644 --- a/.drone.yml +++ b/.drone.yml @@ -6,4 +6,4 @@ steps: image: euantorano/zig:0.9.1 commands: - zig build test - - ./zig-cache/o/b57ef32c79a05339fbe4a8eb648ff6df/test main.zig + - $(find zig-cache -name test) main.zig