Skip to content

Instantly share code, notes, and snippets.

@floooh
Created August 7, 2020 20:45
Show Gist options
  • Save floooh/868d3ac4ac001398d681e02f84a2817d to your computer and use it in GitHub Desktop.
Save floooh/868d3ac4ac001398d681e02f84a2817d to your computer and use it in GitHub Desktop.
sokol-gfx comptime option-bag initialization with Zig
const std = @import("std");
const warn = std.debug.warn;
const sg = @import("sokol_gfx.zig");
pub fn main() void {
var pass_action = make_pass_action(.{
.colors = .{
.{ .action = .CLEAR, .val = .{ 1.0, 0.0, 0.0, 1.0 } },
.{ .action = .CLEAR, .val = .{ 0.0, 1.0, 0.0, 1.0 } },
.{ .action = .DONTCARE }
},
.depth = .{ .action = .CLEAR, .val = 1.0, },
});
for (pass_action.colors) |item, i| {
warn("color {}: action={}, rgba={},{},{},{}\n", .{ i, item.action, item.val[0], item.val[1], item.val[2], item.val[3]});
}
}
// return a PassAction struct initialized from option bag
fn make_pass_action(options: anytype) sg.PassAction {
var pass_action: sg.PassAction = .{ };
init_with(&pass_action, options);
return pass_action;
}
// a generic option-bag initialization function
fn init_with(target_ptr: anytype, opts: anytype) void {
const opts_info = @typeInfo(@TypeOf(opts));
const target_type = @TypeOf(target_ptr.*);
switch (@typeInfo(target_type)) {
.Struct => {
inline for (opts_info.Struct.fields) |field| {
if (@hasField(target_type, field.name)) {
switch (@typeInfo(@TypeOf(@field(target_ptr.*, field.name)))) {
.Array => {
inline for (@field(opts, field.name)) |item, i| {
init_with(&@field(target_ptr.*, field.name)[i], @field(opts, field.name)[i]);
}
},
.Struct => {
init_with(&@field(target_ptr.*, field.name), @field(opts, field.name));
},
else => {
@field(target_ptr.*, field.name) = @field(opts, field.name);
},
}
}
else {
@compileError("No field '" ++ field.name ++ "' in '" ++ @typeName(target_type) ++ "'!\n");
}
}
},
else => {
target_ptr.* = opts;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment