From 7849fbf29ea612be1101e8f413824c05dd7f953a Mon Sep 17 00:00:00 2001 From: Aksel Hjerpbakk Date: Mon, 18 Oct 2021 22:19:25 +0200 Subject: [PATCH] glfw: support multiple types from glfw.Window.hint (#32) * glfw #29: support multiple types from glfw.Window.hint * use 'got' instead of 'not' in error messages --- glfw/src/Window.zig | 138 ++++++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 36 deletions(-) diff --git a/glfw/src/Window.zig b/glfw/src/Window.zig index 6db61f0..6e62bb3 100644 --- a/glfw/src/Window.zig +++ b/glfw/src/Window.zig @@ -34,9 +34,6 @@ pub inline fn defaultHints() Error!void { /// their values until changed by a call to this function or glfw.window.defaultHints, or until the /// library is terminated. /// -/// Only integer value hints can be set with this function. String value hints are set with -/// glfw.Window.hintString. -/// /// This function does not check whether the specified hint values are valid. If you set hints to /// invalid values this will instead be reported by the next call to glfw.createWindow. /// @@ -45,39 +42,49 @@ pub inline fn defaultHints() Error!void { /// /// Possible errors include glfw.Error.NotInitialized and glfw.Error.InvalidEnum. /// +/// @pointer_lifetime in the event that value is of a str type, the specified string is copied before this function returns. +/// /// @thread_safety This function must only be called from the main thread. /// -/// see also: window_hints, glfw.Window.hintString, glfw.Window.defaultHints -pub inline fn hint(hint_const: usize, value: isize) Error!void { - c.glfwWindowHint(@intCast(c_int, hint_const), @intCast(c_int, value)); - try getError(); -} +/// see also: window_hints, glfw.Window.defaultHints +pub inline fn hint(hint_const: usize, value: anytype) Error!void { + const value_type = @TypeOf(value); + const value_type_info: std.builtin.TypeInfo = @typeInfo(value_type); -/// Sets the specified window hint to the desired value. -/// -/// This function sets hints for the next call to glfw.Window.create. The hints, once set, retain -/// their values until changed by a call to this function or glfw.Window.defaultHints, or until the -/// library is terminated. -/// -/// Only string type hints can be set with this function. Integer value hints are set with -/// glfw.Window.hint. -/// -/// This function does not check whether the specified hint values are valid. If you set hints to -/// invalid values this will instead be reported by the next call to glfw.window.create. -/// -/// Some hints are platform specific. These may be set on any platform but they will only affect -/// their specific platform. Other platforms will ignore them. Setting these hints requires no -/// platform specific headers or functions. -/// -/// Possible errors include glfw.Error.NotInitialized and glfw.Error.InvalidEnum. -/// -/// @pointer_lifetime The specified string is copied before this function returns. -/// -/// @thread_safety This function must only be called from the main thread. -/// -/// see also: window_hints, glfw.Window.hint, glfw.Window.defaultHints -pub inline fn hintString(hint_const: usize, value: [:0]const u8) Error!void { - c.glfwWindowHintString(@intCast(c_int, hint_const), &value[0]); + switch (value_type_info) { + .Int, .ComptimeInt => { + c.glfwWindowHint(@intCast(c_int, hint_const), @intCast(c_int, value)); + }, + .Bool => { + const int_value = @boolToInt(value); + c.glfwWindowHint(@intCast(c_int, hint_const), @intCast(c_int, int_value)); + }, + .Enum => { + const int_value = @enumToInt(value); + c.glfwWindowHint(@intCast(c_int, hint_const), @intCast(c_int, int_value)); + }, + .Array => |arr_type| { + if (arr_type.child != u8) { + @compileError("expected array of u8, got " ++ @typeName(arr_type)); + } + c.glfwWindowHintString(@intCast(c_int, hint_const), &value[0]); + }, + .Pointer => |pointer_info| { + const pointed_type = @typeInfo(pointer_info.child); + switch (pointed_type) { + .Array => |arr_type| { + if (arr_type.child != u8) { + @compileError("expected pointer to array of u8, got " ++ @typeName(arr_type)); + } + }, + else => @compileError("expected pointer to array, got " ++ @typeName(pointed_type)), + } + c.glfwWindowHintString(@intCast(c_int, hint_const), &value[0]); + }, + else => { + @compileError("expected a int, bool, enum, array, or pointer, got " ++ @typeName(value_type)); + } + } try getError(); } @@ -1359,7 +1366,7 @@ test "defaultHints" { try defaultHints(); } -test "hint" { +test "hint comptime int" { const glfw = @import("main.zig"); try glfw.init(); defer glfw.terminate(); @@ -1368,12 +1375,71 @@ test "hint" { try defaultHints(); } -test "hintString" { +test "hint int" { const glfw = @import("main.zig"); try glfw.init(); defer glfw.terminate(); - try hintString(glfw.x11_class_name, "myclass"); + var focused: i32 = 1; + + try hint(glfw.focused, focused); + try defaultHints(); +} + +test "hint bool" { + const glfw = @import("main.zig"); + try glfw.init(); + defer glfw.terminate(); + + try hint(glfw.focused, true); + try defaultHints(); +} + +test "hint enum(u1)" { + const glfw = @import("main.zig"); + try glfw.init(); + defer glfw.terminate(); + + const MyEnum = enum(u1) { + @"true" = 1, + @"false" = 0, + }; + + try hint(glfw.focused, MyEnum.@"true"); + try defaultHints(); +} + +test "hint enum(i32)" { + const glfw = @import("main.zig"); + try glfw.init(); + defer glfw.terminate(); + + const MyEnum = enum(i32) { + @"true" = 1, + @"false" = 0, + }; + + try hint(glfw.focused, MyEnum.@"true"); + try defaultHints(); +} + +test "hint array str" { + const glfw = @import("main.zig"); + try glfw.init(); + defer glfw.terminate(); + + const str_arr = [_]u8{ 'm', 'y', 'c', 'l', 'a', 's', 's' }; + + try hint(glfw.x11_class_name, str_arr); + try defaultHints(); +} + +test "hint pointer str" { + const glfw = @import("main.zig"); + try glfw.init(); + defer glfw.terminate(); + + try hint(glfw.x11_class_name, "myclass"); } test "createWindow" {