ui and stuff
This commit is contained in:
parent
4def485a6d
commit
60e77cd611
@ -15,6 +15,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"safe": true,
|
"safe": true,
|
||||||
"opt": "O1",
|
"opt": "O0",
|
||||||
"debug-info": "full"
|
"debug-info": "full"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ div {
|
|||||||
separator {
|
separator {
|
||||||
bg: #fbf1c7ff;
|
bg: #fbf1c7ff;
|
||||||
size: 1;
|
size: 1;
|
||||||
padding: 0 5 0 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|||||||
55
src/conf.c3
55
src/conf.c3
@ -5,9 +5,17 @@ import std::os::env;
|
|||||||
import std::core::mem::allocator;
|
import std::core::mem::allocator;
|
||||||
import std::collections::object;
|
import std::collections::object;
|
||||||
import std::collections::list;
|
import std::collections::list;
|
||||||
|
import std::encoding::json;
|
||||||
|
|
||||||
|
|
||||||
|
struct ConfigFile {
|
||||||
|
Path path;
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
|
||||||
alias StrList = list::List{String};
|
alias StrList = list::List{String};
|
||||||
|
alias ConfFList = list::List{ConfigFile};
|
||||||
|
|
||||||
|
|
||||||
fn Path? String.to_expanded_path(&str, Allocator allocator)
|
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
|
// parse the disk path
|
||||||
String disk = conf.get_string("disk")!!;
|
String disk = conf.get_string("disk")!;
|
||||||
Path disk_path = disk.to_expanded_path(mem)!!;
|
Path disk_path = disk.to_expanded_path(tmem)!;
|
||||||
defer disk_path.free();
|
|
||||||
|
|
||||||
// compose the command line for the vm
|
// compose the command line for the vm
|
||||||
StrList cmd;
|
|
||||||
cmd.init(allocator);
|
cmd.init(allocator);
|
||||||
|
|
||||||
// first the executable
|
// first the executable
|
||||||
@ -62,7 +70,6 @@ fn StrList get_qemu_cmdline(Allocator allocator, Object* conf)
|
|||||||
// 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", disk_path.str_view()));
|
||||||
//cmd.push(string::format(allocator, "file=%s,format=%s", disk_path.str_view(), disk_path.extension()))!!;
|
|
||||||
// memory
|
// memory
|
||||||
cmd.push("-m");
|
cmd.push("-m");
|
||||||
cmd.push(conf.get_string("memory"))!!;
|
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))!!;
|
cmd.push(p.get_string_at(1))!!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return cmd;
|
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)!!;
|
Object* conf = json::parse(mem, &file)!!;
|
||||||
defer conf.free();
|
defer conf.free();
|
||||||
|
|
||||||
// UI initialization
|
// ---------------------------------------------- UI initialization ---------------------------------------------- //
|
||||||
ArenaAllocator arena;
|
ArenaAllocator arena;
|
||||||
char[] arena_mem = mem::new_array(char, 1024*1024);
|
char[] arena_mem = mem::new_array(char, 1024*1024);
|
||||||
defer (void)mem::free(arena_mem);
|
defer (void)mem::free(arena_mem);
|
||||||
@ -59,9 +59,9 @@ fn int main(String[] args)
|
|||||||
|
|
||||||
ui.import_style_from_file(STYLESHEET_PATH);
|
ui.import_style_from_file(STYLESHEET_PATH);
|
||||||
ren::pre(ren.win);
|
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();
|
defer cmd.free();
|
||||||
String vm_name = conf.get_string("name")!!;
|
String vm_name = conf.get_string("name")!!;
|
||||||
String vm_disk = conf.get_string("disk").to_expanded_path(tmem).str_view()!!;
|
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;
|
SubProcess vm_proc;
|
||||||
defer (void)vm_proc.join();
|
defer (void)vm_proc.join();
|
||||||
|
|
||||||
|
ConfFList conf_list = conf::get_config_list(tmem)!!;
|
||||||
|
foreach (cf : conf_list) {
|
||||||
|
io::printn(cf);
|
||||||
|
}
|
||||||
|
|
||||||
bool quit;
|
bool quit;
|
||||||
Clock sleep_clock;
|
Clock sleep_clock;
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
@ -84,10 +89,23 @@ 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;
|
||||||
|
|
||||||
ui.@div(ugui::@grow(), ugui::@grow(), COLUMN) {
|
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.text("Machine:")!!;
|
||||||
ui.separator(ugui::@grow(), ugui::@grow())!!;
|
ui.separator(ugui::@grow(), ugui::@grow())!!;
|
||||||
ui.text(vm_name)!!;
|
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.hor_line()!!;
|
||||||
ui.@div(ugui::@grow(), ugui::@grow(), COLUMN, scroll_y: true) {
|
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