mod: use allocators for Layout and Widget types

This commit is contained in:
2024-11-19 22:56:37 +01:00
parent cd12fb12e6
commit 1c703a196a
18 changed files with 264 additions and 153 deletions

View File

@@ -10,6 +10,7 @@
//!
//! When `Widget.render` is called the provided `Renderer` type is expected
//! which handles how contents are rendered for a given widget.
const std = @import("std");
const isTaggedUnion = @import("event.zig").isTaggedUnion;
const log = @import("std").log.scoped(.widget);
@@ -32,6 +33,7 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
deinit: *const fn (this: *WidgetType) void,
};
allocator: std.mem.Allocator = undefined,
object: *anyopaque = undefined,
vtable: *const VTable = undefined,
@@ -58,34 +60,36 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
pub fn deinit(this: *WidgetType) void {
this.vtable.deinit(this);
this.allocator.destroy(this);
}
pub fn createFrom(object: anytype) WidgetType {
return WidgetType{
.object = @ptrCast(@alignCast(object)),
.vtable = &.{
.handle = struct {
// Handle the provided `Event` for this `Widget`.
fn handle(this: *WidgetType, event: Event) ?Event {
const widget: @TypeOf(object) = @ptrCast(@alignCast(this.object));
return widget.handle(event);
}
}.handle,
.render = struct {
// Return the entire content of this `Widget`.
fn render(this: *WidgetType, renderer: *Renderer) !void {
const widget: @TypeOf(object) = @ptrCast(@alignCast(this.object));
try widget.render(renderer);
}
}.render,
.deinit = struct {
fn deinit(this: *WidgetType) void {
const widget: @TypeOf(object) = @ptrCast(@alignCast(this.object));
widget.deinit();
}
}.deinit,
},
pub fn createFrom(allocator: std.mem.Allocator, object: anytype) *WidgetType {
const widget = allocator.create(WidgetType) catch @panic("widget.zig: out of memory");
widget.allocator = allocator;
widget.object = @ptrCast(object);
widget.vtable = &.{
.handle = struct {
// Handle the provided `Event` for this `Widget`.
fn handle(this: *WidgetType, event: Event) ?Event {
const widget_ptr: @TypeOf(object) = @ptrCast(@alignCast(this.object));
return widget_ptr.handle(event);
}
}.handle,
.render = struct {
// Return the entire content of this `Widget`.
fn render(this: *WidgetType, renderer: *Renderer) !void {
const widget_ptr: @TypeOf(object) = @ptrCast(@alignCast(this.object));
try widget_ptr.render(renderer);
}
}.render,
.deinit = struct {
fn deinit(this: *WidgetType) void {
const widget_ptr: @TypeOf(object) = @ptrCast(@alignCast(this.object));
widget_ptr.deinit();
}
}.deinit,
};
return widget;
}
// import and export of `Widget` implementations