ona/source/ona/app.zig
kayomn 1828eb3b45
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Refactor Kym runtime values to be objects
2023-07-18 23:52:56 +01:00

143 lines
3.3 KiB
Zig

const coral = @import("coral");
const ext = @import("./ext.zig");
const file = @import("./file.zig");
const kym = @import("./kym.zig");
pub const Manifest = struct {
title: [255:0]coral.io.Byte = [_:0]coral.io.Byte{0} ** 255,
width: u16 = 640,
height: u16 = 480,
tick_rate: f32 = 60.0,
pub fn load(self: *Manifest, env: *kym.RuntimeEnv, global_ref: ?*const kym.RuntimeRef, file_access: file.Access) kym.RuntimeError!void {
var manifest_ref = try env.execute_file(global_ref, file_access, file.Path.from(&.{"app.ona"}));
defer env.discard(&manifest_ref);
var title_ref = try kym.get_dynamic_field(env, manifest_ref, "title");
defer env.discard(&title_ref);
const title_string = switch (env.unbox(title_ref)) {
.string => |string| string,
else => "",
};
const width = @as(u16, get: {
var ref = try kym.get_dynamic_field(env, manifest_ref, "width");
defer env.discard(&ref);
// TODO: Add safety-checks to int cast.
break: get switch (env.unbox(ref)) {
.number => |number| @intFromFloat(number),
else => self.width,
};
});
const height = @as(u16, get: {
var ref = try kym.get_dynamic_field(env, manifest_ref, "height");
defer env.discard(&ref);
// TODO: Add safety-checks to int cast.
break: get switch (env.unbox(ref)) {
.number => |number| @intFromFloat(number),
else => self.height,
};
});
const tick_rate = @as(f32, get: {
var ref = try kym.get_dynamic_field(env, manifest_ref, "tick_rate");
defer env.discard(&ref);
break: get switch (env.unbox(ref)) {
.number => |number| @floatCast(number),
else => self.tick_rate,
};
});
{
const limited_title_len = coral.math.min(title_string.len, self.title.len);
coral.io.copy(&self.title, title_string[0 .. limited_title_len]);
coral.io.zero(self.title[limited_title_len .. self.title.len]);
}
self.tick_rate = tick_rate;
self.width = width;
self.height = height;
}
};
pub const LogSeverity = enum {
info,
warn,
fail,
};
pub const WritableLog = struct {
severity: LogSeverity,
write_buffer: coral.list.ByteStack,
pub fn as_writer(self: *WritableLog) coral.io.Writer {
return coral.io.Writer.bind(WritableLog, self, struct {
fn write(writable_log: *WritableLog, bytes: []const coral.io.Byte) ?usize {
writable_log.write(bytes) catch return null;
return bytes.len;
}
}.write);
}
pub fn free(self: *WritableLog) void {
self.write_buffer.free();
}
pub fn make(log_severity: LogSeverity, allocator: coral.io.Allocator) WritableLog {
return .{
.severity = log_severity,
.write_buffer = coral.list.ByteStack.make(allocator),
};
}
pub fn write(self: *WritableLog, bytes: []const coral.io.Byte) coral.io.AllocationError!void {
const format_string = "%.*s";
var line_written = @as(usize, 0);
for (bytes) |byte| {
if (byte == '\n') {
ext.SDL_LogError(
ext.SDL_LOG_CATEGORY_APPLICATION,
format_string,
self.write_buffer.values.len,
self.write_buffer.values.ptr);
self.write_buffer.clear();
line_written = 0;
continue;
}
try self.write_buffer.push_one(byte);
line_written += 1;
}
if (self.write_buffer.values.len == 0) {
ext.SDL_LogError(
ext.SDL_LOG_CATEGORY_APPLICATION,
format_string,
self.write_buffer.values.len,
self.write_buffer.values.ptr);
self.write_buffer.clear();
}
}
};