glfw: Eliminate InvalidEnum

This commit is contained in:
InKryption 2021-11-23 23:16:56 +01:00 committed by Stephen Gutekanst
parent a465d2e021
commit fb0c695bd1
5 changed files with 31 additions and 64 deletions

View file

@ -84,8 +84,6 @@ pub inline fn createStandard(shape: Shape) Error!Cursor {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const cursor = c.glfwCreateStandardCursor(@intCast(c_int, @enumToInt(shape))); const cursor = c.glfwCreateStandardCursor(@intCast(c_int, @enumToInt(shape)));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
// should be unreachable given that only the values in 'Shape' are available, unless the user explicitly gives us a bad value via casting
Error.InvalidEnum => unreachable,
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };

View file

@ -91,7 +91,6 @@ pub inline fn present(self: Joystick) Error!bool {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const is_present = c.glfwJoystickPresent(@enumToInt(self.jid)); const is_present = c.glfwJoystickPresent(@enumToInt(self.jid));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -123,7 +122,6 @@ pub inline fn getAxes(self: Joystick) Error!?[]const f32 {
var count: c_int = undefined; var count: c_int = undefined;
const axes = c.glfwGetJoystickAxes(@enumToInt(self.jid), &count); const axes = c.glfwGetJoystickAxes(@enumToInt(self.jid), &count);
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -160,7 +158,6 @@ pub inline fn getButtons(self: Joystick) Error!?[]const u8 {
var count: c_int = undefined; var count: c_int = undefined;
const buttons = c.glfwGetJoystickButtons(@enumToInt(self.jid), &count); const buttons = c.glfwGetJoystickButtons(@enumToInt(self.jid), &count);
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -213,7 +210,6 @@ pub inline fn getHats(self: Joystick) Error!?[]const Hat {
var count: c_int = undefined; var count: c_int = undefined;
const hats = c.glfwGetJoystickHats(@enumToInt(self.jid), &count); const hats = c.glfwGetJoystickHats(@enumToInt(self.jid), &count);
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -245,7 +241,6 @@ pub inline fn getName(self: Joystick) Error!?[:0]const u8 {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const name_opt = c.glfwGetJoystickName(@enumToInt(self.jid)); const name_opt = c.glfwGetJoystickName(@enumToInt(self.jid));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -286,7 +281,6 @@ pub inline fn getGUID(self: Joystick) Error!?[:0]const u8 {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const guid_opt = c.glfwGetJoystickGUID(@enumToInt(self.jid)); const guid_opt = c.glfwGetJoystickGUID(@enumToInt(self.jid));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -401,7 +395,7 @@ pub inline fn updateGamepadMappings(gamepad_mappings: [*:0]const u8) Error!void
internal_debug.assertInitialized(); internal_debug.assertInitialized();
_ = c.glfwUpdateGamepadMappings(gamepad_mappings); _ = c.glfwUpdateGamepadMappings(gamepad_mappings);
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value Error.InvalidValue => err, // TODO: Evaluate if this is preventable, or if this is like a parsing error which should definitely be returned
else => unreachable, else => unreachable,
}; };
} }
@ -424,10 +418,7 @@ pub inline fn updateGamepadMappings(gamepad_mappings: [*:0]const u8) Error!void
pub inline fn isGamepad(self: Joystick) bool { pub inline fn isGamepad(self: Joystick) bool {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const is_gamepad = c.glfwJoystickIsGamepad(@enumToInt(self.jid)); const is_gamepad = c.glfwJoystickIsGamepad(@enumToInt(self.jid));
getError() catch |err| return switch (err) { getError() catch unreachable;
Error.InvalidEnum => unreachable, // intentionally invalid enum value
else => unreachable,
};
return is_gamepad == c.GLFW_TRUE; return is_gamepad == c.GLFW_TRUE;
} }
@ -454,7 +445,6 @@ pub inline fn getGamepadName(self: Joystick) Error!?[:0]const u8 {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const name_opt = c.glfwGetGamepadName(@enumToInt(self.jid)); const name_opt = c.glfwGetGamepadName(@enumToInt(self.jid));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // intentionally invalid enum value
else => unreachable, else => unreachable,
}; };
return if (name_opt) |name| return if (name_opt) |name|
@ -487,14 +477,11 @@ pub inline fn getGamepadName(self: Joystick) Error!?[:0]const u8 {
/// @thread_safety This function must only be called from the main thread. /// @thread_safety This function must only be called from the main thread.
/// ///
/// see also: gamepad, glfw.UpdateGamepadMappings, glfw.Joystick.isGamepad /// see also: gamepad, glfw.UpdateGamepadMappings, glfw.Joystick.isGamepad
pub inline fn getGamepadState(self: Joystick) Error!?GamepadState { pub inline fn getGamepadState(self: Joystick) ?GamepadState {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
var state: GamepadState = undefined; var state: GamepadState = undefined;
const success = c.glfwGetGamepadState(@enumToInt(self.jid), @ptrCast(*c.GLFWgamepadstate, &state)); const success = c.glfwGetGamepadState(@enumToInt(self.jid), @ptrCast(*c.GLFWgamepadstate, &state));
getError() catch |err| return switch (err) { getError() catch unreachable;
Error.InvalidEnum => unreachable, // intentionally invalid enum value
else => unreachable,
};
return if (success == c.GLFW_TRUE) state else null; return if (success == c.GLFW_TRUE) state else null;
} }
@ -626,7 +613,7 @@ test "getGamepadState" {
defer glfw.terminate(); defer glfw.terminate();
const joystick = glfw.Joystick{ .jid = .one }; const joystick = glfw.Joystick{ .jid = .one };
_ = joystick.getGamepadState() catch |err| std.debug.print("failed to get gamepad state, joysticks not supported? error={}\n", .{err}); _ = joystick.getGamepadState();
_ = (std.mem.zeroes(GamepadState)).getAxis(.left_x); _ = (std.mem.zeroes(GamepadState)).getAxis(.left_x);
_ = (std.mem.zeroes(GamepadState)).getButton(.dpad_up); _ = (std.mem.zeroes(GamepadState)).getButton(.dpad_up);
} }

View file

@ -257,8 +257,7 @@ pub const Hints = struct {
opengl_core_profile = c.GLFW_OPENGL_CORE_PROFILE, opengl_core_profile = c.GLFW_OPENGL_CORE_PROFILE,
}; };
// TODO: Consider whether to retain error here, despite us guaranteeing the absence of 'GLFW_NOT_INITIALIZED' and 'GLFW_INVALID_ENUM' fn set(hints: Hints) void {
fn set(hints: Hints) Error!void {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
inline for (comptime std.meta.fieldNames(Hint)) |field_name| { inline for (comptime std.meta.fieldNames(Hint)) |field_name| {
const hint_tag = @enumToInt(@field(Hint, field_name)); const hint_tag = @enumToInt(@field(Hint, field_name));
@ -279,10 +278,7 @@ pub const Hints = struct {
else => unreachable, else => unreachable,
} }
getError() catch |err| return switch (err) { getError() catch unreachable;
Error.InvalidEnum => unreachable, // should not be possible, given that only values defined within this struct are possible.
else => unreachable,
};
} }
} }
}; };
@ -405,7 +401,7 @@ pub const Hints = struct {
pub inline fn create(width: usize, height: usize, title: [*:0]const u8, monitor: ?Monitor, share: ?Window, hints: Hints) Error!Window { pub inline fn create(width: usize, height: usize, title: [*:0]const u8, monitor: ?Monitor, share: ?Window, hints: Hints) Error!Window {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const ignore_hints_struct = if (comptime @import("builtin").is_test) testing_ignore_window_hints_struct else false; const ignore_hints_struct = if (comptime @import("builtin").is_test) testing_ignore_window_hints_struct else false;
if (!ignore_hints_struct) try hints.set(); if (!ignore_hints_struct) hints.set();
defer if (!ignore_hints_struct) defaultHints(); defer if (!ignore_hints_struct) defaultHints();
const handle = c.glfwCreateWindow( const handle = c.glfwCreateWindow(
@ -417,9 +413,7 @@ pub inline fn create(width: usize, height: usize, title: [*:0]const u8, monitor:
); );
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum, Error.InvalidValue => unreachable,
Error.InvalidValue,
=> unreachable, // we restrict the set of values to only those which GLFW deems to be valid, so these should never be reachable.
Error.APIUnavailable, Error.APIUnavailable,
Error.VersionUnavailable, Error.VersionUnavailable,
Error.FormatUnavailable, Error.FormatUnavailable,
@ -1229,9 +1223,7 @@ pub inline fn getAttrib(self: Window, attrib: Attrib) Error!isize {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const v = c.glfwGetWindowAttrib(self.handle, @enumToInt(attrib)); const v = c.glfwGetWindowAttrib(self.handle, @enumToInt(attrib));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum, Error.PlatformError => err,
Error.PlatformError,
=> err,
else => unreachable, else => unreachable,
}; };
return v; return v;
@ -1265,9 +1257,7 @@ pub inline fn setAttrib(self: Window, attrib: Attrib, value: bool) Error!void {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
c.glfwSetWindowAttrib(self.handle, @enumToInt(attrib), if (value) c.GLFW_TRUE else c.GLFW_FALSE); c.glfwSetWindowAttrib(self.handle, @enumToInt(attrib), if (value) c.GLFW_TRUE else c.GLFW_FALSE);
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum, Error.InvalidValue => unreachable,
Error.InvalidValue,
=> unreachable,
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };
@ -1716,8 +1706,8 @@ pub inline fn getInputMode(self: Window, mode: InputMode) isize {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const value = c.glfwGetInputMode(self.handle, @enumToInt(mode)); const value = c.glfwGetInputMode(self.handle, @enumToInt(mode));
// Possible errors include glfw.Error.InvalidEnum. // Possible errors: 'GLFW_NOT_INITIALIZED' and 'GLFW_INVALID_ENUM'; we guarantee both to be unreachable
getError() catch @panic("unexpected error getting input mode, invalid enum"); getError() catch unreachable;
return @intCast(isize, value); return @intCast(isize, value);
} }
@ -1741,6 +1731,7 @@ pub inline fn getInputMode(self: Window, mode: InputMode) isize {
/// @thread_safety This function must only be called from the main thread. /// @thread_safety This function must only be called from the main thread.
/// ///
/// see also: glfw.Window.getInputMode /// see also: glfw.Window.getInputMode
// TODO: Review this function and consider how to make it impossible for GLFW to set 'GLFW_INVALID_ENUM'
pub inline fn setInputMode(self: Window, mode: InputMode, value: anytype) Error!void { pub inline fn setInputMode(self: Window, mode: InputMode, value: anytype) Error!void {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
switch (@typeInfo(@TypeOf(value))) { switch (@typeInfo(@TypeOf(value))) {
@ -1750,9 +1741,8 @@ pub inline fn setInputMode(self: Window, mode: InputMode, value: anytype) Error!
else => @compileError("expected a int or bool, got " ++ @typeName(@TypeOf(value))), else => @compileError("expected a int or bool, got " ++ @typeName(@TypeOf(value))),
} }
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum, Error.InvalidEnum => err, // TODO: See above 'todo'
Error.PlatformError, Error.PlatformError => err,
=> err,
else => unreachable, else => unreachable,
}; };
} }
@ -1783,13 +1773,10 @@ pub inline fn setInputMode(self: Window, mode: InputMode, value: anytype) Error!
/// @thread_safety This function must only be called from the main thread. /// @thread_safety This function must only be called from the main thread.
/// ///
/// see also: input_key /// see also: input_key
pub inline fn getKey(self: Window, key: Key) Error!Action { pub inline fn getKey(self: Window, key: Key) Action {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const state = c.glfwGetKey(self.handle, @enumToInt(key)); const state = c.glfwGetKey(self.handle, @enumToInt(key));
getError() catch |err| return switch (err) { getError() catch unreachable;
Error.InvalidEnum => err,
else => unreachable,
};
return @intToEnum(Action, state); return @intToEnum(Action, state);
} }
@ -1809,13 +1796,10 @@ pub inline fn getKey(self: Window, key: Key) Error!Action {
/// @thread_safety This function must only be called from the main thread. /// @thread_safety This function must only be called from the main thread.
/// ///
/// see also: input_mouse_button /// see also: input_mouse_button
pub inline fn getMouseButton(self: Window, button: MouseButton) Error!Action { pub inline fn getMouseButton(self: Window, button: MouseButton) Action {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const state = c.glfwGetMouseButton(self.handle, @enumToInt(button)); const state = c.glfwGetMouseButton(self.handle, @enumToInt(button));
getError() catch |err| return switch (err) { getError() catch unreachable;
Error.InvalidEnum => err,
else => unreachable,
};
return @intToEnum(Action, state); return @intToEnum(Action, state);
} }
@ -2190,7 +2174,7 @@ pub inline fn setDropCallback(self: Window, callback: ?fn (window: Window, paths
/// @thread_safety This function must only be called from the main thread. /// @thread_safety This function must only be called from the main thread.
/// ///
/// see also: window_hints, glfw.Window.defaultHints /// see also: window_hints, glfw.Window.defaultHints
inline fn hint(h: Hint, value: anytype) Error!void { inline fn hint(h: Hint, value: anytype) void {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const value_type = @TypeOf(value); const value_type = @TypeOf(value);
const value_type_info: std.builtin.TypeInfo = @typeInfo(value_type); const value_type_info: std.builtin.TypeInfo = @typeInfo(value_type);
@ -2230,7 +2214,7 @@ inline fn hint(h: Hint, value: anytype) Error!void {
@compileError("expected a int, bool, enum, array, or pointer, got " ++ @typeName(value_type)); @compileError("expected a int, bool, enum, array, or pointer, got " ++ @typeName(value_type));
}, },
} }
try getError(); getError() catch unreachable;
} }
test "defaultHints" { test "defaultHints" {
@ -2244,7 +2228,7 @@ test "hint comptime int" {
try glfw.init(.{}); try glfw.init(.{});
defer glfw.terminate(); defer glfw.terminate();
try hint(.focused, 1); hint(.focused, 1);
defaultHints(); defaultHints();
} }
@ -2254,7 +2238,7 @@ test "hint int" {
var focused: i32 = 1; var focused: i32 = 1;
try hint(.focused, focused); hint(.focused, focused);
defaultHints(); defaultHints();
} }
@ -2262,7 +2246,7 @@ test "hint bool" {
try glfw.init(.{}); try glfw.init(.{});
defer glfw.terminate(); defer glfw.terminate();
try hint(.focused, true); hint(.focused, true);
defaultHints(); defaultHints();
} }
@ -2275,7 +2259,7 @@ test "hint enum(u1)" {
@"false" = 0, @"false" = 0,
}; };
try hint(.focused, MyEnum.@"true"); hint(.focused, MyEnum.@"true");
defaultHints(); defaultHints();
} }
@ -2288,7 +2272,7 @@ test "hint enum(i32)" {
@"false" = 0, @"false" = 0,
}; };
try hint(.focused, MyEnum.@"true"); hint(.focused, MyEnum.@"true");
defaultHints(); defaultHints();
} }
@ -2298,7 +2282,7 @@ test "hint array str" {
const str_arr = [_]u8{ 'm', 'y', 'c', 'l', 'a', 's', 's' }; const str_arr = [_]u8{ 'm', 'y', 'c', 'l', 'a', 's', 's' };
try hint(.x11_class_name, str_arr); hint(.x11_class_name, str_arr);
defaultHints(); defaultHints();
} }
@ -2306,7 +2290,7 @@ test "hint pointer str" {
try glfw.init(.{}); try glfw.init(.{});
defer glfw.terminate(); defer glfw.terminate();
try hint(.x11_class_name, "myclass"); hint(.x11_class_name, "myclass");
} }
test "createWindow" { test "createWindow" {
@ -3152,7 +3136,7 @@ test "getKey" {
}; };
defer window.destroy(); defer window.destroy();
_ = try window.getKey(glfw.Key.escape); _ = window.getKey(glfw.Key.escape);
} }
test "getMouseButton" { test "getMouseButton" {
@ -3167,7 +3151,7 @@ test "getMouseButton" {
}; };
defer window.destroy(); defer window.destroy();
_ = try window.getMouseButton(.left); _ = window.getMouseButton(.left);
} }
test "getCursorPos" { test "getCursorPos" {

View file

@ -243,7 +243,6 @@ pub const Key = enum(c_int) {
internal_debug.assertInitialized(); internal_debug.assertInitialized();
const scancode = cc.glfwGetKeyScancode(@enumToInt(self)); const scancode = cc.glfwGetKeyScancode(@enumToInt(self));
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // Should be unreachable for any valid 'Key' value.
Error.PlatformError => err, Error.PlatformError => err,
else => unreachable, else => unreachable,
}; };

View file

@ -177,7 +177,6 @@ fn initHint(hint: InitHint, value: anytype) Error!void {
else => @compileError("expected a int or bool, got " ++ @typeName(@TypeOf(value))), else => @compileError("expected a int or bool, got " ++ @typeName(@TypeOf(value))),
} }
getError() catch |err| return switch (err) { getError() catch |err| return switch (err) {
Error.InvalidEnum => unreachable, // impossible for any valid 'InitHint' value
Error.InvalidValue => err, Error.InvalidValue => err,
else => unreachable, else => unreachable,
}; };