From 60eb518e4f1c335d5792eab30e6247604dd28254 Mon Sep 17 00:00:00 2001 From: Andrew Gutekanst Date: Tue, 7 Feb 2023 20:08:35 -0500 Subject: [PATCH] core: libmachcore fixes --- libs/core/build.zig | 3 +- libs/core/include/libmachcore.h | 37 +++++++++++++++++++ libs/core/sdk.zig | 5 ++- libs/core/src/main.zig | 4 +++ libs/core/src/platform/libmachcore.zig | 50 +++++++++++++++++++++----- 5 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 libs/core/include/libmachcore.h diff --git a/libs/core/build.zig b/libs/core/build.zig index 90948c50..2c58be3d 100644 --- a/libs/core/build.zig +++ b/libs/core/build.zig @@ -39,7 +39,7 @@ pub fn build(b: *std.build.Builder) !void { glfw_test_step.dependOn(&(try glfw.testStep(b, mode, target)).step); gpu_test_step.dependOn(&(try gpu.testStep(b, mode, target, options.gpuOptions())).step); - core_test_step.dependOn(&core.testStep(b, mode, target).step); + core_test_step.dependOn(&(try core.testStep(b, mode, target)).step); all_tests_step.dependOn(glfw_test_step); all_tests_step.dependOn(gpu_test_step); @@ -52,6 +52,7 @@ pub fn build(b: *std.build.Builder) !void { // Compiles the `libmachcore` shared library const shared_lib = try core.buildSharedLib(b, mode, target, options); + shared_lib.install(); } diff --git a/libs/core/include/libmachcore.h b/libs/core/include/libmachcore.h new file mode 100644 index 00000000..42178af3 --- /dev/null +++ b/libs/core/include/libmachcore.h @@ -0,0 +1,37 @@ +#ifndef MACHCORE_H_ +#define MACHCORE_H_ + +#if defined(MACHCORE_SHARED_LIBRARY) +# if defined(_WIN32) +# if defined(MACHCORE_IMPLEMENTATION) +# define MACHCORE_EXPORT __declspec(dllexport) +# else +# define MACHCORE_EXPORT __declspec(dllimport) +# endif +# else // defined(_WIN32) +# if defined(MACHCORE_IMPLEMENTATION) +# define MACHCORE_EXPORT __attribute__((visibility("default"))) +# else +# define MACHCORE_EXPORT +# endif +# endif // defined(_WIN32) +#else // defined(MACHCORE_SHARED_LIBRARY) +# define MACHCORE_EXPORT +#endif // defined(MACHCORE_SHARED_LIBRARY) + +#include +#include +#include + +typedef struct MachCoreInstanceImpl MachCoreInstance; + +typedef struct MachCoreEventIteratorImpl { + unsigned char _data[8]; +} MachCoreEventIterator; + +MachCoreInstance* mach_core_init(); +void mach_core_deinit(MachCoreInstance* core); +MachCoreEventIterator mach_core_poll_events(MachCoreInstance* core); + + +#endif // MACHCORE_H_ \ No newline at end of file diff --git a/libs/core/sdk.zig b/libs/core/sdk.zig index 3cc157a9..c9b89326 100644 --- a/libs/core/sdk.zig +++ b/libs/core/sdk.zig @@ -19,13 +19,16 @@ pub fn Sdk(comptime deps: anytype) type { } }; - pub fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) *std.build.RunStep { + pub fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) !*std.build.RunStep { const main_tests = b.addTestExe("core-tests", "src/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); for (pkg.dependencies.?) |dependency| { main_tests.addPackage(dependency); } + main_tests.addPackage(deps.glfw.pkg); + try deps.glfw.link(b, main_tests, .{}); + main_tests.addIncludePath(sdkPath("/include")); main_tests.install(); return main_tests.run(); } diff --git a/libs/core/src/main.zig b/libs/core/src/main.zig index a382d755..5f129289 100644 --- a/libs/core/src/main.zig +++ b/libs/core/src/main.zig @@ -3,3 +3,7 @@ pub const Core = @import("Core.zig"); pub const Timer = @import("Timer.zig"); pub const gpu = @import("gpu"); pub const sysjs = @import("sysjs"); + +test { + _ = @import("platform/libmachcore.zig"); +} diff --git a/libs/core/src/platform/libmachcore.zig b/libs/core/src/platform/libmachcore.zig index 4a25ab38..05d60e04 100644 --- a/libs/core/src/platform/libmachcore.zig +++ b/libs/core/src/platform/libmachcore.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const testing = std.testing; const gpu = @import("gpu"); const ecs = @import("ecs"); const glfw = @import("glfw"); @@ -20,31 +21,64 @@ const _ = gpu.Export(GPUInterface); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); +pub const MachCoreInstance = anyopaque; + // Returns a pointer to a newly allocated Core // Will return a null pointer if an error occurred while initializing Core -pub export fn mach_core_init() ?*native.Core { - gpu.Impl.init(); +pub export fn mach_core_init() ?*MachCoreInstance { + if (!@import("builtin").is_test) gpu.Impl.init(); + // TODO(libmach): eliminate this allocation var core = allocator.create(native.Core) catch { - return @intToPtr(?*native.Core, 0); + return null; }; // TODO(libmach): allow passing init options core.init(allocator, .{}) catch { // TODO(libmach): better error handling - return @intToPtr(?*native.Core, 0); + return null; }; return core; } -pub export fn mach_core_deinit(core: *native.Core) void { +pub export fn mach_core_deinit(_core: *MachCoreInstance) void { + var core = @ptrCast(*native.Core, @alignCast(@alignOf(@TypeOf(_core)), _core)); native.Core.deinit(core); } -// pub export fn mach_core_poll_events(core: *native.Core) Core.Event { -// return native.Core.pollEvents(core); -// } +pub const MachCoreEventIterator = extern struct { + _data: [8]u8, +}; + +pub const MachCoreEvent = Core.Event; + +pub export fn mach_core_poll_events(_core: *MachCoreInstance) MachCoreEventIterator { + var core = @ptrCast(*native.Core, @alignCast(@alignOf(@TypeOf(_core)), _core)); + var iter = native.Core.pollEvents(core); + return @ptrCast(*MachCoreEventIterator, &iter).*; +} + +pub export fn mach_core_event_iterator_next(_iter: *MachCoreEventIterator, event: *MachCoreEvent) bool { + var iter = @ptrCast(*native.Core.EventIterator, @alignCast(@alignOf(@TypeOf(_iter)), _iter)); + var value = iter.next() orelse return false; + event.* = value; + return true; +} const MachStatus = enum(c_int) { Success = 0x00000000, Error = 0x00000001, }; + +test "C sizes" { + const c_header = @cImport({ + @cInclude("libmachcore.h"); + }); + + // Core.EventIterator can have different sizes depending on the platform, + // so we ensure we always use the maximum size in our C API. + if (@sizeOf(Core.EventIterator) > @sizeOf(MachCoreEventIterator)) { + try testing.expectEqual(@sizeOf(Core.EventIterator), @sizeOf(MachCoreEventIterator)); + } + + try testing.expectEqual(@sizeOf(c_header.MachCoreEventIterator), @sizeOf(MachCoreEventIterator)); +}