Refactor codebase
continuous-integration/drone/pr Build is failing Details
continuous-integration/drone/push Build is failing Details

This commit is contained in:
kayomn 2022-10-17 10:34:04 +01:00
parent 3d3d0e488a
commit 489ece4b7b
10 changed files with 198 additions and 143 deletions

View File

@ -1,21 +1,28 @@
const std = @import("std");
///
/// Builds the engine, tools, and dependencies of all.
///
pub fn build(builder: *std.build.Builder) void {
const target = builder.standardTargetOptions(.{});
const mode = builder.standardReleaseOptions();
const ona_pkg = projectPkg("ona", &.{});
// Ona executable.
// Engine executable.
{
const ona_exe = builder.addExecutable("ona", "./src/main.zig");
const engine_exe = builder.addExecutable("ona", "./src/engine/main.zig");
const oar_pkg = projectPkg("oar", &.{ona_pkg});
ona_exe.setTarget(target);
ona_exe.setBuildMode(mode);
ona_exe.install();
ona_exe.addIncludeDir("./ext");
ona_exe.linkSystemLibrary("SDL2");
ona_exe.linkLibC();
engine_exe.addPackage(oar_pkg);
engine_exe.addPackage(ona_pkg);
engine_exe.setTarget(target);
engine_exe.setBuildMode(mode);
engine_exe.install();
engine_exe.addIncludeDir("./ext");
engine_exe.linkSystemLibrary("SDL2");
engine_exe.linkLibC();
const run_cmd = ona_exe.run();
const run_cmd = engine_exe.run();
run_cmd.step.dependOn(builder.getInstallStep());
@ -24,6 +31,11 @@ pub fn build(builder: *std.build.Builder) void {
builder.step("run", "Run Ona application").dependOn(&run_cmd.step);
}
// Oar executable.
{
}
// Ona tests.
{
const ona_tests = builder.addTestExe("test", "./src/main.zig");
@ -33,3 +45,15 @@ pub fn build(builder: *std.build.Builder) void {
builder.step("test", "Run Ona unit tests").dependOn(&ona_tests.step);
}
}
///
/// Returns a [std.build.Pkg] within the project codebase path at `name` with `dependencies` as its
/// dependencies.
///
fn projectPkg(comptime name: []const u8, dependencies: []const std.build.Pkg) std.build.Pkg {
return std.build.Pkg{
.name = name,
.path = .{.path = "./src/" ++ name ++ "/main.zig"},
.dependencies = dependencies,
};
}

View File

@ -1,9 +1,4 @@
const ext = @cImport({
@cInclude("SDL2/SDL.h");
});
const io = @import("./io.zig");
const stack = @import("./stack.zig");
const ona = @import("ona");
const std = @import("std");
const sys = @import("./sys.zig");
@ -14,13 +9,6 @@ pub fn main() anyerror!void {
return nosuspend await async sys.runGraphics(anyerror, run);
}
test {
_ = io;
_ = stack;
_ = std;
_ = sys;
}
fn run(app: *sys.AppContext, graphics: *sys.GraphicsContext) anyerror!void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@ -37,8 +25,7 @@ fn run(app: *sys.AppContext, graphics: *sys.GraphicsContext) anyerror!void {
defer allocator.free(buffer);
if ((try file_access.read(buffer)) != file_size)
return error.ScriptLoadFailure;
if ((try file_access.read(buffer)) != file_size) return error.ScriptLoadFailure;
sys.Log.debug.write(buffer);
}
@ -47,3 +34,7 @@ fn run(app: *sys.AppContext, graphics: *sys.GraphicsContext) anyerror!void {
graphics.present();
}
}
test {
_ = sys;
}

View File

@ -2,11 +2,8 @@ const ext = @cImport({
@cInclude("SDL2/SDL.h");
});
const io = @import("./io.zig");
const mem = @import("./mem.zig");
const meta = @import("./meta.zig");
const oar = @import("./oar.zig");
const stack = @import("./stack.zig");
const oar = @import("oar");
const ona = @import("ona");
const std = @import("std");
///
@ -131,12 +128,14 @@ pub const AppContext = opaque {
}
///
/// Initializes a new [Implemenation] with `data_access` as the data archive to read from
/// and `user_path_prefix` as the native writable user data directory.
/// Initializes a new [Implemenation] with `data_archive_file_access` as the data archive to
/// read from and `user_path_prefix` as the native writable user data directory.
///
/// Returns the created [Implementation] value on success or [InitError] on failure.
///
fn init(allocator: std.mem.Allocator, data_access: FileAccess) InitError!Implementation {
fn init(allocator: std.mem.Allocator,
data_archive_file_access: ona.io.FileAccess) InitError!Implementation {
const user_path_prefix = ext.SDL_GetPrefPath("ona", "ona") orelse
return error.OutOfMemory;
@ -149,7 +148,7 @@ pub const AppContext = opaque {
.user_path_prefix = user_path_prefix,
.data_file_system = .{.archive = .{
.instance = try oar.Archive.init(allocator, data_access),
.instance = try oar.Archive.init(allocator, data_archive_file_access),
}},
.message_thread = null,
@ -223,12 +222,12 @@ pub const AppContext = opaque {
///
///
pub fn schedule(app_context: *AppContext, procedure: anytype,
arguments: anytype) meta.FnReturn(@TypeOf(procedure)) {
arguments: anytype) ona.meta.FnReturn(@TypeOf(procedure)) {
const Task = struct {
procedure: @TypeOf(procedure),
arguments: *@TypeOf(arguments),
result: meta.FnReturn(@TypeOf(procedure)),
result: ona.meta.FnReturn(@TypeOf(procedure)),
const Task = @This();
@ -263,102 +262,6 @@ pub const AppContext = opaque {
}
};
///
/// File-system agnostic abstraction for manipulating a file.
///
pub const FileAccess = struct {
context: *anyopaque,
implementation: *const Implementation,
///
/// Provides a set of implementation-specific behaviors to a [FileAccess] instance.
///
pub const Implementation = struct {
close: fn (*anyopaque) void,
queryCursor: fn (*anyopaque) Error!u64,
queryLength: fn (*anyopaque) Error!u64,
read: fn (*anyopaque, []u8) Error!usize,
seek: fn (*anyopaque, u64) Error!void,
seekToEnd: fn (*anyopaque) Error!void,
skip: fn (*anyopaque, i64) Error!void,
};
///
/// [Error.FileInaccessible] is a generic catch-all for a [FileAccess] reference no longer
/// pointing to a file or the file becomming invalid for whatever reason.
///
pub const Error = error {
FileInaccessible,
};
///
/// Close the file referenced by `file_access` on the main thread, invalidating the reference to
/// it and releasing any associated resources.
///
/// Freeing an invalid `file_access` has no effect on the file and logs a warning over the
/// wasted effort.
///
pub fn close(file_access: *FileAccess) void {
return file_access.implementation.close(file_access.context);
}
///
/// Attempts to query the current 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
/// [Error] on failure.
///
pub fn queryCursor(file_access: *FileAccess) Error!u64 {
return file_access.implementation.queryCursor(file_access.context);
}
///
/// Attempts to query the current length for the file referenced by `file_access`.
///
/// Returns the current length of the file at the time of the operation or a [Error] if the file
/// failed to be queried.
///
pub fn queryLength(file_access: *FileAccess) Error!u64 {
return file_access.implementation.queryLength(file_access.context);
}
///
/// Attempts to read `file_access` from the its current position into `buffer`.
///
/// Returns the number of bytes that were available to be read, otherwise an [Error] on failure.
///
pub fn read(file_access: *FileAccess, buffer: []u8) Error!usize {
return file_access.implementation.read(file_access.context, buffer);
}
///
/// Attempts to seek `file_access` from the beginning of the file to `cursor` bytes.
///
/// Returns [Error] on failure.
///
pub fn seek(file_access: *FileAccess, cursor: u64) Error!void {
return file_access.implementation.seek(file_access.context, cursor);
}
///
/// Attempts to seek `file_access` to the end of the file.
///
/// Returns [Error] on failure.
///
pub fn seekToEnd(file_access: *FileAccess) Error!void {
return file_access.implementation.seekToEnd(file_access.context);
}
///
/// Attempts to seek `file_access` by `offset` from the current file position.
///
/// Returns [Error] on failure;
///
pub fn skip(file_access: *FileAccess, offset: i64) Error!void {
return file_access.implementation.skip(file_access.context, offset);
}
};
///
/// Platform-agnostic mechanism for working with an abstraction of the underlying file-system(s)
/// available to the application in a sandboxed environment.
@ -447,11 +350,13 @@ pub const FileSystem = union(enum) {
/// Returns a [FileAccess] reference that provides access to the file referenced by `path`
/// or a [OpenError] if it failed.
///
pub fn open(path: Path, mode: OpenMode) OpenError!FileAccess {
pub fn open(path: Path, mode: OpenMode) OpenError!ona.io.FileAccess {
switch (path.file_system.*) {
.archive => |*archive| {
if (mode != .readonly) return error.ModeUnsupported;
const FileAccess = ona.io.FileAccess;
for (archive.entry_table) |*entry| if (entry.owner == null) {
const Implementation = struct {
fn close(context: *anyopaque) void {
@ -567,6 +472,8 @@ pub const FileSystem = union(enum) {
ext.SDL_ClearError();
const FileAccess = ona.io.FileAccess;
const Implementation = struct {
fn rwOpsCast(context: *anyopaque) *ext.SDL_RWops {
return @ptrCast(*ext.SDL_RWops, @alignCast(
@ -693,7 +600,7 @@ pub const FileSystem = union(enum) {
const last_sequence_index = sequences.len - 1;
for (sequences) |sequence, index| if (sequence.len != 0) {
var components = mem.Spliterator(u8){
var components = ona.mem.Spliterator(u8){
.source = sequence,
.delimiter = "/",
};

View File

@ -1,18 +1,17 @@
const ona = @import("ona");
const std = @import("std");
const sys = @import("./sys.zig");
const table = @import("./table.zig");
///
/// Thin file-wrapper and in-memory layout cache of an OAR archive file.
///
pub const Archive = struct {
file_access: sys.FileAccess,
file_access: ona.io.FileAccess,
index_cache: IndexCache,
///
/// [OpenError.EntryNotFound] happens when an entry could not be found.
///
pub const FindError = sys.FileAccess.Error || error {
pub const FindError = ona.io.FileAccess.Error || error {
EntryNotFound,
};
@ -27,7 +26,7 @@ pub const Archive = struct {
/// As the archive is queried via [find], the cache is lazily assembled with the absolute
/// offsets of each queried file.
///
const IndexCache = table.Hashed([]const u8, u64, table.string_context);
const IndexCache = ona.table.Hashed([]const u8, u64, ona.table.string_context);
///
/// Deinitializes the index cache of `archive`, freeing all associated memory.
@ -49,6 +48,7 @@ pub const Archive = struct {
.header = find_header: {
var header = Entry.Header{
.revision = 0,
.path = Path.empty,
.file_size = 0,
.absolute_offset = 0
};
@ -73,7 +73,7 @@ pub const Archive = struct {
// Read first entry.
while ((try archive.file_access.read(mem.asBytes(&header))) == header_size) {
if (mem.eql(u8, entry_path, header.name_buffer[0 .. header.name_length])) {
if (mem.eql(u8, entry_path, header.path.buffer[0 .. header.path.length])) {
// If caching fails... oh well...
archive.index_cache.insert(entry_path, header.absolute_offset) catch {};
@ -110,7 +110,7 @@ pub const Archive = struct {
/// **Note** that `archive_file_access` does nothing to manage the lifetime of the open file.
///
pub fn init(cache_allocator: std.mem.Allocator,
archive_file_access: sys.FileAccess) InitError!Archive {
archive_file_access: ona.io.FileAccess) InitError!Archive {
return Archive{
.index_cache = try IndexCache.init(cache_allocator),
@ -123,7 +123,7 @@ pub const Archive = struct {
/// Handles the state of an opened archive entry.
///
pub const Entry = struct {
owner: ?*sys.FileAccess,
owner: ?*ona.io.FileAccess,
cursor: u64,
header: Header,
@ -135,8 +135,7 @@ pub const Entry = struct {
pub const Header = extern struct {
signature: [signature_magic.len]u8 = signature_magic,
revision: u8,
name_buffer: [255]u8 = std.mem.zeroes([255]u8),
name_length: u8 = 0,
path: Path,
file_size: u64,
absolute_offset: u64,
padding: [232]u8 = std.mem.zeroes([232]u8),
@ -155,3 +154,16 @@ pub const Entry = struct {
pub const signature_magic = [3]u8{'o', 'a', 'r'};
};
};
///
///
///
pub const Path = extern struct {
buffer: [255]u8,
length: u8,
///
///
///
pub const empty = std.mem.zeroes(Path);
};

View File

@ -1,6 +1,102 @@
const stack = @import("./stack.zig");
const std = @import("std");
///
/// File-system agnostic abstraction for manipulating a file.
///
pub const FileAccess = struct {
context: *anyopaque,
implementation: *const Implementation,
///
/// Provides a set of implementation-specific behaviors to a [FileAccess] instance.
///
pub const Implementation = struct {
close: fn (*anyopaque) void,
queryCursor: fn (*anyopaque) Error!u64,
queryLength: fn (*anyopaque) Error!u64,
read: fn (*anyopaque, []u8) Error!usize,
seek: fn (*anyopaque, u64) Error!void,
seekToEnd: fn (*anyopaque) Error!void,
skip: fn (*anyopaque, i64) Error!void,
};
///
/// [Error.FileInaccessible] is a generic catch-all for a [FileAccess] reference no longer
/// pointing to a file or the file becomming invalid for whatever reason.
///
pub const Error = error {
FileInaccessible,
};
///
/// Close the file referenced by `file_access` on the main thread, invalidating the reference to
/// it and releasing any associated resources.
///
/// Freeing an invalid `file_access` has no effect on the file and logs a warning over the
/// wasted effort.
///
pub fn close(file_access: *FileAccess) void {
return file_access.implementation.close(file_access.context);
}
///
/// Attempts to query the current 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
/// [Error] on failure.
///
pub fn queryCursor(file_access: *FileAccess) Error!u64 {
return file_access.implementation.queryCursor(file_access.context);
}
///
/// Attempts to query the current length for the file referenced by `file_access`.
///
/// Returns the current length of the file at the time of the operation or a [Error] if the file
/// failed to be queried.
///
pub fn queryLength(file_access: *FileAccess) Error!u64 {
return file_access.implementation.queryLength(file_access.context);
}
///
/// Attempts to read `file_access` from the its current position into `buffer`.
///
/// Returns the number of bytes that were available to be read, otherwise an [Error] on failure.
///
pub fn read(file_access: *FileAccess, buffer: []u8) Error!usize {
return file_access.implementation.read(file_access.context, buffer);
}
///
/// Attempts to seek `file_access` from the beginning of the file to `cursor` bytes.
///
/// Returns [Error] on failure.
///
pub fn seek(file_access: *FileAccess, cursor: u64) Error!void {
return file_access.implementation.seek(file_access.context, cursor);
}
///
/// Attempts to seek `file_access` to the end of the file.
///
/// Returns [Error] on failure.
///
pub fn seekToEnd(file_access: *FileAccess) Error!void {
return file_access.implementation.seekToEnd(file_access.context);
}
///
/// Attempts to seek `file_access` by `offset` from the current file position.
///
/// Returns [Error] on failure;
///
pub fn skip(file_access: *FileAccess, offset: i64) Error!void {
return file_access.implementation.skip(file_access.context, offset);
}
};
///
/// Opaque interface to a "writable" resource, such as a block device, memory buffer, or network
/// socket.

25
src/ona/main.zig Normal file
View File

@ -0,0 +1,25 @@
///
///
///
pub const io = @import("./io.zig");
///
///
///
pub const mem = @import("./mem.zig");
///
///
///
pub const meta = @import("./meta.zig");
///
///
///
pub const stack = @import("./stack.zig");
///
///
///
pub const table = @import("./table.zig");