Hello, I’m new to Zig (not programming) and the manual memory allocation thingie.
I’m in the process of building a GUI library in Zig utilizing Mitchell’s wonderful zig-objc
library.
Got memory management figured out and many things seem to work nicely.
This GUI library uses native UI controls and currently works on macOS and iOS-Simulator (iPhone/iPad).
The user of this library will be able to build the UI and never mind the memory allocation the UI entities need. Every UI control has its defer
→ deinit
function for cleaning up the used memory at app termination.
Now to my question about the preferred Zig library structure/logic as I realize that Zig users want 100% control over memory allocations:
Would Zig users even use such a library if the memory allocation stuff is done in the background (inside the library) ?
Asking, because from a UI building point of view, dealing with memory for the GUI is always the same (Application, Window, Button, Label, etc.) and can get quite boring.
If it is preferred that the user of this library has to allocate the memory, I would have to take that code out of the library and make it available to the user.
Which would not be my preferred thing to do as I prefer the memory allocation inside the library, but…
It would be nice if the Zig community could let me know, because I would like to have this sorted
before I push my code to Github or somewhere else for public consumption. (Is Github the preferred repo of Zig users?)
Here a simple hello world app utilizing my library named zignui
(the gn
is pronounced like the Italian gnocchi
and it stands for zig native user interface
.
(zui
and zigui
are already in use on Github by zig users, and I did not come up with a better name… sorry…)
const std = @import("std");
const ui = @import("zignui");
pub fn main() !void {
std.log.info("Starting Hello ZIGNUI Library application...", .{});
// Initialize application
var app = ui.Application("com.example.zignui-hello", .regular) catch |err| {
std.log.err("Failed to initialize application: {}", .{err});
return err;
};
app.quitOnLastWindowClosed(true);
std.log.info("Application initialized successfully", .{});
app.setGUIInitializer(gui_init);
std.log.info("Graphical user interface initialized successfully", .{});
// Run the application event loop
app.run();
std.log.info("Application terminated successfully", .{});
}
fn gui_init(app: anytype) !void {
// Create main window
const win_rect = ui.Rect(100, 100, 500, 400); // size is for macOS
var win = app.Window("main_window", win_rect) catch |err| {
std.log.err("Error in createWindow: {}", .{err});
return;
};
win.setTitle("Hello Zui Library!");
win.center();
// Show the window
win.show();
}
The app.setGUIInitializer
function is needed as it helps a lot with iOS UIScene stuff (which is the preferred iOS way nowadays) and also helps later with having different sizes (or whatever) for different operating systems.
This code compiles for macOS and iOS-simulator as a target utilizing a tool I wrote (ZAC - zig application creator) which uses zig and creates subfolders in the zig-out
folder named after the target: aarch64-macos
or aarch64-ios-simulator
and generates the app
for macOS and a different app
for the iOS simulator (they have different internal structures).
Of course ZAC
will be released alongside the ZIGNUI
library to facilitate the creation of Apple operating system apps.
(did not master the deployment of iOS apps on real iPhones yet, as it is quite cumbersome, but in the future Zac
should handle this as well…)
There are certainly many things that still need to be done, and my hope is that many Zig users are interested in such a library and are willing to spend their time helping/extending/maintaining it.
BTW: As you already might have recognized, Zignui (or ZIGNUI / zignui…) uses a high-level, platform-agnostic, imperative syntax and not a declarative syntax like most new UI libraries in use today. Why? Because I don’t like the declarative syntax stuff… sorry.
ALSO: Maybe I should add that the library already has several view controls like WebView
, MediaView
and GraphicView
controls.
The GraphicView
control uses Apples Metal
framework for macOS and iOS and it can show the usual multicolor triangle for both operating systems. (the sizing on iOS is still wrong, but I’m working on it…)
This GraphicView
control uses its own event loop for drawing things separate from the application GUI.
Please let me know about the memory allocation question… very much appreciated.
Thanks for reading.