initial commit
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 30s

This commit is contained in:
2024-11-09 21:24:42 +01:00
parent ff58e7ef69
commit 6d389bcd4b
21 changed files with 2738 additions and 0 deletions

78
src/widget.zig Normal file
View File

@@ -0,0 +1,78 @@
//! Dynamic dispatch for widget implementations.
//! Each widget should at last implement these functions:
//! - handle(this: *@This(), event: Event) ?Event {}
//! - content(this: *@This()) ![]u8 {}
//! - deinit(this: *@This()) void {}
//!
//! Create a `Widget` using `createFrom(object: anytype)` and use them through
//! the defined interface. The widget will take care of calling the correct
//! implementation of the corresponding underlying type.
//!
//! Each `Widget` may cache its content and should if the contents will not
//! change for a long time.
const isTaggedUnion = @import("event.zig").isTaggedUnion;
pub fn Widget(comptime Event: type) type {
if (!isTaggedUnion(Event)) {
@compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`.");
}
return struct {
const WidgetType = @This();
const Ptr = usize;
const VTable = struct {
handle: *const fn (this: *WidgetType, event: Event) ?Event,
content: *const fn (this: *WidgetType) anyerror![]u8,
deinit: *const fn (this: *WidgetType) void,
};
object: Ptr = undefined,
vtable: *const VTable = undefined,
// Handle the provided `Event` for this `Widget`.
pub fn handle(this: *WidgetType, event: Event) ?Event {
return this.vtable.handle(this, event);
}
// Return the entire content of this `Widget`.
pub fn content(this: *WidgetType) ![]u8 {
return try this.vtable.content(this);
}
pub fn deinit(this: *WidgetType) void {
this.vtable.deinit(this);
this.* = undefined;
}
pub fn createFrom(object: anytype) WidgetType {
return WidgetType{
.object = @intFromPtr(object),
.vtable = &.{
.handle = struct {
// Handle the provided `Event` for this `Widget`.
fn handle(this: *WidgetType, event: Event) ?Event {
const widget: @TypeOf(object) = @ptrFromInt(this.object);
return widget.handle(event);
}
}.handle,
.content = struct {
// Return the entire content of this `Widget`.
fn content(this: *WidgetType) ![]u8 {
const widget: @TypeOf(object) = @ptrFromInt(this.object);
return try widget.content();
}
}.content,
.deinit = struct {
fn deinit(this: *WidgetType) void {
const widget: @TypeOf(object) = @ptrFromInt(this.object);
widget.deinit();
}
}.deinit,
},
};
}
// TODO: import and export of `Widget` implementations (with corresponding intialization using `Event`)
pub const RawText = @import("widget/RawText.zig").Widget(Event);
};
}