initial commit
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 30s
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 30s
This commit is contained in:
83
src/event.zig
Normal file
83
src/event.zig
Normal file
@@ -0,0 +1,83 @@
|
||||
//! Events which are defined by the library. They might be extended by user
|
||||
//! events. See `App` for more details about user defined events.
|
||||
const std = @import("std");
|
||||
const terminal = @import("terminal.zig");
|
||||
|
||||
const Size = terminal.Size;
|
||||
const Key = terminal.Key;
|
||||
|
||||
pub const Error = struct {
|
||||
err: anyerror,
|
||||
msg: []const u8,
|
||||
};
|
||||
|
||||
// System events available to every application.
|
||||
pub const SystemEvent = union(enum) {
|
||||
quit,
|
||||
err: Error,
|
||||
resize: Size,
|
||||
key: Key,
|
||||
};
|
||||
|
||||
pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type {
|
||||
if (!isTaggedUnion(A) or !isTaggedUnion(B)) {
|
||||
@compileError("Both types for merging tagged unions need to be of type `union(enum)`.");
|
||||
}
|
||||
const a_fields = @typeInfo(A).Union.fields;
|
||||
const a_fields_tag = @typeInfo(A).Union.tag_type.?;
|
||||
const a_enum_fields = @typeInfo(a_fields_tag).Enum.fields;
|
||||
const b_fields = @typeInfo(B).Union.fields;
|
||||
const b_fields_tag = @typeInfo(B).Union.tag_type.?;
|
||||
const b_enum_fields = @typeInfo(b_fields_tag).Enum.fields;
|
||||
var fields: [a_fields.len + b_fields.len]std.builtin.Type.UnionField = undefined;
|
||||
var enum_fields: [a_fields.len + b_fields.len]std.builtin.Type.EnumField = undefined;
|
||||
var i: usize = 0;
|
||||
for (a_fields, a_enum_fields) |field, enum_field| {
|
||||
fields[i] = field;
|
||||
var enum_f = enum_field;
|
||||
enum_f.value = i;
|
||||
enum_fields[i] = enum_f;
|
||||
i += 1;
|
||||
}
|
||||
for (b_fields, b_enum_fields) |field, enum_field| {
|
||||
fields[i] = field;
|
||||
var enum_f = enum_field;
|
||||
enum_f.value = i;
|
||||
enum_fields[i] = enum_f;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
const log2_i = @bitSizeOf(@TypeOf(i)) - @clz(i);
|
||||
|
||||
const EventType = @Type(.{ .Int = .{
|
||||
.signedness = .unsigned,
|
||||
.bits = log2_i,
|
||||
} });
|
||||
|
||||
const Event = @Type(.{ .Enum = .{
|
||||
.tag_type = EventType,
|
||||
.fields = enum_fields[0..],
|
||||
.decls = &.{},
|
||||
.is_exhaustive = true,
|
||||
} });
|
||||
|
||||
return @Type(.{ .Union = .{
|
||||
.layout = .auto,
|
||||
.tag_type = Event,
|
||||
.fields = fields[0..],
|
||||
.decls = &.{},
|
||||
} });
|
||||
}
|
||||
|
||||
// Determine at `comptime` wether the provided type `E` is an `union(enum)`.
|
||||
pub fn isTaggedUnion(comptime E: type) bool {
|
||||
switch (@typeInfo(E)) {
|
||||
.Union => |u| {
|
||||
if (u.tag_type) |_| {} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
else => return false,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user