2022-09-25 00:09:02 +02:00
|
|
|
const ext = @cImport({
|
|
|
|
@cInclude("SDL2/SDL.h");
|
|
|
|
});
|
|
|
|
|
2022-09-27 22:45:32 +02:00
|
|
|
const io = @import("./io.zig");
|
2022-09-25 00:09:02 +02:00
|
|
|
const mem = @import("./mem.zig");
|
|
|
|
const stack = @import("./stack.zig");
|
|
|
|
const std = @import("std");
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
2022-09-30 10:50:18 +02:00
|
|
|
pub const EventLoop = struct {
|
2022-09-25 00:09:02 +02:00
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
};
|
2022-09-25 00:09:02 +02:00
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
|
|
|
pub const FileAccess = opaque {
|
2022-09-25 00:09:02 +02:00
|
|
|
///
|
2022-09-30 10:50:18 +02:00
|
|
|
/// Scans the number of bytes in the file referenced by `file_access` via `event_loop`, returing
|
|
|
|
/// its byte size or a [FileError] if it failed.
|
2022-09-25 00:09:02 +02:00
|
|
|
///
|
2022-09-30 10:50:18 +02:00
|
|
|
pub fn size(file_access: *FileAccess, event_loop: *EventLoop) FileError!usize {
|
|
|
|
const origin_cursor = try app.tellFile(file_access);
|
2022-09-27 22:45:32 +02:00
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
try app.seekFile(file_access, .tail, 0);
|
2022-09-27 22:45:32 +02:00
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
const ending_cursor = try app.tellFile(file_access);
|
2022-09-27 22:45:32 +02:00
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
try app.seekFile(file_access, .head, origin_cursor);
|
2022-09-27 22:45:32 +02:00
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
return ending_cursor;
|
2022-09-25 00:09:02 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-09-27 22:45:32 +02:00
|
|
|
///
|
|
|
|
/// With files typically being backed by a block device, they can produce a variety of errors -
|
|
|
|
/// from physical to virtual errors - these are all encapsulated by the API as general
|
|
|
|
/// [Error.Inaccessible] errors.
|
|
|
|
///
|
|
|
|
pub const FileError = error {
|
|
|
|
Inaccessible,
|
|
|
|
};
|
2022-09-25 00:09:02 +02:00
|
|
|
|
|
|
|
///
|
|
|
|
/// Platform-agnostic mechanism for accessing files on any of the virtual file-systems supported by
|
|
|
|
/// Ona.
|
|
|
|
///
|
|
|
|
pub const Path = struct {
|
|
|
|
length: u16,
|
|
|
|
buffer: [max]u8,
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
2022-09-27 22:45:32 +02:00
|
|
|
pub const Error = error {
|
2022-09-25 00:09:02 +02:00
|
|
|
TooLong,
|
|
|
|
};
|
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
|
|
|
pub fn isComplete(path: Path) bool {
|
|
|
|
return (path.length != 0) and (path.buffer[0] == '/');
|
|
|
|
}
|
|
|
|
|
2022-09-25 00:09:02 +02:00
|
|
|
///
|
|
|
|
/// Returns `true` if the length of `path` is empty, otherwise `false`.
|
|
|
|
///
|
|
|
|
pub fn isEmpty(path: Path) bool {
|
|
|
|
return (path.length == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Returns `true` if `this` is equal to `that`, otherwise `false`.
|
|
|
|
///
|
|
|
|
pub fn equals(this: Path, that: Path) bool {
|
2022-09-27 22:45:32 +02:00
|
|
|
return std.mem.eql(u8, this.buffer[0 .. this.length], that.buffer[0 .. that.length]);
|
2022-09-25 00:09:02 +02:00
|
|
|
}
|
|
|
|
|
2022-09-30 10:50:18 +02:00
|
|
|
///
|
|
|
|
/// Creates and returns a [Path] value in the file system indicated by `file_system` from the
|
|
|
|
/// path components in `component_groups`.
|
|
|
|
///
|
|
|
|
pub fn from(file_system: FileSystem, component_groups: []const []const u8) Error!Path {
|
|
|
|
var path = Path{
|
|
|
|
.file_system = file_system,
|
|
|
|
.buffer = std.mem.zeroes([max]u8),
|
|
|
|
.length = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
for (component_groups) |first_component_group,
|
|
|
|
first_component_group_index| if (first_component_group.len != 0) {
|
|
|
|
|
|
|
|
var first_component_root_offset = @as(usize, 0);
|
|
|
|
|
|
|
|
if (component_group[0] == '/') {
|
|
|
|
comptime if (max < 1) unreachable;
|
|
|
|
|
|
|
|
path.buffer[path.length] = '/';
|
|
|
|
path.length += 1;
|
|
|
|
first_component_root_offset = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
var first_components = mem.Spliterator(u8){
|
|
|
|
.source = first_component_group[first_component_root_offset ..
|
|
|
|
(first_component_group.len - first_component_root_offset)],
|
|
|
|
|
|
|
|
.delimiter = "/",
|
|
|
|
};
|
|
|
|
|
|
|
|
while (first_components.next()) |component| if (component.len != 0) {
|
|
|
|
for (component) |byte| {
|
|
|
|
if (path.length == max) return error.TooLong;
|
|
|
|
|
|
|
|
path.buffer[path.length] = byte;
|
|
|
|
path.length += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path.length == max) return error.TooLong;
|
|
|
|
|
|
|
|
path.buffer[path.length] = '/';
|
|
|
|
path.length += 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
const second_component_group_index = (first_component_group_index + 1);
|
|
|
|
|
|
|
|
for (component_groups[second_component_group_index .. (component_groups.len -
|
|
|
|
second_component_group_index)]) |component_group| if (component_group.len != 0) {
|
|
|
|
|
|
|
|
var components = mem.Spliterator(u8){
|
|
|
|
.source = component_group,
|
|
|
|
.delimiter = "/",
|
|
|
|
};
|
|
|
|
|
|
|
|
while (components.next()) |component| if (component.len != 0) {
|
|
|
|
for (component) |byte| {
|
|
|
|
if (path.length == max) return error.TooLong;
|
|
|
|
|
|
|
|
path.buffer[path.length] = byte;
|
|
|
|
path.length += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path.length == max) return error.TooLong;
|
|
|
|
|
|
|
|
path.buffer[path.length] = '/';
|
|
|
|
path.length += 1;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2022-09-25 00:09:02 +02:00
|
|
|
///
|
|
|
|
/// The maximum possible byte-length of a [Path].
|
|
|
|
///
|
|
|
|
/// Note that paths are encoded using UTF-8, meaning that a character may be bigger than one
|
|
|
|
/// byte. Because of this, it is not safe to asume that a path may hold [max] individual
|
|
|
|
/// characters.
|
|
|
|
///
|
|
|
|
pub const max = 1000;
|
|
|
|
|
2022-09-27 22:45:32 +02:00
|
|
|
///
|
2022-09-25 00:09:02 +02:00
|
|
|
///
|
|
|
|
///
|
2022-09-27 22:45:32 +02:00
|
|
|
pub fn write(path: Path, writer: io.Writer) bool {
|
|
|
|
return (writer.write(path.buffer[0 .. path.length]) == path.length);
|
|
|
|
}
|
2022-09-25 00:09:02 +02:00
|
|
|
};
|
2022-09-30 10:50:18 +02:00
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
|
|
|
pub fn runGraphics(comptime ErrorUnion: anytype, run: fn (*App) ErrorUnion!void) void {
|
|
|
|
|
|
|
|
}
|