feat: update to c3 0.8.2

This commit is contained in:
Alessandro Mauri 2026-07-29 01:26:16 +02:00
parent 59eb5ff636
commit e899260b27
9 changed files with 64 additions and 87 deletions

View File

@ -1,37 +0,0 @@
{
"Debug": {
"build": [
{
"args": "-j8",
"command": "make",
"working_dir": ""
}
],
"build_types": [],
"clean": [
{
"args": "clean",
"command": "c3c",
"working_dir": ""
}
],
"config": {
"clear_sys_env": false
},
"os": [],
"output_parser": {
"config": {
"preset": "generic",
"relative_file_paths": true
}
},
"run": [
{
"args": "",
"command": "build/ugui",
"name": "Custom Executable",
"working_dir": ""
}
]
}
}

@ -1 +1 @@
Subproject commit 64d168f53b0fe70bda77e2ed7bec35f3f0f1af78 Subproject commit fedf67ecfe4fcfa6ea617a03628d51c1657f8da2

@ -1 +0,0 @@
Subproject commit e7356df5d1d0c22a6bba822bda6994062b0b75d7

BIN
lib/sdl3.c3l Normal file

Binary file not shown.

@ -1 +1 @@
Subproject commit 60bec17d36aa2fd1bddb3ffd4413bbfe867b6716 Subproject commit 1584b04fd31490967fd53c95af57b516e5e99cdc

@ -1 +1 @@
Subproject commit 050624fd67c2d80190114c7774ccfa64b0f449b9 Subproject commit 6c2f3fc2834a439bab4adaf1194ee0789edacb82

View File

