Zig UI demo #154
Loading…
Reference in New Issue
No description provided.
Delete Branch "ilidemi/orca:zig-ui"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tried to make it as zig as possible but my knowledge is far from perfect. Nitpicks are welcome.
Notes:
Zig bindings thoughts
[]const u8
or[]u8
-based.oc_on_raw_event
now takes C-style event which has a conversion method to a Zig-style one. If we provide language-specific event handlers that could be nicer (along with camelCase naming) but not sure if it's possible to only wrap the ones that are defined in the user code.14bd0880e6
to47cba86c03
@ -1443,1 +1486,3 @@
Count = 349,
};
pub const key_code_count: usize = 349;
Might want this to be some sort of comptime thing where it looks up the last field of the enum and uses that value instead of hardcoding it. Something like this:
@ -1451,10 +1505,111 @@ pub const MouseButton = enum(c_uint) {
Ext2 = 0x04,
};
pub const mouse_button_count: usize = 5;
Same as key_code_count above
Thanks a ton, this is obviously a lot of work! Still reading through the changes, I'll try to finish it up sometime tonight.
re your notes:
oc_str8/16/32
, it should be transparent. This will also pair nicely with a change I've been thinking about making to the APIs where any function that takes aoc_str
gets a zig wrapper function that takes a slice and converts it internally to make them more ergonomic.Str8.pushBuffer()
is trying to do whatArena.pushStr()
does, although it goes the extra mile of wrapping it in aStr8
. I think duplicating the functionality is fine, and null-terminating it is probably good as well since I suspect some of the C APIs used internally expect null-terminated strings. fwiw zig string literals are null-terminated as well.orca.zig
, then use them as trampolines to zig-native event handlers defined in userland. I haven't tried this yet because I hadn't seen a compelling reason yet, but looking at the@export
documentation I suspect it's possible: https://ziglang.org/documentation/0.11.0/#exportAllocError
: "calling widgets would become even more convoluted". I was originally using nulls to signal alloc failure like Orca does but then realized zig's error system would be a more natural fit. Do you think theAllocError
approach doesn't fit well with the UI system? Or should we go back to using nulls?@ -0,0 +166,4 @@
fn widgets(arena: *oc.Arena) void {
columnBegin("Widgets", 1.0 / 3.0);
defer columnEnd();
What do you think about putting the ui and column prefixed functions into a
ui
struct to namespace them and make it a bit clearer they are intended to be used together?Good suggestion!
@ -1695,1 +1852,4 @@
pub fn array(rect: *Rect) *[4]f32 {
return @ptrCast(rect);
}
Nice, I like these changes. Makes it a lot easier to work with the base rect but keeps the other "views" of the data around.
This one is on UI rather than on the bindings.
AllocError
is great, it's just the UI layer operates under assumption that 1MB of memory is enough and doesn't handle/propagate errors, even in C. With error propagation, box making would become even more noisy (_ = try ui.boxBegin("content", .{});
) and functions likeui.panelEnd()
would be un-deferrable becausetry
is not allowed there. I guess we'd need to document that UI expects memory to be available and add asserts where it is allocated.This isn't quite true. Arenas grow as long as we can give them more memory. So for wasm32 allocations will fail somewhere a bit under 4GB, with an out of memory assertion managed by the runtime. Virtual memory backed arenas on wasm64 could grow much larger. But the main idea is that if you fill your whole address space, there's not much we can do except displaying an OOM message box and closing the program.
Sorry I wasn't clear, yes the UI will happily take up as much address space as needed and available. I'm pointing at a discrepancy between how arenas explicitly return an error to the user and UI doesn't check the allocation results at all, for example in the chain from
oc_ui_box_make_str8
tooc_arena_chunk_alloc
. If we expect the runtime to abort on allocation errors, the wasm side doesn't need to worry aboutAllocError
s at all (at the expense of being less systems-y). If I understand the code correctly, the runtime will abort when running out of wasm address space and (at least on win32) will silently drop the error ifVirtualAlloc(MEM_COMMIT)
fails, so actually there isn't a case where the wasm side has to handle a null.@ -1848,0 +3269,4 @@
text: []u8,
};
pub fn textBox(name: []const u8, arena: Arena, text: []const u8) TextBoxResult {
I think this
Arena
needs to be a pointer. Same on 3195Good catch!
@ -1848,0 +2797,4 @@
theme: *Theme,
extern fn oc_ui_init(context: *Context) void;
pub const init = oc_ui_init;
Zig style usually has the init function take either no arguments or some config options. In this case, maybe we can provide a wrapper function that returns a new
Context
by value after callingoc_ui_init()
on it, so that all the user has to do is:Here the address of ui_ctx is important. Moved init outside of the Context.
Re: the alloc stuff. It sounds like in that case the Zig bindings should just always assume valid memory will be returned from Arena allocs, since if Orca OOMs, it will be "handled" on the native side via a shutdown. So I can just remove
AllocError
.