glfw: ziggify all Action enums

Make the GLFW action enumerations proper Zig enums so one can use `.Name` syntax, etc.

Helps #37

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2021-10-29 21:22:19 -07:00 committed by Stephen Gutekanst
parent ed10bebf99
commit 8a14d56fc3
6 changed files with 49 additions and 50 deletions

View file

@ -42,7 +42,7 @@ pub const last = c.GLFW_JOYSTICK_LAST;
/// ///
/// see also: gamepad, glfwGetGamepadState /// see also: gamepad, glfwGetGamepadState
const GamepadState = extern struct { const GamepadState = extern struct {
/// The states of each gamepad button (see gamepad_buttons), `glfw.press` or `glfw.release`. /// The states of each gamepad button (see gamepad_buttons), `glfw.Action.press` or `glfw.Action.release`.
buttons: [15]u8, buttons: [15]u8,
/// The states of each gamepad axis (see gamepad_axes), in the range -1.0 to 1.0 inclusive. /// The states of each gamepad axis (see gamepad_axes), in the range -1.0 to 1.0 inclusive.
@ -100,7 +100,7 @@ pub inline fn getAxes(self: Joystick) Error!?[]const f32 {
/// Returns the state of all buttons of the specified joystick. /// Returns the state of all buttons of the specified joystick.
/// ///
/// This function returns the state of all buttons of the specified joystick. Each element in the /// This function returns the state of all buttons of the specified joystick. Each element in the
/// array is either `glfw.press` or `glfw.release`. /// array is either `glfw.Action.press` or `glfw.Action.release`.
/// ///
/// For backward compatibility with earlier versions that did not have glfw.Joystick.getHats, the /// For backward compatibility with earlier versions that did not have glfw.Joystick.getHats, the
/// button array also includes all hats, each represented as four buttons. The hats are in the same /// button array also includes all hats, each represented as four buttons. The hats are in the same
@ -396,7 +396,7 @@ pub inline fn getGamepadName(self: Joystick) Error!?[*c]const u8 {
/// Steam client. /// Steam client.
/// ///
/// Not all devices have all the buttons or axes provided by GamepadState. Unavailable buttons /// Not all devices have all the buttons or axes provided by GamepadState. Unavailable buttons
/// and axes will always report `glfw.release` and 0.0 respectively. /// and axes will always report `glfw.Action.release` and 0.0 respectively.
/// ///
/// @param[in] jid The joystick (see joysticks) to query. /// @param[in] jid The joystick (see joysticks) to query.
/// @param[out] state The gamepad input state of the joystick. /// @param[out] state The gamepad input state of the joystick.

View file

@ -11,6 +11,7 @@ const Image = @import("Image.zig");
const Monitor = @import("Monitor.zig"); const Monitor = @import("Monitor.zig");
const Cursor = @import("Cursor.zig"); const Cursor = @import("Cursor.zig");
const Key = @import("key.zig").Key; const Key = @import("key.zig").Key;
const Action = @import("action.zig").Action;
const Window = @This(); const Window = @This();
@ -47,9 +48,9 @@ pub const InternalUserPointer = struct {
setMaximizeCallback: ?fn (window: Window, maximized: bool) void, setMaximizeCallback: ?fn (window: Window, maximized: bool) void,
setFramebufferSizeCallback: ?fn (window: Window, width: isize, height: isize) void, setFramebufferSizeCallback: ?fn (window: Window, width: isize, height: isize) void,
setContentScaleCallback: ?fn (window: Window, xscale: f32, yscale: f32) void, setContentScaleCallback: ?fn (window: Window, xscale: f32, yscale: f32) void,
setKeyCallback: ?fn (window: Window, key: isize, scancode: isize, action: isize, mods: isize) void, setKeyCallback: ?fn (window: Window, key: isize, scancode: isize, action: Action, mods: isize) void,
setCharCallback: ?fn (window: Window, codepoint: u21) void, setCharCallback: ?fn (window: Window, codepoint: u21) void,
setMouseButtonCallback: ?fn (window: Window, button: isize, action: isize, mods: isize) void, setMouseButtonCallback: ?fn (window: Window, button: isize, action: Action, mods: isize) void,
setCursorPosCallback: ?fn (window: Window, xpos: f64, ypos: f64) void, setCursorPosCallback: ?fn (window: Window, xpos: f64, ypos: f64) void,
setCursorEnterCallback: ?fn (window: Window, entered: bool) void, setCursorEnterCallback: ?fn (window: Window, entered: bool) void,
setScrollCallback: ?fn (window: Window, xoffset: f64, yoffset: f64) void, setScrollCallback: ?fn (window: Window, xoffset: f64, yoffset: f64) void,
@ -1347,9 +1348,9 @@ pub inline fn getInputMode(self: Window, mode: isize) isize {
/// ///
/// If the mode is `glfw.sticky_mouse_buttons`, the value must be either `true` to enable sticky /// If the mode is `glfw.sticky_mouse_buttons`, the value must be either `true` to enable sticky
/// mouse buttons, or `false` to disable it. If sticky mouse buttons are enabled, a mouse button /// mouse buttons, or `false` to disable it. If sticky mouse buttons are enabled, a mouse button
/// press will ensure that glfw.Window.getMouseButton returns `glfw.press` the next time it is /// press will ensure that glfw.Window.getMouseButton returns `glfw.Action.press` the next time it
/// called even if the mouse button had been released before the call. This is useful when you are /// is called even if the mouse button had been released before the call. This is useful when you
/// only interested in whether mouse buttons have been pressed but not when or in which order. /// are only interested in whether mouse buttons have been pressed but not when or in which order.
/// ///
/// If the mode is `glfw.lock_key_mods`, the value must be either `true` to enable lock key modifier /// If the mode is `glfw.lock_key_mods`, the value must be either `true` to enable lock key modifier
/// bits, or `false` to disable them. If enabled, callbacks that receive modifier bits will also /// bits, or `false` to disable them. If enabled, callbacks that receive modifier bits will also
@ -1383,10 +1384,10 @@ pub inline fn setInputMode(self: Window, mode: isize, value: anytype) Error!void
/// ///
/// This function returns the last press state reported for the specified key to the specified /// This function returns the last press state reported for the specified key to the specified
/// window. The returned state is one of `true` (pressed) or `false` (released). The higher-level /// window. The returned state is one of `true` (pressed) or `false` (released). The higher-level
/// action `glfw.repeat` is only reported to the key callback. /// action `glfw.Action.repeat` is only reported to the key callback.
/// ///
/// If the `glfw.sticky_keys` input mode is enabled, this function returns `glfw.press` the first /// If the `glfw.sticky_keys` input mode is enabled, this function returns `glfw.Action.press` the
/// time you call it for a key that was pressed, even if that key has already been released. /// first time you call it for a key that was pressed, even if that key has already been released.
/// ///
/// The key functions deal with physical keys, with key tokens (see keys) named after their use on /// The key functions deal with physical keys, with key tokens (see keys) named after their use on
/// the standard US keyboard layout. If you want to input text, use the Unicode character callback /// the standard US keyboard layout. If you want to input text, use the Unicode character callback
@ -1399,17 +1400,16 @@ pub inline fn setInputMode(self: Window, mode: isize, value: anytype) Error!void
/// @param[in] window The desired window. /// @param[in] window The desired window.
/// @param[in] key The desired keyboard key (see keys). `glfw.key.unknown` is not a valid key for /// @param[in] key The desired keyboard key (see keys). `glfw.key.unknown` is not a valid key for
/// this function. /// this function.
/// @return `true` (pressed) or `false` (released)
/// ///
/// Possible errors include glfw.Error.NotInitialized and glfw.Error.InvalidEnum. /// Possible errors include glfw.Error.NotInitialized and glfw.Error.InvalidEnum.
/// ///
/// @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!bool { pub inline fn getKey(self: Window, key: Key) Error!Action {
const state = c.glfwGetKey(self.handle, @enumToInt(key)); const state = c.glfwGetKey(self.handle, @enumToInt(key));
try getError(); try getError();
return state == c.GLFW_PRESS; return @intToEnum(Action, state);
} }
/// Returns the last reported state of a mouse button for the specified window. /// Returns the last reported state of a mouse button for the specified window.
@ -1428,10 +1428,10 @@ pub inline fn getKey(self: Window, key: Key) Error!bool {
/// @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: isize) Error!bool { pub inline fn getMouseButton(self: Window, button: isize) Error!Action {
const state = c.glfwGetMouseButton(self.handle, @intCast(c_int, button)); const state = c.glfwGetMouseButton(self.handle, @intCast(c_int, button));
try getError(); try getError();
return state == c.GLFW_PRESS; return @intToEnum(Action, state);
} }
const CursorPos = struct { const CursorPos = struct {
@ -1524,7 +1524,7 @@ pub inline fn setCursor(self: Window, cursor: Cursor) Error!void {
fn setKeyCallbackWrapper(handle: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.C) void { fn setKeyCallbackWrapper(handle: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, mods: c_int) callconv(.C) void {
const window = from(handle.?) catch unreachable; const window = from(handle.?) catch unreachable;
const internal = window.getInternal(); const internal = window.getInternal();
internal.setKeyCallback.?(window, @intCast(isize, key), @intCast(isize, scancode), @intCast(isize, action), @intCast(isize, mods)); internal.setKeyCallback.?(window, @intCast(isize, key), @intCast(isize, scancode), @intToEnum(Action, action), @intCast(isize, mods));
} }
/// Sets the key callback. /// Sets the key callback.
@ -1554,14 +1554,14 @@ fn setKeyCallbackWrapper(handle: ?*c.GLFWwindow, key: c_int, scancode: c_int, ac
/// @callback_param[in] window The window that received the event. /// @callback_param[in] window The window that received the event.
/// @callback_param[in] key The keyboard key (see keys) that was pressed or released. /// @callback_param[in] key The keyboard key (see keys) that was pressed or released.
/// @callback_param[in] scancode The system-specific scancode of the key. /// @callback_param[in] scancode The system-specific scancode of the key.
/// @callback_param[in] action `glfw.press`, `glfw.release` or `glfw.repeat`. Future releases may /// @callback_param[in] action `glfw.Action.press`, `glfw.Action.release` or `glfw.Action.repeat`.
/// add more actions. /// Future releases may add more actions.
/// @callback_param[in] mods Bit field describing which modifier keys (see mods) were held down. /// @callback_param[in] mods Bit field describing which modifier keys (see mods) were held down.
/// ///
/// @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 setKeyCallback(self: Window, callback: ?fn (window: Window, key: isize, scancode: isize, action: isize, mods: isize) void) void { pub inline fn setKeyCallback(self: Window, callback: ?fn (window: Window, key: isize, scancode: isize, action: Action, mods: isize) void) void {
var internal = self.getInternal(); var internal = self.getInternal();
internal.setKeyCallback = callback; internal.setKeyCallback = callback;
_ = c.glfwSetKeyCallback(self.handle, if (callback != null) setKeyCallbackWrapper else null); _ = c.glfwSetKeyCallback(self.handle, if (callback != null) setKeyCallbackWrapper else null);
@ -1616,7 +1616,7 @@ pub inline fn setCharCallback(self: Window, callback: ?fn (window: Window, codep
fn setMouseButtonCallbackWrapper(handle: ?*c.GLFWwindow, button: c_int, action: c_int, mods: c_int) callconv(.C) void { fn setMouseButtonCallbackWrapper(handle: ?*c.GLFWwindow, button: c_int, action: c_int, mods: c_int) callconv(.C) void {
const window = from(handle.?) catch unreachable; const window = from(handle.?) catch unreachable;
const internal = window.getInternal(); const internal = window.getInternal();
internal.setMouseButtonCallback.?(window, @intCast(isize, button), @intCast(isize, action), @intCast(isize, mods)); internal.setMouseButtonCallback.?(window, @intCast(isize, button), @intToEnum(Action, action), @intCast(isize, mods));
} }
/// Sets the mouse button callback. /// Sets the mouse button callback.
@ -1634,14 +1634,14 @@ fn setMouseButtonCallbackWrapper(handle: ?*c.GLFWwindow, button: c_int, action:
/// ///
/// @callback_param[in] window The window that received the event. /// @callback_param[in] window The window that received the event.
/// @callback_param[in] button The mouse button that was pressed or released. /// @callback_param[in] button The mouse button that was pressed or released.
/// @callback_param[in] action One of `glfw.press` or `glfw.release`. Future releases may add more /// @callback_param[in] action One of `glfw.Action.press` or `glfw.Action.release`. Future releases
/// actions. /// may add more actions.
/// @callback_param[in] mods Bit field describing which modifier keys (see mods) were held down. /// @callback_param[in] mods Bit field describing which modifier keys (see mods) were held down.
/// ///
/// @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 setMouseButtonCallback(self: Window, callback: ?fn (window: Window, button: isize, action: isize, mods: isize) void) void { pub inline fn setMouseButtonCallback(self: Window, callback: ?fn (window: Window, button: isize, action: Action, mods: isize) void) void {
var internal = self.getInternal(); var internal = self.getInternal();
internal.setMouseButtonCallback = callback; internal.setMouseButtonCallback = callback;
_ = c.glfwSetMouseButtonCallback(self.handle, if (callback != null) setMouseButtonCallbackWrapper else null); _ = c.glfwSetMouseButtonCallback(self.handle, if (callback != null) setMouseButtonCallbackWrapper else null);
@ -2696,7 +2696,7 @@ test "setKeyCallback" {
defer window.destroy(); defer window.destroy();
window.setKeyCallback((struct { window.setKeyCallback((struct {
fn callback(_window: Window, key: isize, scancode: isize, action: isize, mods: isize) void { fn callback(_window: Window, key: isize, scancode: isize, action: Action, mods: isize) void {
_ = _window; _ = _window;
_ = key; _ = key;
_ = scancode; _ = scancode;
@ -2741,7 +2741,7 @@ test "setMouseButtonCallback" {
defer window.destroy(); defer window.destroy();
window.setMouseButtonCallback((struct { window.setMouseButtonCallback((struct {
fn callback(_window: Window, button: isize, action: isize, mods: isize) void { fn callback(_window: Window, button: isize, action: Action, mods: isize) void {
_ = _window; _ = _window;
_ = button; _ = button;
_ = action; _ = action;

View file

@ -2,11 +2,14 @@
const c = @import("c.zig").c; const c = @import("c.zig").c;
/// The key or mouse button was released. /// Holds all GLFW C action enumerations in their raw form.
pub const release = c.GLFW_RELEASE; pub const Action = enum(c_int) {
/// The key or mouse button was released.
release = c.GLFW_RELEASE,
/// The key or mouse button was pressed. /// The key or mouse button was pressed.
pub const press = c.GLFW_PRESS; press = c.GLFW_PRESS,
/// The key was held down until it repeated. /// The key was held down until it repeated.
pub const repeat = c.GLFW_REPEAT; repeat = c.GLFW_REPEAT,
};

View file

@ -23,10 +23,10 @@ const getError = @import("errors.zig").getError;
/// enum containing all glfw keys /// enum containing all glfw keys
pub const Key = enum(c_int) { pub const Key = enum(c_int) {
/// The unknown key /// The unknown key
unknown = cc.GLFW_KEY_UNKNOWN, unknown = cc.GLFW_KEY_UNKNOWN,
/// Printable keys /// Printable keys
space = cc.GLFW_KEY_SPACE, space = cc.GLFW_KEY_SPACE,
apostrophe = cc.GLFW_KEY_APOSTROPHE, apostrophe = cc.GLFW_KEY_APOSTROPHE,
comma = cc.GLFW_KEY_COMMA, comma = cc.GLFW_KEY_COMMA,
minus = cc.GLFW_KEY_MINUS, minus = cc.GLFW_KEY_MINUS,
@ -78,7 +78,7 @@ pub const Key = enum(c_int) {
world_2 = cc.GLFW_KEY_WORLD_2, // non-US #2 world_2 = cc.GLFW_KEY_WORLD_2, // non-US #2
// Function keys // Function keys
escape = cc.GLFW_KEY_ESCAPE, escape = cc.GLFW_KEY_ESCAPE,
enter = cc.GLFW_KEY_ENTER, enter = cc.GLFW_KEY_ENTER,
tab = cc.GLFW_KEY_TAB, tab = cc.GLFW_KEY_TAB,
backspace = cc.GLFW_KEY_BACKSPACE, backspace = cc.GLFW_KEY_BACKSPACE,
@ -153,7 +153,6 @@ pub const Key = enum(c_int) {
return @intToEnum(Key, cc.GLFW_KEY_LAST); return @intToEnum(Key, cc.GLFW_KEY_LAST);
} }
/// Returns the layout-specific name of the specified printable key. /// Returns the layout-specific name of the specified printable key.
/// ///
/// This function returns the name of the specified printable key, encoded as UTF-8. This is /// This function returns the name of the specified printable key, encoded as UTF-8. This is
@ -238,9 +237,8 @@ pub const Key = enum(c_int) {
} }
}; };
test "getName" { test "getName" {
const glfw = @import("main.zig"); const glfw = @import("main.zig");
try glfw.init(); try glfw.init();
defer glfw.terminate(); defer glfw.terminate();

View file

@ -9,7 +9,7 @@ pub usingnamespace @import("consts.zig");
pub const Error = @import("errors.zig").Error; pub const Error = @import("errors.zig").Error;
const getError = @import("errors.zig").getError; const getError = @import("errors.zig").getError;
pub const action = @import("action.zig"); pub const Action = @import("action.zig").Action;
pub const gamepad_axis = @import("gamepad_axis.zig"); pub const gamepad_axis = @import("gamepad_axis.zig");
pub const gamepad_button = @import("gamepad_button.zig"); pub const gamepad_button = @import("gamepad_button.zig");
pub const GammaRamp = @import("GammaRamp.zig"); pub const GammaRamp = @import("GammaRamp.zig");

View file

@ -7,7 +7,7 @@ const c = @import("c.zig").c;
// must be in sync with https://www.glfw.org/docs/3.3/group__mods.html // must be in sync with https://www.glfw.org/docs/3.3/group__mods.html
/// A bitmask of all key modifiers /// A bitmask of all key modifiers
pub const Mods = packed struct { pub const Mods = packed struct {
shift: bool align(@alignOf(c_int)) = false, shift: bool align(@alignOf(c_int)) = false,
control: bool = false, control: bool = false,
alt: bool = false, alt: bool = false,
super: bool = false, super: bool = false,
@ -34,7 +34,7 @@ pub const Mods = packed struct {
} }
}; };
/// Hold all glfw values as is /// Holds all GLFW mod values in their raw form.
pub const RawMods = struct { pub const RawMods = struct {
/// If this bit is set one or more Shift keys were held down. /// If this bit is set one or more Shift keys were held down.
pub const shift = c.GLFW_MOD_SHIFT; pub const shift = c.GLFW_MOD_SHIFT;
@ -55,7 +55,6 @@ pub const RawMods = struct {
pub const num_lock = c.GLFW_MOD_NUM_LOCK; pub const num_lock = c.GLFW_MOD_NUM_LOCK;
}; };
test "shift int to bitmask" { test "shift int to bitmask" {
const std = @import("std"); const std = @import("std");
@ -112,13 +111,12 @@ test "num lock int to bitmask" {
std.testing.expect(mod.num_lock == true); std.testing.expect(mod.num_lock == true);
} }
test "all int to bitmask" { test "all int to bitmask" {
const std = @import("std"); const std = @import("std");
const int_mod = RawMods.shift | RawMods.control | const int_mod = RawMods.shift | RawMods.control |
RawMods.alt | RawMods.super | RawMods.alt | RawMods.super |
RawMods.caps_lock | RawMods.num_lock; RawMods.caps_lock | RawMods.num_lock;
const mod = Mods.fromInt(int_mod); const mod = Mods.fromInt(int_mod);
std.testing.expect(mod.shift == true); std.testing.expect(mod.shift == true);
@ -150,7 +148,7 @@ test "shift and alt bitmask to int" {
test "all bitmask to int" { test "all bitmask to int" {
const std = @import("std"); const std = @import("std");
const mod = Mods{ const mod = Mods{
.shift = true, .shift = true,
.control = true, .control = true,
.alt = true, .alt = true,
@ -160,9 +158,9 @@ test "all bitmask to int" {
}; };
const int_mod = mod.toInt(c_int); const int_mod = mod.toInt(c_int);
const expected = RawMods.shift | RawMods.control | const expected = RawMods.shift | RawMods.control |
RawMods.alt | RawMods.super | RawMods.alt | RawMods.super |
RawMods.caps_lock | RawMods.num_lock; RawMods.caps_lock | RawMods.num_lock;
std.testing.expectEqual(int_mod, expected); std.testing.expectEqual(int_mod, expected);
} }