Application Context Implementation #4

Closed
kayomn wants to merge 93 commits from event-loop-dev into main
13 changed files with 133 additions and 90 deletions
Showing only changes of commit 813df95e02 - Show all commits

11
.vscode/launch.json vendored
View File

@ -2,7 +2,7 @@
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"name": "Ona",
"type": "gdb",
"request": "launch",
"target": "${workspaceFolder}/zig-out/bin/ona",
@ -10,6 +10,15 @@
"valuesFormatting": "parseText",
"preLaunchTask": "Build Debug",
},
{
"name": "Oar",
"type": "gdb",
"request": "launch",
"target": "${workspaceFolder}/zig-out/bin/oar",
"cwd": "${workspaceRoot}",
"valuesFormatting": "parseText",
"preLaunchTask": "Build Debug",
},
{
"name": "Test",
"type": "gdb",

5
.vscode/tasks.json vendored
View File

@ -41,11 +41,12 @@
"revealProblems": "onProblem",
},
},
{
"label": "Build Test",
"label": "Build Tests",
"type": "shell",
"command": "zig build test",
"group": "test"
"group": "build",
},
],
}

View File

@ -6,14 +6,14 @@ const std = @import("std");
pub fn build(builder: *std.build.Builder) void {
const target = builder.standardTargetOptions(.{});
const mode = builder.standardReleaseOptions();
const ona_pkg = projectPkg("ona", &.{});
const core_pkg = projectPkg("core", &.{});
// Engine executable.
// Ona executable.
{
const exe = builder.addExecutable("engine", "./src/engine/main.zig");
const exe = builder.addExecutable("ona", "./src/ona/main.zig");
exe.addPackage(projectPkg("oar", &.{ona_pkg}));
exe.addPackage(ona_pkg);
exe.addPackage(projectPkg("oar", &.{core_pkg}));
exe.addPackage(core_pkg);
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
@ -26,7 +26,7 @@ pub fn build(builder: *std.build.Builder) void {
{
const exe = builder.addExecutable("oar", "./src/oar/main.zig");
exe.addPackage(ona_pkg);
exe.addPackage(core_pkg);
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();

View File

@ -183,11 +183,11 @@ test "Spliterating text" {
pub const Writer = meta.Function(@sizeOf(usize), []const u8, usize);
///
/// Returns `true` if `this_bytes` is the same length and contains the same data as `that_bytes`,
/// otherwise `false`.
/// Returns `true` if `this` is the same length and contains the same data as `that`, otherwise
/// `false`.
///
pub fn equalsBytes(this_bytes: []const u8, that_bytes: []const u8) bool {
return std.mem.eql(u8, this_bytes, that_bytes);
pub fn equalsBytes(this: []const u8, that: []const u8) bool {
return std.mem.eql(u8, this, that);
}
test "Equivalence of bytes" {

27
src/core/main.zig Normal file
View File

@ -0,0 +1,27 @@
///
/// Platform-agnostic input and output interfaces for working with memory, files, and networks.
///
pub const io = @import("./io.zig");
///
/// Metaprogramming introspection utilities
///
pub const meta = @import("./meta.zig");
///
/// Sequential last-in first-out data structures.
///
pub const stack = @import("./stack.zig");
///
/// Unordered key-value association data structures.
///
pub const table = @import("./table.zig");
test {
_ = io;
_ = meta;
_ = stack;
_ = table;
}

View File

@ -1,40 +0,0 @@
const ona = @import("ona");
const std = @import("std");
const sys = @import("./sys.zig");
///
/// Starts the the game engine.
///
pub fn main() anyerror!void {
return nosuspend await async sys.display(anyerror, run);
}
fn run(app: *sys.App, graphics: *sys.Graphics) anyerror!void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
{
var file_access = try app.data.open(try sys.Path.joined(&.{"ona.lua"}), .readonly);
defer file_access.close();
const file_size = try file_access.queryLength();
const allocator = gpa.allocator();
const buffer = try allocator.alloc(u8, file_size);
defer allocator.free(buffer);
if ((try file_access.read(buffer)) != file_size) return error.ScriptLoadFailure;
app.log(.debug, buffer);
}
while (graphics.poll()) |_| {
graphics.present();
}
}
test {
_ = sys;
}

View File

@ -1,4 +1,4 @@
const ona = @import("ona");
const core = @import("core");
const std = @import("std");
///
@ -23,14 +23,18 @@ pub const Entry = extern struct {
}
///
/// Attempts to read the next [Entry] from `file_access`.
///
/// Returns the read [Entry], `null` if there is no more to read, or a
/// [core.io.FileAccess.Error] if it failed.
///
pub fn next(file_access: ona.io.FileAccess) ona.io.FileAccess.Error!?Entry {
var entry = std.mem.zeroes(Entry);
pub fn next(file_access: core.io.FileAccess) core.io.FileAccess.Error!?Entry {
const mem = std.mem;
var entry = mem.zeroes(Entry);
const origin = try file_access.queryCursor();
if (((try file_access.read(std.mem.asBytes(&entry))) != @sizeOf(Entry)) and
ona.io.equalsBytes(&entry.signature, &signature_magic)) {
if (((try file_access.read(mem.asBytes(&entry))) != @sizeOf(Entry)) and
core.io.equalsBytes(&entry.signature, &signature_magic)) {
try file_access.seek(origin);
@ -72,7 +76,7 @@ pub const Path = extern struct {
/// Returns `true` if `this_path` is equal to `that_path, otherwise `false`.
///
pub fn equals(this_path: Path, that_path: Path) bool {
return ona.io.equalsBytes(this_path.buffer[0 ..this_path.
return core.io.equalsBytes(this_path.buffer[0 ..this_path.
length], that_path.buffer[0 .. that_path.length]);
}
@ -80,7 +84,7 @@ pub const Path = extern struct {
/// Returns the hash of the text in `path`.
///
pub fn hash(path: Path) usize {
return ona.io.hashBytes(path.buffer[0 .. path.length]);
return core.io.hashBytes(path.buffer[0 .. path.length]);
}
///
@ -97,7 +101,7 @@ pub const Path = extern struct {
const last_sequence_index = sequences.len - 1;
for (sequences) |sequence, index| if (sequence.len != 0) {
var components = ona.io.Spliterator(u8){
var components = core.io.Spliterator(u8){
.source = sequence,
.delimiter = "/",
};
@ -144,8 +148,37 @@ pub const Path = extern struct {
///
/// Starts the **O**na **Ar**chive packer utility.
///
pub fn main() u8 {
// TODO: Implement.
pub fn main() !u8 {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const process = std.process;
const allocator = gpa.allocator();
const args = try process.argsAlloc(allocator);
defer process.argsFree(allocator, args);
const outWriter = std.io.getStdOut().writer();
if (args.len > 1) {
const command = args[1];
const io = core.io;
if (io.equalsBytes(command, "pack")) {
return 0;
}
if (io.equalsBytes(command, "unpack")) {
return 0;
}
try outWriter.print("Unknown command: {s}", .{command});
return 1;
}
try outWriter.print("{s}", .{args[0]});
return 0;
}

View File

@ -1,27 +1,40 @@
const core = @import("core");
const std = @import("std");
const sys = @import("./sys.zig");
///
/// Platform-agnostic input and output interfaces for working with memory, files, and networks.
/// Starts the the game engine.
///
pub const io = @import("./io.zig");
pub fn main() anyerror!void {
return nosuspend await async sys.display(anyerror, run);
}
///
/// Metaprogramming introspection utilities
///
pub const meta = @import("./meta.zig");
fn run(app: *sys.App, graphics: *sys.Graphics) anyerror!void {
kayomn marked this conversation as resolved Outdated

Missing documentation comment.

Missing documentation comment.
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
///
/// Sequential last-in first-out data structures.
///
pub const stack = @import("./stack.zig");
defer _ = gpa.deinit();
///
/// Unordered key-value association data structures.
///
pub const table = @import("./table.zig");
{
var file_access = try app.data.open(try sys.Path.joined(&.{"ona.lua"}), .readonly);
defer file_access.close();
const file_size = try file_access.queryLength();
const allocator = gpa.allocator();
const buffer = try allocator.alloc(u8, file_size);
defer allocator.free(buffer);
if ((try file_access.read(buffer)) != file_size) return error.ScriptLoadFailure;
app.log(.debug, buffer);
}
while (graphics.poll()) |_| {
graphics.present();
}
}
test {
_ = io;
_ = meta;
_ = stack;
_ = table;
_ = sys;
}

View File

@ -2,8 +2,8 @@ const ext = @cImport({
@cInclude("SDL2/SDL.h");
});
const core = @import("core");
const oar = @import("oar");
const ona = @import("ona");
const std = @import("std");
///
@ -44,12 +44,12 @@ pub const App = struct {
/// Once the execution frame resumes, the value returned by executing `procedure` is returned.
///
pub fn schedule(app: *App, procedure: anytype,
arguments: anytype) ona.meta.FnReturn(@TypeOf(procedure)) {
arguments: anytype) core.meta.FnReturn(@TypeOf(procedure)) {
const Task = struct {
procedure: @TypeOf(procedure),
arguments: *@TypeOf(arguments),
result: ona.meta.FnReturn(@TypeOf(procedure)),
result: core.meta.FnReturn(@TypeOf(procedure)),
const Task = @This();
@ -104,7 +104,7 @@ pub const FileSystem = union(enum) {
/// Archive file system information.
///
const Archive = struct {
file_access: ona.io.FileAccess,
file_access: core.io.FileAccess,
index_cache: IndexCache,
entry_table: [max_open_entries]Entry = std.mem.zeroes([max_open_entries]Entry),
@ -117,7 +117,7 @@ pub const FileSystem = union(enum) {
/// Stateful extension of an [oar.Entry].
///
const Entry = struct {
owner: ?*ona.io.FileAccess,
owner: ?*core.io.FileAccess,
cursor: u64,
header: oar.Entry,
};
@ -125,7 +125,7 @@ pub const FileSystem = union(enum) {
///
/// Table cache for associating [oar.Path] values with offsets to entries in a given file.
///
const IndexCache = ona.table.Hashed(oar.Path, u64, .{
const IndexCache = core.table.Hashed(oar.Path, u64, .{
.equals = oar.Path.equals,
.hash = oar.Path.hash,
});
@ -172,12 +172,12 @@ 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(file_system: *FileSystem, path: Path, mode: OpenMode) OpenError!ona.io.FileAccess {
pub fn open(file_system: *FileSystem, path: Path, mode: OpenMode) OpenError!core.io.FileAccess {
switch (file_system.*) {
.archive => |*archive| {
if (mode != .readonly) return error.ModeUnsupported;
const FileAccess = ona.io.FileAccess;
const FileAccess = core.io.FileAccess;
for (archive.entry_table) |*entry| if (entry.owner == null) {
const Implementation = struct {
@ -320,7 +320,7 @@ pub const FileSystem = union(enum) {
mem.copy(u8, path_buffer[native.len .. path_buffer.
len], path.buffer[0 .. path.length]);
const FileAccess = ona.io.FileAccess;
const FileAccess = core.io.FileAccess;
const Implementation = struct {
fn rwOpsCast(context: *anyopaque) *ext.SDL_RWops {