feat(model): implement Elm architecture
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 1m2s
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 1m2s
Now the `App` contains a state which is a user-defined `struct` which is passed to the `handle` and `contents` callbacks for `Container`'s and `Element`'s. Built-in `Element`'s shall not access the `App.Model` and should therefore never cause any side-effects. User-defined events shall be used to act as *messages* to cause potential side-effects for the model. This is the reason why only the `handle` callback has a non-const pointer to the `App.Model`. The `contents` callback can only access the `App.Model` read-only to use for generating the *view* (in context of the elm architecture).
This commit is contained in:
+14
-3
@@ -21,14 +21,17 @@ pub const SystemEvent = union(enum) {
|
||||
key: Key,
|
||||
/// Mouse input event
|
||||
mouse: Mouse,
|
||||
/// Focus event for mouse interaction
|
||||
/// TODO this should instead be a union with a `Size` to derive which container / element the focus meant for
|
||||
/// Focus event indicating that the application has gained the focus of the user
|
||||
focus: bool,
|
||||
};
|
||||
|
||||
/// Merge the two provided `union(enum)` `A` and `B` to a tagged union containing all fields of both tagged unions in `comptime`.
|
||||
/// Declarations are not supported for `comptime` created types, see https://github.com/ziglang/zig/issues/6709 for details.
|
||||
pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type {
|
||||
// TODO maybe it makes sense to have a nested tagged union type (i.e. system: union(enum) and event: union(enum))
|
||||
// - allows re-definition of system / built-in events
|
||||
// - clearly shows which events are system / built-in ones and which are user defined events
|
||||
// - the memory footprint for the nesting is not really harmful
|
||||
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;
|
||||
@@ -93,7 +96,7 @@ pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type {
|
||||
} });
|
||||
}
|
||||
|
||||
/// Determine at whether the provided type `T` is a tagged union: `union(enum)`.
|
||||
/// Determine whether the provided type `T` is a tagged union: `union(enum)`.
|
||||
pub fn isTaggedUnion(comptime T: type) bool {
|
||||
switch (@typeInfo(T)) {
|
||||
.@"union" => |u| if (u.tag_type) |_| {} else {
|
||||
@@ -104,6 +107,14 @@ pub fn isTaggedUnion(comptime T: type) bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Determine whether the provided type `T` is a `struct`.
|
||||
pub fn isStruct(comptime T: type) bool {
|
||||
return switch (@typeInfo(T)) {
|
||||
.@"struct" => |_| true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const input = @import("input.zig");
|
||||
const terminal = @import("terminal.zig");
|
||||
|
||||
Reference in New Issue
Block a user