Backlog/engine/platform/src/windowing.zig

170 lines
4.8 KiB
Zig

const std = @import("std");
const core = @import("core");
const platform = @import("platform.zig");
const RingQueue = core.RingQueue;
const sdl3 = @import("sdl3");
const tracy = core.tracy;
pub const InputListenerError = error{
UnknownError,
};
pub const RawInputListenerInterface = struct {
// required functions
OnIoEvent: *const fn (*anyopaque, event: IOEvent) InputListenerError!void,
pub fn from(comptime TargetType: type) @This() {
const Wrapped = struct {
pub fn OnIoEvent(pointer: *anyopaque, event: IOEvent) InputListenerError!void {
var ptr = @as(*TargetType, @ptrCast(@alignCast(pointer)));
try ptr.OnIoEvent(event);
}
};
return .{
.OnIoEvent = Wrapped.OnIoEvent,
};
}
};
pub const RawInputObjectRef = struct {
ptr: *anyopaque,
vtable: *const RawInputListenerInterface,
pub fn from(target: anytype) @This() {
const vtable = &(@TypeOf(target.*)).RawInputListenerVTable;
return .{
.ptr = target,
.vtable = vtable,
};
}
};
// We are having some serious issues with this events pump.
pub const PlatformParams = struct {
extent: core.Vector2c = .{ .x = 1600, .y = 900 },
windowName: []const u8 = "sample window",
icon: []const u8 = "textures/icon.png",
hasVideo: bool = true,
};
pub var gPlatformSettings: struct {
pollLockoutTime: ?f32 = null,
decoratedWindow: bool = true,
transparentFrameBuffer: bool = false,
} = .{};
// For windows and linux computers this is a glfw instance
pub const PlatformInstance = struct {
allocator: std.mem.Allocator,
cursorEnabled: bool = true,
newCursorEnabled: bool = true,
hasVideo: bool = false,
window: *sdl3.Window = undefined,
windowExtent: core.Vector2c,
windowName: [:0]u8,
iconPath: [:0]u8,
windowDestroyed: bool = false,
pub fn deinit(self: *@This()) void {
self.allocator.free(self.windowName);
self.allocator.free(self.iconPath);
// shutdown
}
pub fn onExitSignal(self: *@This()) void {
sdl3.c.SDL_DestroyWindow(self.window);
self.windowDestroyed = true;
}
pub fn readyToExit(self: *@This()) bool {
return self.windowDestroyed;
}
pub fn init(
allocator: std.mem.Allocator,
params: PlatformParams,
) !@This() {
const self: @This() = .{
.allocator = allocator,
.windowName = try allocator.dupeZ(u8, params.windowName),
.iconPath = try allocator.dupeZ(u8, params.icon),
.windowExtent = params.extent,
.hasVideo = params.hasVideo,
};
return self;
}
pub fn setupWindow(opaqueSelf: *anyopaque) core.EngineDataEventError!void {
const self: *@This() = @alignCast(@ptrCast(opaqueSelf));
sdl3.init(.{ .video = true, .gamepad = true }) catch return error.BadInit;
self.window = sdl3.c.SDL_CreateWindow(self.windowName, self.windowExtent.x, self.windowExtent.y, 0).?; // resizeable
}
pub fn registerSetupFuncs(self: *@This()) !void {
core.setupEnginePlatform(self, setupWindow, enginePoll, processEvents);
}
// runs pinned on io thread.
// old glfw needed to do it's polling here.
pub fn enginePoll(opaqueSelf: *anyopaque) core.EngineDataEventError!void {
_ = opaqueSelf;
// this polling event should probably be used for IO, now that we have a free thread for doing w.e
// var self: *@This() = @alignCast(@ptrCast(opaqueSelf));
// self.pollEvents();
}
pub fn installListener(self: *@This(), listener: anytype) !void {
try self.listeners.append(RawInputObjectRef.from(listener));
}
pub fn processEvents(ptr: *anyopaque, frameNumber: u64) core.EngineDataEventError!void {
_ = frameNumber;
_ = ptr;
// const self: *@This() = @ptrCast(@alignCast(ptr));
var t1 = tracy.ZoneN(@src(), "Pumping Events");
defer t1.End();
const inputStack = core.getInputStack();
inputStack.updatePreviousInputs();
while (sdl3.pollEvent()) |event| {
if (core.inputs.convertEvent(event)) |converted| {
inputStack.routeEvent(converted);
}
switch (event.type) {
sdl3.events.quit => {
core.exitNow();
},
else => {},
}
}
}
pub fn getCursorPosition(self: *@This()) core.Vector2f {
return self.cursorPos;
}
pub fn setCursorEnabled(self: *@This(), cursorEnabled: bool) void {
self.newCursorEnabled = cursorEnabled;
}
pub fn isCursorEnabled(self: @This()) bool {
return self.cursorEnabled;
}
};
pub const IOEvent = core.IOEvent;