ui and stuff
This commit is contained in:
parent
4def485a6d
commit
60e77cd611
@ -15,6 +15,6 @@
|
||||
}
|
||||
},
|
||||
"safe": true,
|
||||
"opt": "O1",
|
||||
"opt": "O0",
|
||||
"debug-info": "full"
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ div {
|
||||
separator {
|
||||
bg: #fbf1c7ff;
|
||||
size: 1;
|
||||
padding: 0 5 0 5;
|
||||
}
|
||||
|
||||
button {
|
||||
|
||||
55
src/conf.c3
55
src/conf.c3
@ -5,9 +5,17 @@ import std::os::env;
|
||||
import std::core::mem::allocator;
|
||||
import std::collections::object;
|
||||
import std::collections::list;
|
||||
import std::encoding::json;
|
||||
|
||||
|
||||
struct ConfigFile {
|
||||
Path path;
|
||||
String name;
|
||||
}
|
||||
|
||||
alias StrList = list::List{String};
|
||||
alias ConfFList = list::List{ConfigFile};
|
||||
|
||||
|
||||
fn Path? String.to_expanded_path(&str, Allocator allocator)
|
||||
{
|
||||
@ -46,15 +54,15 @@ fn Path? String.to_expanded_path(&str, Allocator allocator)
|
||||
};
|
||||
}
|
||||
|
||||
fn StrList get_qemu_cmdline(Allocator allocator, Object* conf)
|
||||
fn StrList? get_qemu_cmdline(Allocator allocator, Object* conf)
|
||||
{
|
||||
StrList cmd;
|
||||
@pool() {
|
||||
// parse the disk path
|
||||
String disk = conf.get_string("disk")!!;
|
||||
Path disk_path = disk.to_expanded_path(mem)!!;
|
||||
defer disk_path.free();
|
||||
String disk = conf.get_string("disk")!;
|
||||
Path disk_path = disk.to_expanded_path(tmem)!;
|
||||
|
||||
// compose the command line for the vm
|
||||
StrList cmd;
|
||||
cmd.init(allocator);
|
||||
|
||||
// first the executable
|
||||
@ -62,7 +70,6 @@ fn StrList get_qemu_cmdline(Allocator allocator, Object* conf)
|
||||
// then the drive
|
||||
cmd.push("-drive");
|
||||
cmd.push(string::format(allocator, "file=%s", disk_path.str_view()));
|
||||
//cmd.push(string::format(allocator, "file=%s,format=%s", disk_path.str_view(), disk_path.extension()))!!;
|
||||
// memory
|
||||
cmd.push("-m");
|
||||
cmd.push(conf.get_string("memory"))!!;
|
||||
@ -80,6 +87,42 @@ fn StrList get_qemu_cmdline(Allocator allocator, Object* conf)
|
||||
cmd.push(p.get_string_at(1))!!;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
fn ConfFList? get_config_list(Allocator allocator)
|
||||
{
|
||||
ConfFList l;
|
||||
l.init(allocator);
|
||||
@pool() {
|
||||
// find the right config directory
|
||||
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())) {
|
||||
path::mkdir(conf_dir, recursive:true)!;
|
||||
return l;
|
||||
}
|
||||
|
||||
// list all json files
|
||||
PathList pl = path::ls(tmem, conf_dir)!;
|
||||
foreach (fname : pl) @pool() {
|
||||
if ((fname.extension() ?? "") != "json") continue;
|
||||
Path fpath = conf_dir.append(tmem, fname.str_view())!;
|
||||
|
||||
File cf = file::open_path(fpath, "r")!;
|
||||
defer (void)cf.close();
|
||||
|
||||
Object* c = json::parse(tmem, &cf)!;
|
||||
ConfigFile e = {
|
||||
.path = path::new(allocator, fpath.str_view(), fpath.env)!,
|
||||
.name = string::format(allocator, "%s", c.get_string("name"))!,
|
||||
};
|
||||
l.push(e);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
26
src/main.c3
26
src/main.c3
@ -28,7 +28,7 @@ fn int main(String[] args)
|
||||
Object* conf = json::parse(mem, &file)!!;
|
||||
defer conf.free();
|
||||
|
||||
// UI initialization
|
||||
// ---------------------------------------------- UI initialization ---------------------------------------------- //
|
||||
ArenaAllocator arena;
|
||||
char[] arena_mem = mem::new_array(char, 1024*1024);
|
||||
defer (void)mem::free(arena_mem);
|
||||
@ -59,9 +59,9 @@ fn int main(String[] args)
|
||||
|
||||
ui.import_style_from_file(STYLESHEET_PATH);
|
||||
ren::pre(ren.win);
|
||||
// End UI initialization
|
||||
// -------------------------------------------- End UI initialization -------------------------------------------- //
|
||||
|
||||
StrList cmd = conf::get_qemu_cmdline(mem, conf);
|
||||
StrList cmd = conf::get_qemu_cmdline(mem, conf)!!;
|
||||
defer cmd.free();
|
||||
String vm_name = conf.get_string("name")!!;
|
||||
String vm_disk = conf.get_string("disk").to_expanded_path(tmem).str_view()!!;
|
||||
@ -71,6 +71,11 @@ fn int main(String[] args)
|
||||
SubProcess vm_proc;
|
||||
defer (void)vm_proc.join();
|
||||
|
||||
ConfFList conf_list = conf::get_config_list(tmem)!!;
|
||||
foreach (cf : conf_list) {
|
||||
io::printn(cf);
|
||||
}
|
||||
|
||||
bool quit;
|
||||
Clock sleep_clock;
|
||||
while (!quit) {
|
||||
@ -84,10 +89,23 @@ fn int main(String[] args)
|
||||
if (ui.check_key_combo(ugui::KMOD_CTRL, "q")) quit = true;
|
||||
|
||||
ui.@div(ugui::@grow(), ugui::@grow(), COLUMN) {
|
||||
ui.@div(ugui::@grow(), ugui::@fit(20)) {
|
||||
ui.@div(ugui::@grow(), ugui::@fit(20), ROW, LEFT) {
|
||||
ui.text("Machine:")!!;
|
||||
ui.separator(ugui::@grow(), ugui::@grow())!!;
|
||||
ui.text(vm_name)!!;
|
||||
|
||||
static bool popup;
|
||||
static Point popup_pos;
|
||||
if (ui.button("v")!!.mouse_release) {
|
||||
popup = true;
|
||||
popup_pos = ui.input.mouse.pos;
|
||||
}
|
||||
ui.@popup(&popup, popup_pos, ugui::@fit(), ugui::@fit(), COLUMN) {
|
||||
foreach (idx, c : conf_list) {
|
||||
ui.text(c.name, idx)!!;
|
||||
}
|
||||
}!!;
|
||||
|
||||
}!!;
|
||||
ui.hor_line()!!;
|
||||
ui.@div(ugui::@grow(), ugui::@grow(), COLUMN, scroll_y: true) {
|
||||
|
||||
90
src/vm.c3
Normal file
90
src/vm.c3
Normal file
@ -0,0 +1,90 @@
|
||||
import std::io;
|
||||
import std::io::path;
|
||||
import std::io::file;
|
||||
import std::os::process;
|
||||
import std::collections::object;
|
||||
import std::encoding::json;
|
||||
import conf;
|
||||
|
||||
|
||||
struct VirtualMachineDesc {
|
||||
Path config_path;
|
||||
Object* config;
|
||||
String name;
|
||||
StrList cmdline;
|
||||
Path disk_path;
|
||||
SubProcess process;
|
||||
}
|
||||
|
||||
|
||||
fn VirtualMachineDesc? new_from_path(Allocator allocator, Path path)
|
||||
{
|
||||
VirtualMachineDesc desc;
|
||||
desc.config_path = path::new(allocator, path.str_view(), path.env)!;
|
||||
|
||||
File file = file::open_path(path, "r")!;
|
||||
defer (void)file.close();
|
||||
|
||||
desc.config = json::parse(allocator, &file)!;
|
||||
desc.name = desc.config.get_string("name")!;
|
||||
desc.disk_path = desc.config.get_string("disk").to_expanded_path(allocator)!;
|
||||
|
||||
desc.cmdline = conf::get_qemu_cmdline(allocator, desc.config)!;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
||||
<* @param[&in] desc *>
|
||||
fn bool VirtualMachineDesc.is_initialized(&desc)
|
||||
{
|
||||
return desc.config_path.str_view() != ""
|
||||
&& desc.config != null
|
||||
&& desc.name != ""
|
||||
&& desc.disk_path.str_view() != ""
|
||||
&& desc.cmdline.len() != 0;
|
||||
}
|
||||
|
||||
|
||||
<* @param[&inout] desc *>
|
||||
fn void VirtualMachineDesc.free(&desc)
|
||||
{
|
||||
if (!desc.is_initialized()) return;
|
||||
(void)desc.stop();
|
||||
desc.config_path.free();
|
||||
desc.config.free();
|
||||
// desc.name.free() name is just a string view into desc.config
|
||||
desc.disk_path.free();
|
||||
desc.cmdline.free();
|
||||
|
||||
*desc = {};
|
||||
}
|
||||
|
||||
|
||||
<* @param[&inout] desc *>
|
||||
fn void? VirtualMachineDesc.start(&desc)
|
||||
{
|
||||
if (!desc.is_initialized()) return;
|
||||
if ((desc.process.is_running() ?? false)) return;
|
||||
|
||||
desc.process = process::create(desc.cmdline.array_view(), {.inherit_stdio=true, .inherit_environment=true})!;
|
||||
}
|
||||
|
||||
|
||||
<* @param[&inout] desc *>
|
||||
fn void? VirtualMachineDesc.stop(&desc)
|
||||
{
|
||||
if (!desc.is_initialized()) return;
|
||||
if (!(desc.process.is_running() ?? false)) return;
|
||||
|
||||
desc.process.terminate()!;
|
||||
desc.process.join()!;
|
||||
}
|
||||
|
||||
|
||||
<* @param[&in] desc *>
|
||||
fn bool VirtualMachineDesc.is_running(&desc)
|
||||
{
|
||||
if (!desc.is_initialized()) return false;
|
||||
return desc.process.is_running() ?? false;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user