@ -1,12 +1,12 @@
{ {
"langrev": "1", "langrev": "1",
"warnings": ["no-unused"], "warnings": [ "no-unused" ],
"dependency-search-paths": ["lib"], "dependency-search-paths": [ "lib" ],
"dependencies": ["ugui", "ugui_sdl3"], "dependencies": [ "ugui", "ugui_sdl3", "sdl3", "schrift" ],
"features": ["DEBUG_POINTER"], "features": [ "DEBUG_POINTER" ],
"authors": ["Alessandro Mauri <ale@shitposting.expert>"], "authors": [ "Alessandro Mauri <ale@shitposting.expert>" ],
"version": "0.1.0", "version": "0.1.0",
"sources": ["src/**"], "sources": [ "src/**" ],
"output": "build", "output": "build",
"target": "linux-x64", "target": "linux-x64",
"targets": { "targets": {

View File

@ -17,40 +17,55 @@ alias StrList = list::List{String};
alias ConfFList = list::List{ConfigFile}; alias ConfFList = list::List{ConfigFile};
fn Path? String.to_expanded_path(&str, Allocator allocator) fn Path? String.to_expanded_path(&str, Allocator allocator, String[] extra_env = {})
{ {
@pool() { @pool() {
StrList l; StrList l;
l.tinit(); l.tinit();
Path str_path = str.to_tpath()!; Path str_path = str.to_tpath()!;
l.push(str_path.basename()); l.push(str_path.basename());
Path? p = str_path.parent(); Path? p = str_path.parent();
while (true) { while (true) {
Path? x; Path? x;
if (try p) { if (try p) {
String n = p.basename(); String n = p.basename();
l.push("/");
// env variable // env variable
if (n.starts_with("$")) { if (n.starts_with("$")) {
l.push(env::tget_var(n[1..]))!; String? e = env::tget_var(n[1..]);
if (catch e) {
// var is not in regular environment, check extra_env
bool in_extra = false;
foreach_r (j: extra_env) {
if (j.starts_with(n[1..])) {
l.push(j.strip_suffix(n[1..])[1..]);
in_extra = true;
break;
}
}
if (!in_extra) {
return NOT_FOUND~;
}
} else {
l.push(e);
}
} else { } else {
l.push(n); l.push(n);
} }
x = p.parent(); x = p.parent();
} else { } else {
break; break;
} }
p = x; p = x;
} }
l.reverse();
String path;
path = string::tjoin(l.array_view(), path);
Path path = path::temp("")!; return path::new(allocator, path);
foreach_r (idx, s: l) {
path = path.tappend(s)!;
}
return path::new(allocator, path.str_view(), path.env);
}; };
} }
@ -69,7 +84,7 @@ fn StrList? get_qemu_cmdline(Allocator allocator, Object* conf)
cmd.push(conf.get_string("qemu"))!!; cmd.push(conf.get_string("qemu"))!!;
// then the drive // then the drive
cmd.push("-drive"); cmd.push("-drive");
cmd.push(string::format(allocator, "file=%s", disk_path.str_view())); cmd.push(string::format(allocator, "file=%s", (String)disk_path));
// memory // memory
cmd.push("-m"); cmd.push("-m");
cmd.push(conf.get_string("memory"))!!; cmd.push(conf.get_string("memory"))!!;
@ -78,7 +93,7 @@ fn StrList? get_qemu_cmdline(Allocator allocator, Object* conf)
cmd.push(conf.get_string("processors") ?? "1"); cmd.push(conf.get_string("processors") ?? "1");
// then all the parameters // then all the parameters
Object* parameters = conf.get("parameters")!!; Object* parameters = conf.get("parameters")!!;
for (usz i = 0; i < parameters.get_len(); i++) { for (sz i = 0; i < parameters.get_len(); i++) {
Object* p = parameters.get_at(i); Object* p = parameters.get_at(i);
if (p.is_string()) { if (p.is_string()) {
cmd.push(string::format(allocator, "-%s", p.s)); cmd.push(string::format(allocator, "-%s", p.s));
@ -100,7 +115,7 @@ fn ConfFList? get_config_list(Allocator allocator)
// find the right config directory // find the right config directory
Path conf_dir = env::get_config_dir(tmem).append(tmem, "simple-qemu-manager")!; Path conf_dir = env::get_config_dir(tmem).append(tmem, "simple-qemu-manager")!;
if (!file::exists(conf_dir.str_view()) || !file::is_dir(conf_dir.str_view())) { if (!file::exists((String)conf_dir) || !file::is_dir((String)conf_dir)) {
path::mkdir(conf_dir, recursive:true)!; path::mkdir(conf_dir, recursive:true)!;
return l; return l;
} }
@ -109,14 +124,13 @@ fn ConfFList? get_config_list(Allocator allocator)
PathList pl = path::ls(tmem, conf_dir)!; PathList pl = path::ls(tmem, conf_dir)!;
foreach (fname : pl) @pool() { foreach (fname : pl) @pool() {
if ((fname.extension() ?? "") != "json") continue; if ((fname.extension() ?? "") != "json") continue;
Path fpath = conf_dir.append(tmem, fname.str_view())!; Path fpath = conf_dir.append(tmem, (String)fname)!;
File cf = file::open_path(fpath, "r")!; char[] cf = file::load_temp(fpath)!;
defer (void)cf.close();
Object* c = json::parse(tmem, &cf)!; Object* c = json::parse(tmem, (String)cf)!;
ConfigFile e = { ConfigFile e = {
.path = path::new(allocator, fpath.str_view(), fpath.env)!, .path = path::new(allocator, (String)fpath)!,
.name = string::format(allocator, "%s", c.get_string("name"))!, .name = string::format(allocator, "%s", c.get_string("name"))!,
}; };
l.push(e); l.push(e);

View File

@ -8,7 +8,7 @@ import std::time;
import conf; import conf;
import vm; import vm;
import ugui; import ugui;
import ugui::sdl::ren; import ugui::sdl3::ren;
const char[*] VS_PATH = "resources/shaders/compiled/ugui.vert.spv"; const char[*] VS_PATH = "resources/shaders/compiled/ugui.vert.spv";
@ -36,12 +36,12 @@ fn int main(String[] args)
ren.init("Qemu Manager", 800, 600, VSYNC); ren.init("Qemu Manager", 800, 600, VSYNC);
defer ren.free(); defer ren.free();
ui.input_window_size(800, 600)!!; ui.input_window_size(800, 600)!!;
ui.load_font(&arena, "font1", "resources/hack-nerd.ttf", 16)!!; ui.load_font(&arena, "font1", "resources/hack-nerd.ttf", 16)!!;
ren.font_atlas_id = ui.get_font_id("font1"); ren.font_atlas_id = ui.get_font_id("font1");
Atlas* font_atlas = ui.get_font_atlas("font1")!!; Atlas* font_atlas = ui.get_font_atlas("font1")!!;
ren.new_texture("font1", JUST_ALPHA, font_atlas.buffer, font_atlas.width, font_atlas.height); ren.new_texture("font1", JUST_ALPHA, font_atlas.buffer, font_atlas.width, font_atlas.height);
ui.sprite_atlas_create("icons", AtlasType.ATLAS_R8G8B8A8, 512, 512)!!; ui.sprite_atlas_create("icons", AtlasType.ATLAS_R8G8B8A8, 512, 512)!!;
ui.import_sprite_file_qoi("tick", "resources/tick_sdf.qoi", SpriteType.SPRITE_MSDF)!!; ui.import_sprite_file_qoi("tick", "resources/tick_sdf.qoi", SpriteType.SPRITE_MSDF)!!;
ui.import_sprite_file_qoi("vm", "resources/vm.qoi", SpriteType.SPRITE_NORMAL)!!; ui.import_sprite_file_qoi("vm", "resources/vm.qoi", SpriteType.SPRITE_NORMAL)!!;
@ -77,7 +77,7 @@ fn int main(String[] args)
if (ui.check_key_combo(ugui::KMOD_CTRL, "q")) quit = true; if (ui.check_key_combo(ugui::KMOD_CTRL, "q")) quit = true;
static usz which_vm = 0; static sz which_vm = 0;
ui.@div(ugui::@grow(), ugui::@grow()) { ui.@div(ugui::@grow(), ugui::@grow()) {
ui.@div(ugui::@fit((short)(ui.width*0.4)), ugui::@grow(), COLUMN, scroll_x: false, scroll_y: true, resize: {.right = true}) { ui.@div(ugui::@fit((short)(ui.width*0.4)), ugui::@grow(), COLUMN, scroll_x: false, scroll_y: true, resize: {.right = true}) {
foreach (idx, &vm : vm_list) { foreach (idx, &vm : vm_list) {
@ -100,7 +100,7 @@ fn int main(String[] args)
// TODO: implement a "selectable div" to display the information of the right vm // TODO: implement a "selectable div" to display the information of the right vm
VirtualMachineDesc* vm = &vm_list[which_vm]; VirtualMachineDesc* vm = &vm_list[which_vm];
ui.text(string::tformat("Name: %s", vm.name))!!; ui.text(string::tformat("Name: %s", vm.name))!!;
ui.text(string::tformat("Disk: %s (%s)", vm.disk_path.str_view(), bytes_to_human_readable(tmem, file::get_size(vm.disk_path.str_view()))))!!; ui.text(string::tformat("Disk: %s (%s)", (String)vm.disk_path, bytes_to_human_readable(tmem, file::get_size((String)vm.disk_path))))!!;
ui.text(string::tformat("Runner: %s", vm.config.get_string("qemu")))!!; ui.text(string::tformat("Runner: %s", vm.config.get_string("qemu")))!!;
ui.text(string::tformat("Memory: %s", vm.config.get_string("memory")))!!; ui.text(string::tformat("Memory: %s", vm.config.get_string("memory")))!!;
ui.text(string::tformat("Processors: %s", vm.config.get_string("processors")))!!; ui.text(string::tformat("Processors: %s", vm.config.get_string("processors")))!!;
@ -109,7 +109,7 @@ fn int main(String[] args)
ui.frame_end()!!; ui.frame_end()!!;
/* End UI Handling */ /* End UI Handling */
/* Start UI Drawing */ /* Start UI Drawing */
ren.begin_render(true); ren.begin_render(true);
ren.render_ugui(&ui.cmd_queue); ren.render_ugui(&ui.cmd_queue);
@ -126,8 +126,8 @@ fn int main(String[] args)
} }
fn String bytes_to_human_readable(Allocator allocator, usz bytes, int dp = 1) { fn String bytes_to_human_readable(Allocator allocator, sz bytes, int dp = 1) {
static usz thresh = 1024; static sz thresh = 1024;
static String[] units = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}; static String[] units = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"};
double b = bytes; double b = bytes;
@ -138,4 +138,3 @@ fn String bytes_to_human_readable(Allocator allocator, usz bytes, int dp = 1) {
return string::format(allocator, "%.*f %s", dp, b, units[u]); return string::format(allocator, "%.*f %s", dp, b, units[u]);
} }

View File

@ -9,12 +9,13 @@ import conf;
struct VirtualMachineDesc { struct VirtualMachineDesc {
Allocator allocator;
Path config_path; Path config_path;
Object* config; Object* config;
String name; String name;
StrList cmdline; StrList cmdline;
Path disk_path; Path disk_path;
SubProcess process; Process process;
} }
@ -24,12 +25,12 @@ alias VMList = list::List{VirtualMachineDesc};
fn VirtualMachineDesc? new_from_path(Allocator allocator, Path path) fn VirtualMachineDesc? new_from_path(Allocator allocator, Path path)
{ {
VirtualMachineDesc desc; VirtualMachineDesc desc;
desc.config_path = path::new(allocator, path.str_view(), path.env)!; desc.allocator = allocator;
desc.config_path = path::new(allocator, (String)path)!;
File file = file::open_path(path, "r")!; char[] file = file::load_temp(path)!;
defer (void)file.close();
desc.config = json::parse(allocator, &file)!; desc.config = json::parse(allocator, (String)file)!;
desc.name = desc.config.get_string("name")!; desc.name = desc.config.get_string("name")!;
desc.disk_path = desc.config.get_string("disk").to_expanded_path(allocator)!; desc.disk_path = desc.config.get_string("disk").to_expanded_path(allocator)!;
@ -42,11 +43,11 @@ fn VirtualMachineDesc? new_from_path(Allocator allocator, Path path)
<* @param[&in] desc *> <* @param[&in] desc *>
fn bool VirtualMachineDesc.is_initialized(&desc) fn bool VirtualMachineDesc.is_initialized(&desc)
{ {
return desc.config_path.str_view() != "" return (String)desc.config_path != ""
&& desc.config != null && desc.config != null
&& desc.name != "" && desc.name != ""
&& desc.disk_path.str_view() != "" && (String)desc.disk_path != ""
&& desc.cmdline.len() != 0; && desc.cmdline.len() != 0;
} }
@ -55,10 +56,10 @@ fn void VirtualMachineDesc.free(&desc)
{ {
if (!desc.is_initialized()) return; if (!desc.is_initialized()) return;
(void)desc.stop(); (void)desc.stop();
desc.config_path.free(); desc.config_path.free(desc.allocator);
desc.config.free(); desc.config.free();
// desc.name.free() name is just a string view into desc.config // desc.name.free() name is just a string view into desc.config
desc.disk_path.free(); desc.disk_path.free(desc.allocator);
desc.cmdline.free(); desc.cmdline.free();
*desc = {}; *desc = {};
@ -71,7 +72,7 @@ fn void? VirtualMachineDesc.start(&desc)
if (!desc.is_initialized()) return; if (!desc.is_initialized()) return;
if ((desc.process.is_running() ?? false)) return; if ((desc.process.is_running() ?? false)) return;
desc.process = process::create(desc.cmdline.array_view(), {.inherit_stdio=true, .inherit_environment=true})!; desc.process = process::spawn(desc.cmdline.array_view(), INHERIT_STDIO|INHERIT_ENV)!;
} }