81 lines
3.3 KiB
Zig
81 lines
3.3 KiB
Zig
//! Dynamic dispatch for layout implementations.
|
|
//! Each layout should at last implement these functions:
|
|
//! - handle(this: *@This(), event: Event) anyerror!*std.ArrayList(Event) {}
|
|
//! - content(this: *@This()) anyerror!*std.ArrayList(u8) {}
|
|
//! - deinit(this: *@This()) void {}
|
|
//!
|
|
//! Create a `Layout` using `createFrom(object: anytype)` and use them through
|
|
//! the defined interface. The layout will take care of calling the correct
|
|
//! implementation of the corresponding underlying type.
|
|
//!
|
|
//! Each `Layout` is responsible for clearing the allocated memory of the used
|
|
//! widgets when deallocated. This means that `deinit()` will also deallocate
|
|
//! every used widget too.
|
|
const std = @import("std");
|
|
const lib_event = @import("event.zig");
|
|
|
|
pub fn Layout(comptime Event: type) type {
|
|
if (!lib_event.isTaggedUnion(Event)) {
|
|
@compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`.");
|
|
}
|
|
return struct {
|
|
const LayoutType = @This();
|
|
const Ptr = usize;
|
|
|
|
const VTable = struct {
|
|
handle: *const fn (this: *LayoutType, event: Event) anyerror!*std.ArrayList(Event),
|
|
content: *const fn (this: *LayoutType) anyerror!*std.ArrayList(u8),
|
|
deinit: *const fn (this: *LayoutType) void,
|
|
};
|
|
|
|
object: Ptr = undefined,
|
|
vtable: *const VTable = undefined,
|
|
|
|
// Handle the provided `Event` for this `Widget`.
|
|
pub fn handle(this: *LayoutType, event: Event) !*std.ArrayList(Event) {
|
|
return try this.vtable.handle(this, event);
|
|
}
|
|
|
|
// Return the entire content of this `Widget`.
|
|
pub fn content(this: *LayoutType) !*std.ArrayList(u8) {
|
|
return try this.vtable.content(this);
|
|
}
|
|
|
|
pub fn deinit(this: *LayoutType) void {
|
|
this.vtable.deinit(this);
|
|
this.* = undefined;
|
|
}
|
|
|
|
pub fn createFrom(object: anytype) LayoutType {
|
|
return LayoutType{
|
|
.object = @intFromPtr(object),
|
|
.vtable = &.{
|
|
.handle = struct {
|
|
// Handle the provided `Event` for this `Widget`.
|
|
fn handle(this: *LayoutType, event: Event) !*std.ArrayList(Event) {
|
|
const layout: @TypeOf(object) = @ptrFromInt(this.object);
|
|
return try layout.handle(event);
|
|
}
|
|
}.handle,
|
|
.content = struct {
|
|
// Return the entire content of this `Widget`.
|
|
fn content(this: *LayoutType) !*std.ArrayList(u8) {
|
|
const layout: @TypeOf(object) = @ptrFromInt(this.object);
|
|
return try layout.content();
|
|
}
|
|
}.content,
|
|
.deinit = struct {
|
|
fn deinit(this: *LayoutType) void {
|
|
const layout: @TypeOf(object) = @ptrFromInt(this.object);
|
|
layout.deinit();
|
|
}
|
|
}.deinit,
|
|
},
|
|
};
|
|
}
|
|
|
|
// import and export of `Layout` implementations
|
|
pub const Pane = @import("layout/Pane.zig").Layout(Event);
|
|
};
|
|
}
|