2023-02-18 04:34:40 +01:00
|
|
|
export module runtime;
|
|
|
|
|
|
|
|
import app;
|
|
|
|
|
2023-02-19 17:50:29 +01:00
|
|
|
import coral;
|
|
|
|
import coral.files;
|
|
|
|
import coral.math;
|
|
|
|
import coral.sequence;
|
2023-02-18 04:34:40 +01:00
|
|
|
|
|
|
|
import kym;
|
|
|
|
import kym.environment;
|
|
|
|
|
|
|
|
extern "C" int main(int argc, char const * const * argv) {
|
|
|
|
return app::display("Ona Runtime", [](app::system & system, app::graphics & graphics) -> int {
|
2023-02-19 17:50:29 +01:00
|
|
|
constexpr coral::path config_path{"config.kym"};
|
2023-02-19 17:45:40 +01:00
|
|
|
bool is_config_loaded{false};
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-20 02:28:58 +01:00
|
|
|
system.res_fs().read_file(config_path, [&](coral::reader & file) {
|
2023-02-19 18:43:37 +01:00
|
|
|
coral::allocator * const allocator{&system.thread_safe_allocator()};
|
|
|
|
|
|
|
|
kym::vm vm{allocator, [&system](coral::slice<char const> const & error_message) {
|
|
|
|
system.log(app::log_level::error, error_message);
|
|
|
|
}};
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-19 18:16:43 +01:00
|
|
|
if (!vm.init({.datastack_size = 64, .callstack_size = 64})) {
|
2023-02-18 04:34:40 +01:00
|
|
|
system.log(app::log_level::error, "failed to allocate memory for config vm");
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-02-19 18:43:37 +01:00
|
|
|
coral::stack<coral::u8> script_source{allocator};
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-20 02:28:58 +01:00
|
|
|
{
|
|
|
|
coral::u8 stream_buffer[1024]{0};
|
|
|
|
coral::sequence_writer script_writer{&script_source};
|
|
|
|
|
|
|
|
if (!coral::stream(script_writer, file, stream_buffer).is_ok()) return;
|
|
|
|
}
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-19 17:50:29 +01:00
|
|
|
vm.with_object(vm.compile(coral::slice{script_source.begin(), script_source.end()}.as_chars()), [&](kym::bound_object & script) {
|
2023-02-20 16:27:14 +01:00
|
|
|
vm.with_object(script.call({}), [&](kym::bound_object config) {
|
|
|
|
constexpr auto as_u16 = [](coral::i64 value) -> coral::optional<coral::i16> {
|
|
|
|
if ((value >= 0) && (value <= coral::u16_max))
|
|
|
|
return static_cast<coral::u16>(value);
|
|
|
|
|
|
|
|
return {};
|
|
|
|
};
|
|
|
|
|
|
|
|
coral::u16 const width{config.get_field("width").
|
|
|
|
as_integer().map(as_u16).value_or(0)};
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-18 14:19:01 +01:00
|
|
|
if (width == 0) return system.log(app::log_level::error,
|
|
|
|
"failed to decode `width` property of config");
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-20 16:27:14 +01:00
|
|
|
coral::u16 const height{config.get_field("height").
|
|
|
|
as_integer().map(as_u16).value_or(0)};
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-18 14:19:01 +01:00
|
|
|
if (height == 0) return system.log(app::log_level::error,
|
|
|
|
"failed to decode `height` property of config");
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-19 17:45:40 +01:00
|
|
|
if (graphics.show(width, height) != app::graphics::show_result::ok)
|
|
|
|
return system.log(app::log_level::error, "failed to initialize window");
|
2023-02-18 04:34:40 +01:00
|
|
|
|
|
|
|
vm.with_object(config.get_field("title"), [&](kym::bound_object & title) {
|
2023-02-19 17:50:29 +01:00
|
|
|
coral::stack<coral::u8, 128> title_buffer{&system.thread_safe_allocator()};
|
2023-02-20 02:28:58 +01:00
|
|
|
coral::sequence_writer title_writer{&title_buffer};
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-20 02:28:58 +01:00
|
|
|
if (!title.stringify(title_writer).is_ok()) {
|
2023-02-18 14:19:01 +01:00
|
|
|
system.log(app::log_level::error,
|
|
|
|
"failed to decode `title` property of config");
|
2023-02-18 04:34:40 +01:00
|
|
|
|
2023-02-18 14:19:01 +01:00
|
|
|
return;
|
|
|
|
}
|
2023-02-18 04:34:40 +01:00
|
|
|
|
|
|
|
is_config_loaded = true;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2023-02-19 18:16:43 +01:00
|
|
|
});
|
|
|
|
|
2023-02-19 18:43:37 +01:00
|
|
|
if (!is_config_loaded) {
|
|
|
|
coral::stack<coral::u8> error_message{&system.thread_safe_allocator()};
|
|
|
|
|
|
|
|
{
|
|
|
|
coral::sequence_writer error_writer{&error_message};
|
|
|
|
|
2023-02-20 02:28:58 +01:00
|
|
|
if (!error_writer.write(coral::slice{"failed to load "}.as_bytes()).is_ok())
|
2023-02-19 18:43:37 +01:00
|
|
|
return coral::u8_max;
|
|
|
|
|
2023-02-20 02:28:58 +01:00
|
|
|
if (!error_writer.write(config_path.as_slice().as_bytes()).is_ok())
|
2023-02-19 18:43:37 +01:00
|
|
|
return coral::u8_max;
|
|
|
|
}
|
|
|
|
|
|
|
|
return coral::u8_max;
|
|
|
|
}
|
2023-02-18 04:34:40 +01:00
|
|
|
|
|
|
|
// app::canvas canvas_2d();
|
|
|
|
|
|
|
|
while (system.poll()) {
|
|
|
|
// canvas_2d.render(graphics);
|
|
|
|
graphics.present();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
}
|