C++20 Port #5
301
source/app.cpp
301
source/app.cpp
|
@ -1,61 +1,103 @@
|
||||||
|
module;
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
export module app;
|
export module app;
|
||||||
|
|
||||||
import core;
|
import core;
|
||||||
|
import core.files;
|
||||||
import core.image;
|
import core.image;
|
||||||
import core.lalgebra;
|
import core.lalgebra;
|
||||||
|
|
||||||
|
import oar;
|
||||||
|
|
||||||
export namespace app {
|
export namespace app {
|
||||||
struct path {
|
struct directory : public core::fs {
|
||||||
static constexpr core::usize max = 0xff;
|
using core::fs::access_result;
|
||||||
|
|
||||||
static constexpr char seperator = '/';
|
struct rules {
|
||||||
|
bool can_read;
|
||||||
|
|
||||||
core::u8 buffer[max + 1];
|
bool can_write;
|
||||||
|
|
||||||
static constexpr path empty() {
|
|
||||||
path empty_path = {0};
|
|
||||||
|
|
||||||
empty_path.buffer[max] = max;
|
|
||||||
|
|
||||||
return empty_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
core::slice<char const> as_slice() const {
|
|
||||||
return {reinterpret_cast<char const *>(this->buffer), this->size()};
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr core::usize size() const {
|
|
||||||
return max - this->buffer[max];
|
|
||||||
}
|
|
||||||
|
|
||||||
core::i16 compare(path const & that) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equals(path const & that) const {
|
|
||||||
return core::equals(this->as_slice().as_bytes(), that.as_slice().as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr path joined(core::slice<char const> const & text) const {
|
|
||||||
if (text.length > this->buffer[max]) return empty();
|
|
||||||
|
|
||||||
path joined_path = *this;
|
|
||||||
|
|
||||||
for (char const c : text) {
|
|
||||||
joined_path.buffer[joined_path.size()] = c;
|
|
||||||
joined_path.buffer[max] -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return joined_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
core::u64 hash() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct file_store {
|
directory() : path_buffer{0} {}
|
||||||
virtual void read_file(app::path const & file_path, core::callable<void(core::readable const &)> const & then) = 0;
|
|
||||||
|
access_result read_file(core::path const & file_path,
|
||||||
|
core::callable<void(core::readable const &)> const & then) {
|
||||||
|
|
||||||
|
if (this->prefix_length == 0) return access_result::not_found;
|
||||||
|
|
||||||
|
if (!this->access_rules.can_read) return access_result::access_denied;
|
||||||
|
|
||||||
|
::SDL_RWops * rw_ops = this->open_rw(file_path, {.can_read = true});
|
||||||
|
|
||||||
|
if (rw_ops == nullptr) return access_result::not_found;
|
||||||
|
|
||||||
|
then([rw_ops](core::slice<uint8_t> const & buffer) -> size_t {
|
||||||
|
return ::SDL_RWread(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
::SDL_RWclose(rw_ops);
|
||||||
|
|
||||||
|
return access_result::ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void target(core::slice<char const> const & directory_path, rules const & access_rules) {
|
||||||
|
this->access_rules = access_rules;
|
||||||
|
this->prefix_length = core::min(directory_path.length, path_max - 1);
|
||||||
|
|
||||||
|
{
|
||||||
|
core::slice const path_buffer_slice{this->path_buffer};
|
||||||
|
|
||||||
|
core::copy(path_buffer_slice.sliced(0, this->prefix_length),
|
||||||
|
directory_path.sliced(0, this->prefix_length).as_bytes());
|
||||||
|
|
||||||
|
core::zero(path_buffer_slice.sliced(this->prefix_length, path_max - this->prefix_length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
access_result write_file(core::path const & file_path,
|
||||||
|
core::callable<void(core::writable const &)> const & then) {
|
||||||
|
|
||||||
|
if (this->prefix_length == 0) return access_result::not_found;
|
||||||
|
|
||||||
|
if (!this->access_rules.can_write) return access_result::access_denied;
|
||||||
|
|
||||||
|
::SDL_RWops * rw_ops = this->open_rw(file_path, {.can_write = true});
|
||||||
|
|
||||||
|
if (rw_ops == nullptr) return access_result::not_found;
|
||||||
|
|
||||||
|
then([rw_ops](core::slice<uint8_t const> const & buffer) -> size_t {
|
||||||
|
return ::SDL_RWwrite(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
::SDL_RWclose(rw_ops);
|
||||||
|
|
||||||
|
return access_result::ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr core::usize path_max = 4096;
|
||||||
|
|
||||||
|
rules access_rules;
|
||||||
|
|
||||||
|
core::usize prefix_length;
|
||||||
|
|
||||||
|
core::u8 path_buffer[path_max];
|
||||||
|
|
||||||
|
::SDL_RWops * open_rw(core::path const & file_path, rules const & file_rules) {
|
||||||
|
core::u8 * const path_begin = this->path_buffer + this->prefix_length;
|
||||||
|
|
||||||
|
core::slice const path_remaining =
|
||||||
|
{path_begin, path_begin + (path_max - this->prefix_length) - 1};
|
||||||
|
|
||||||
|
if (path_remaining.length < file_path.byte_size()) return nullptr;
|
||||||
|
|
||||||
|
core::copy(path_remaining, core::slice{file_path.begin(), file_path.end()}.as_bytes());
|
||||||
|
|
||||||
|
return ::SDL_RWFromFile(reinterpret_cast<char const *>(this->path_buffer), "r");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class log_level {
|
enum class log_level {
|
||||||
|
@ -65,18 +107,103 @@ export namespace app {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct system {
|
struct system {
|
||||||
virtual bool poll() = 0;
|
system(core::path const & title) : res_archive{} {
|
||||||
|
constexpr directory::rules read_only_rules = {.can_read = true};
|
||||||
|
|
||||||
virtual file_store & bundle() = 0;
|
{
|
||||||
|
char * const path = ::SDL_GetBasePath();
|
||||||
|
|
||||||
virtual void log(log_level level, core::slice<char const> const & message) = 0;
|
if (path == nullptr) {
|
||||||
|
this->cwd_directory.target("./", read_only_rules);
|
||||||
|
} else {
|
||||||
|
core::usize path_length = 0;
|
||||||
|
|
||||||
virtual core::allocator & thread_safe_allocator() = 0;
|
while (path[path_length] != 0) path_length += 1;
|
||||||
|
|
||||||
|
if (path_length == 0) {
|
||||||
|
this->cwd_directory.target("./", read_only_rules);
|
||||||
|
} else {
|
||||||
|
this->cwd_directory.target({path, path_length}, read_only_rules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::SDL_free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char * const path = ::SDL_GetPrefPath("ona", title.begin());
|
||||||
|
|
||||||
|
if (path != nullptr) {
|
||||||
|
core::usize path_length = 0;
|
||||||
|
|
||||||
|
while (path[path_length] != 0) path_length += 1;
|
||||||
|
|
||||||
|
if (path_length != 0) this->cwd_directory.target({path, path_length}, {
|
||||||
|
.can_read = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
::SDL_free(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core::fs & cwd_fs() {
|
||||||
|
return this->cwd_directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool poll() {
|
||||||
|
while (::SDL_PollEvent(&this->sdl_event) != 0) {
|
||||||
|
switch (this->sdl_event.type) {
|
||||||
|
case SDL_QUIT: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
core::fs & res_fs() {
|
||||||
|
return this->res_archive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log(app::log_level level, core::slice<char const> const & message) {
|
||||||
|
core::i32 const length = static_cast<core::i32>(
|
||||||
|
core::min(message.length, static_cast<size_t>(core::i32_max)));
|
||||||
|
|
||||||
|
::SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
SDL_LOG_PRIORITY_INFO, "%.*s", length, message.pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
core::allocator & thread_safe_allocator() {
|
||||||
|
return this->allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
core::fs & user_fs() {
|
||||||
|
return this->user_directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
::SDL_Event sdl_event;
|
||||||
|
|
||||||
|
struct : public core::allocator {
|
||||||
|
core::u8 * reallocate(core::u8 * maybe_allocation, core::usize requested_size) override {
|
||||||
|
return reinterpret_cast<core::u8 *>(::SDL_malloc(requested_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(void * allocation) override {
|
||||||
|
::SDL_free(allocation);
|
||||||
|
}
|
||||||
|
} allocator;
|
||||||
|
|
||||||
|
oar::archive res_archive;
|
||||||
|
|
||||||
|
directory cwd_directory;
|
||||||
|
|
||||||
|
directory user_directory;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct graphics {
|
struct graphics {
|
||||||
enum class show_error {
|
enum class [[nodiscard]] show_result {
|
||||||
none,
|
ok,
|
||||||
out_of_memory,
|
out_of_memory,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,12 +211,72 @@ export namespace app {
|
||||||
core::color background_color;
|
core::color background_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void render(canvas & source_canvas) = 0;
|
graphics(core::path const & title) {
|
||||||
|
this->retitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void present() = 0;
|
void render(canvas & source_canvas) {
|
||||||
|
if (this->sdl_renderer != nullptr) {
|
||||||
|
SDL_SetRenderDrawColor(this->sdl_renderer, source_canvas.background_color.to_r8(),
|
||||||
|
source_canvas.background_color.to_g8(), source_canvas.background_color.to_b8(),
|
||||||
|
source_canvas.background_color.to_a8());
|
||||||
|
|
||||||
virtual show_error show(core::u16 physical_width, core::u16 physical_height) = 0;
|
SDL_RenderClear(this->sdl_renderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void retitle(core::slice<const char> const & updated_title) = 0;
|
void retitle(core::path const & title) {
|
||||||
|
this->title = title;
|
||||||
|
|
||||||
|
if (this->sdl_window != nullptr)
|
||||||
|
::SDL_SetWindowTitle(this->sdl_window, this->title.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
show_result show(core::u16 physical_width, core::u16 physical_height) {
|
||||||
|
if (this->sdl_window == nullptr) {
|
||||||
|
constexpr int sdl_windowpos = SDL_WINDOWPOS_UNDEFINED;
|
||||||
|
constexpr core::u32 sdl_windowflags = 0;
|
||||||
|
|
||||||
|
this->sdl_window = ::SDL_CreateWindow(this->title.begin(), sdl_windowpos,
|
||||||
|
sdl_windowpos, static_cast<int>(physical_width), static_cast<int>(physical_height),
|
||||||
|
sdl_windowflags);
|
||||||
|
|
||||||
|
if (this->sdl_window == nullptr) return show_result::out_of_memory;
|
||||||
|
} else {
|
||||||
|
::SDL_ShowWindow(this->sdl_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->sdl_renderer == nullptr) {
|
||||||
|
constexpr core::u32 sdl_rendererflags = 0;
|
||||||
|
|
||||||
|
this->sdl_renderer = ::SDL_CreateRenderer(this->sdl_window, -1, sdl_rendererflags);
|
||||||
|
|
||||||
|
if (this->sdl_renderer == nullptr) return show_result::out_of_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
return show_result::ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void present() {
|
||||||
|
if (this->sdl_renderer != nullptr) {
|
||||||
|
::SDL_RenderPresent(this->sdl_renderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
core::path title;
|
||||||
|
|
||||||
|
::SDL_Window * sdl_window = nullptr;
|
||||||
|
|
||||||
|
::SDL_Renderer * sdl_renderer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using graphical_runnable = core::callable<int(system &, graphics &)>;
|
||||||
|
|
||||||
|
int display(core::path const & title, graphical_runnable const & run) {
|
||||||
|
system app_system{title};
|
||||||
|
graphics app_graphics{title};
|
||||||
|
|
||||||
|
return run(app_system, app_graphics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
module;
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
export module app.sdl;
|
|
||||||
|
|
||||||
import app;
|
|
||||||
|
|
||||||
import core;
|
|
||||||
import core.image;
|
|
||||||
import core.sequence;
|
|
||||||
import core.lalgebra;
|
|
||||||
|
|
||||||
struct bundled_file_store : public app::file_store {
|
|
||||||
void read_file(app::path const & file_path, core::callable<void(core::readable const &)> const & then) override {
|
|
||||||
constexpr core::slice<char const> path_prefix = "./";
|
|
||||||
constexpr core::usize path_max = 512;
|
|
||||||
|
|
||||||
if ((file_path.size() + path_prefix.length) > path_max) core::unreachable();
|
|
||||||
|
|
||||||
core::stack<char, path_max> path_buffer{&core::null_allocator()};
|
|
||||||
|
|
||||||
if (path_buffer.append("./") != core::append_result::ok) core::unreachable();
|
|
||||||
|
|
||||||
// File path is guaranteed to be null-terminated.
|
|
||||||
if (path_buffer.append(file_path.as_slice()) != core::append_result::ok)
|
|
||||||
core::unreachable();
|
|
||||||
|
|
||||||
SDL_RWops * rw_ops = ::SDL_RWFromFile(path_buffer.begin(), "r");
|
|
||||||
|
|
||||||
if (rw_ops == nullptr) return;
|
|
||||||
|
|
||||||
then([rw_ops](core::slice<uint8_t> const & buffer) -> size_t {
|
|
||||||
return ::SDL_RWread(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
::SDL_RWclose(rw_ops);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sdl_allocator : public core::allocator {
|
|
||||||
core::u8 * reallocate(core::u8 * maybe_allocation, core::usize requested_size) override {
|
|
||||||
return reinterpret_cast<core::u8 *>(::SDL_malloc(requested_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate(void * allocation) override {
|
|
||||||
::SDL_free(allocation);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sdl_system : public app::system {
|
|
||||||
private:
|
|
||||||
::SDL_Event sdl_event;
|
|
||||||
|
|
||||||
sdl_allocator allocator;
|
|
||||||
|
|
||||||
bundled_file_store bundled_store;
|
|
||||||
|
|
||||||
public:
|
|
||||||
sdl_system() :
|
|
||||||
sdl_event{0},
|
|
||||||
allocator{} {}
|
|
||||||
|
|
||||||
bool poll() override {
|
|
||||||
while (::SDL_PollEvent(&this->sdl_event) != 0) {
|
|
||||||
switch (this->sdl_event.type) {
|
|
||||||
case SDL_QUIT: return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
app::file_store & bundle() override {
|
|
||||||
return this->bundled_store;
|
|
||||||
}
|
|
||||||
|
|
||||||
void log(app::log_level level, core::slice<char const> const & message) override {
|
|
||||||
core::i32 const length = static_cast<core::i32>(
|
|
||||||
core::min(message.length, static_cast<size_t>(core::i32_max)));
|
|
||||||
|
|
||||||
::SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
SDL_LOG_PRIORITY_INFO, "%.*s", length, message.pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
core::allocator & thread_safe_allocator() override {
|
|
||||||
return this->allocator;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sdl_graphics : public app::graphics {
|
|
||||||
static constexpr core::usize title_maximum = 128;
|
|
||||||
|
|
||||||
core::u32 title_length;
|
|
||||||
|
|
||||||
char title_buffer[title_maximum];
|
|
||||||
|
|
||||||
::SDL_Window * sdl_window = nullptr;
|
|
||||||
|
|
||||||
::SDL_Renderer * sdl_renderer = nullptr;
|
|
||||||
|
|
||||||
sdl_graphics(core::slice<char const> const & title) {
|
|
||||||
this->retitle(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
void render(canvas & source_canvas) override {
|
|
||||||
if (this->sdl_renderer != nullptr) {
|
|
||||||
SDL_SetRenderDrawColor(this->sdl_renderer, source_canvas.background_color.to_r8(),
|
|
||||||
source_canvas.background_color.to_g8(), source_canvas.background_color.to_b8(),
|
|
||||||
source_canvas.background_color.to_a8());
|
|
||||||
|
|
||||||
SDL_RenderClear(this->sdl_renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void retitle(core::slice<char const> const & title) override {
|
|
||||||
this->title_length = core::min(title.length, title_maximum - 1);
|
|
||||||
|
|
||||||
for (core::usize i = 0; i < this->title_length; i += 1) title_buffer[i] = title[i];
|
|
||||||
|
|
||||||
for (core::usize i = this->title_length; i < title_maximum; i += 1) title_buffer[i] = 0;
|
|
||||||
|
|
||||||
if (this->sdl_window != nullptr) ::SDL_SetWindowTitle(this->sdl_window, title_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
app::graphics::show_error show(core::u16 physical_width, core::u16 physical_height) override {
|
|
||||||
if (this->sdl_window == nullptr) {
|
|
||||||
constexpr int sdl_windowpos = SDL_WINDOWPOS_UNDEFINED;
|
|
||||||
constexpr core::u32 sdl_windowflags = 0;
|
|
||||||
|
|
||||||
this->sdl_window = ::SDL_CreateWindow(title_buffer, sdl_windowpos, sdl_windowpos,
|
|
||||||
static_cast<int>(physical_width), static_cast<int>(physical_height),
|
|
||||||
sdl_windowflags);
|
|
||||||
|
|
||||||
if (this->sdl_window == nullptr) return show_error::out_of_memory;
|
|
||||||
} else {
|
|
||||||
::SDL_ShowWindow(this->sdl_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->sdl_renderer == nullptr) {
|
|
||||||
constexpr core::u32 sdl_rendererflags = 0;
|
|
||||||
|
|
||||||
this->sdl_renderer = ::SDL_CreateRenderer(this->sdl_window, -1, sdl_rendererflags);
|
|
||||||
|
|
||||||
if (this->sdl_renderer == nullptr) return show_error::out_of_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
return show_error::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
void present() override {
|
|
||||||
if (this->sdl_renderer != nullptr) {
|
|
||||||
::SDL_RenderPresent(this->sdl_renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export namespace app {
|
|
||||||
int display(core::slice<char const> const & title,
|
|
||||||
core::callable<int(app::system &, app::graphics &)> const & run) {
|
|
||||||
|
|
||||||
sdl_system system;
|
|
||||||
sdl_graphics graphics(title);
|
|
||||||
|
|
||||||
return run(system, graphics);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
export module runtime;
|
export module runtime;
|
||||||
|
|
||||||
import app;
|
import app;
|
||||||
import app.sdl;
|
|
||||||
|
|
||||||
import core;
|
import core;
|
||||||
|
import core.files;
|
||||||
import core.lalgebra;
|
import core.lalgebra;
|
||||||
import core.sequence;
|
import core.sequence;
|
||||||
|
|
||||||
|
@ -12,11 +12,12 @@ import kym.environment;
|
||||||
|
|
||||||
extern "C" int main(int argc, char const * const * argv) {
|
extern "C" int main(int argc, char const * const * argv) {
|
||||||
return app::display("Ona Runtime", [](app::system & system, app::graphics & graphics) -> int {
|
return app::display("Ona Runtime", [](app::system & system, app::graphics & graphics) -> int {
|
||||||
constexpr app::path config_path = app::path::empty().joined("config.kym");
|
constexpr core::path config_path{"config.kym"};
|
||||||
bool is_config_loaded = false;
|
bool is_config_loaded{false};
|
||||||
|
|
||||||
system.bundle().read_file(config_path, [&](core::readable const & file) {
|
if ((system.res_fs().read_file(config_path, [&](core::readable const & file) {
|
||||||
kym::vm vm{&system.thread_safe_allocator(), [&system](core::slice<char const> const & error_message) {
|
kym::vm vm{&system.thread_safe_allocator(),
|
||||||
|
[&system](core::slice<char const> const & error_message) {
|
||||||
system.log(app::log_level::error, error_message);
|
system.log(app::log_level::error, error_message);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -30,24 +31,25 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
core::stack<core::u8> script_source{&system.thread_safe_allocator()};
|
core::stack<core::u8> script_source{&system.thread_safe_allocator()};
|
||||||
core::u8 stream_buffer[1024] = {};
|
core::u8 stream_buffer[1024]{0};
|
||||||
|
|
||||||
if (!core::stream(core::sequence_writer{&script_source}, file, stream_buffer).is_ok())
|
if (!core::stream(core::sequence_writer{&script_source}, file, stream_buffer).is_ok())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vm.with_object(vm.compile(core::slice{script_source.begin(), script_source.end()}.as_chars()), [&](kym::bound_object & script) {
|
vm.with_object(vm.compile(core::slice{script_source.begin(), script_source.end()}.as_chars()), [&](kym::bound_object & script) {
|
||||||
vm.with_object(script.call({}), [&](kym::bound_object & config) {
|
vm.with_object(script.call({}), [&](kym::bound_object & config) {
|
||||||
core::u16 const width = config.get_field("width").as_u16().value_or(0);
|
core::u16 const width{config.get_field("width").as_u16().value_or(0)};
|
||||||
|
|
||||||
if (width == 0) return system.log(app::log_level::error,
|
if (width == 0) return system.log(app::log_level::error,
|
||||||
"failed to decode `width` property of config");
|
"failed to decode `width` property of config");
|
||||||
|
|
||||||
core::u16 const height = config.get_field("height").as_u16().value_or(0);
|
core::u16 const height{config.get_field("height").as_u16().value_or(0)};
|
||||||
|
|
||||||
if (height == 0) return system.log(app::log_level::error,
|
if (height == 0) return system.log(app::log_level::error,
|
||||||
"failed to decode `height` property of config");
|
"failed to decode `height` property of config");
|
||||||
|
|
||||||
graphics.show(width, height);
|
if (graphics.show(width, height) != app::graphics::show_result::ok)
|
||||||
|
return system.log(app::log_level::error, "failed to initialize window");
|
||||||
|
|
||||||
vm.with_object(config.get_field("title"), [&](kym::bound_object & title) {
|
vm.with_object(config.get_field("title"), [&](kym::bound_object & title) {
|
||||||
core::stack<core::u8, 128> title_buffer{&system.thread_safe_allocator()};
|
core::stack<core::u8, 128> title_buffer{&system.thread_safe_allocator()};
|
||||||
|
@ -63,13 +65,7 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}) != core::fs::access_result::ok) || (!is_config_loaded)) return core::u8_max;
|
||||||
|
|
||||||
if (!is_config_loaded) {
|
|
||||||
system.log(app::log_level::error, "failed to load config");
|
|
||||||
|
|
||||||
return core::u8_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// app::canvas canvas_2d();
|
// app::canvas canvas_2d();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue