const coral = @import("coral"); const kym = @import("kym"); const ona = @import("ona"); fn create_canvas_binding(binding_vm: *kym.Vm, canvas: *ona.gfx.Canvas) !*kym.Object { const canvas_object = try binding_vm.new(.{.native = canvas}, .{}); const Object = kym.Object; const Value = kym.Value; try binding_vm.set_field(canvas_object, "create_sprite", .{.object = try binding_vm.new_closure(struct { fn call(calling_vm: *kym.Vm, _: *Object, context: *Object, arguments: []const Value) kym.RuntimeError!Value { const properties = try kym.object_argument(calling_vm, arguments, 0); @ptrCast(*ona.gfx.Canvas, context.userdata().native).create_sprite(.{ .position = calling_vm.get_field(properties, "position").to_vector2() orelse coral.math.Vector2.zero, .rotation = @floatCast(f32, calling_vm.get_field(properties, "rotation").to_float() orelse 0.0), }); return .nil; } }.call)}); return canvas_object; } pub fn main() anyerror!void { return ona.App.run(anyerror, start); } fn start(app: *ona.App) anyerror!void { var vm = try kym.Vm.init(ona.allocator, .{ .stack_max = 256, .objects_max = 512, }); defer vm.deinit(); try vm.set_field(vm.globals(), "events", .{.object = try create_canvas_binding(&vm, app.canvas())}); { const index_path = "index.kym"; const index_file = try app.data_fs().open_readable(index_path); defer if (!index_file.close()) ona.log_error(&.{.{.string = "failed to close "}, .{.string = index_path}}); const index_size = (try app.data_fs().query(index_path)).size; const index_allocation = ona.allocator.allocate_many(u8, index_size) orelse return error.OutOfMemory; defer ona.allocator.deallocate(index_allocation); var index_buffer = coral.buffer.Fixed{.data = index_allocation[0 .. index_size]}; { var stream_buffer = [_]u8{0} ** 1024; if ((try coral.io.stream(index_buffer.as_writer(), index_file.as_reader(), &stream_buffer)) != index_size) return error.IoUnavailable; } _ = try vm.call_self(try vm.new_script(index_buffer.data), &.{}); } while (app.poll()) { } }