C++20 Port #5
2
build.py
2
build.py
|
@ -28,7 +28,7 @@ def compile_package(root_module_name: str) -> None:
|
||||||
for file_name in os.listdir(root_module_source_path):
|
for file_name in os.listdir(root_module_source_path):
|
||||||
compile_module(os.path.join(root_module_source_path, file_name), f"{root_module_name}.{os.path.splitext(file_name)[0]}")
|
compile_module(os.path.join(root_module_source_path, file_name), f"{root_module_name}.{os.path.splitext(file_name)[0]}")
|
||||||
|
|
||||||
compile_package("core")
|
compile_package("coral")
|
||||||
compile_package("oar")
|
compile_package("oar")
|
||||||
compile_package("app")
|
compile_package("app")
|
||||||
compile_package("kym")
|
compile_package("kym")
|
||||||
|
|
|
@ -4,16 +4,16 @@ module;
|
||||||
|
|
||||||
export module app;
|
export module app;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
import core.files;
|
import coral.files;
|
||||||
import core.image;
|
import coral.image;
|
||||||
import core.math;
|
import coral.math;
|
||||||
|
|
||||||
import oar;
|
import oar;
|
||||||
|
|
||||||
export namespace app {
|
export namespace app {
|
||||||
struct directory : public core::fs {
|
struct directory : public coral::fs {
|
||||||
using core::fs::access_result;
|
using coral::fs::access_result;
|
||||||
|
|
||||||
struct rules {
|
struct rules {
|
||||||
bool can_read;
|
bool can_read;
|
||||||
|
@ -23,8 +23,8 @@ export namespace app {
|
||||||
|
|
||||||
directory() : path_buffer{0} {}
|
directory() : path_buffer{0} {}
|
||||||
|
|
||||||
access_result read_file(core::path const & file_path,
|
access_result read_file(coral::path const & file_path,
|
||||||
core::callable<void(core::readable const &)> const & then) {
|
coral::callable<void(coral::readable const &)> const & then) {
|
||||||
|
|
||||||
if (this->prefix_length == 0) return access_result::not_found;
|
if (this->prefix_length == 0) return access_result::not_found;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export namespace app {
|
||||||
|
|
||||||
if (rw_ops == nullptr) return access_result::not_found;
|
if (rw_ops == nullptr) return access_result::not_found;
|
||||||
|
|
||||||
then([rw_ops](core::slice<uint8_t> const & buffer) -> size_t {
|
then([rw_ops](coral::slice<uint8_t> const & buffer) -> size_t {
|
||||||
return ::SDL_RWread(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
return ::SDL_RWread(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -43,22 +43,22 @@ export namespace app {
|
||||||
return access_result::ok;
|
return access_result::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void target(core::slice<char const> const & directory_path, rules const & access_rules) {
|
void target(coral::slice<char const> const & directory_path, rules const & access_rules) {
|
||||||
this->access_rules = access_rules;
|
this->access_rules = access_rules;
|
||||||
this->prefix_length = core::min(directory_path.length, path_max - 1);
|
this->prefix_length = coral::min(directory_path.length, path_max - 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
core::slice const path_buffer_slice{this->path_buffer};
|
coral::slice const path_buffer_slice{this->path_buffer};
|
||||||
|
|
||||||
core::copy(path_buffer_slice.sliced(0, this->prefix_length),
|
coral::copy(path_buffer_slice.sliced(0, this->prefix_length),
|
||||||
directory_path.sliced(0, this->prefix_length).as_bytes());
|
directory_path.sliced(0, this->prefix_length).as_bytes());
|
||||||
|
|
||||||
core::zero(path_buffer_slice.sliced(this->prefix_length, path_max - this->prefix_length));
|
coral::zero(path_buffer_slice.sliced(this->prefix_length, path_max - this->prefix_length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
access_result write_file(core::path const & file_path,
|
access_result write_file(coral::path const & file_path,
|
||||||
core::callable<void(core::writable const &)> const & then) {
|
coral::callable<void(coral::writable const &)> const & then) {
|
||||||
|
|
||||||
if (this->prefix_length == 0) return access_result::not_found;
|
if (this->prefix_length == 0) return access_result::not_found;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ export namespace app {
|
||||||
|
|
||||||
if (rw_ops == nullptr) return access_result::not_found;
|
if (rw_ops == nullptr) return access_result::not_found;
|
||||||
|
|
||||||
then([rw_ops](core::slice<uint8_t const> const & buffer) -> size_t {
|
then([rw_ops](coral::slice<uint8_t const> const & buffer) -> size_t {
|
||||||
return ::SDL_RWwrite(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
return ::SDL_RWwrite(rw_ops, buffer.pointer, sizeof(uint8_t), buffer.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -78,23 +78,23 @@ export namespace app {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr core::usize path_max = 4096;
|
static constexpr coral::usize path_max = 4096;
|
||||||
|
|
||||||
rules access_rules;
|
rules access_rules;
|
||||||
|
|
||||||
core::usize prefix_length;
|
coral::usize prefix_length;
|
||||||
|
|
||||||
core::u8 path_buffer[path_max];
|
coral::u8 path_buffer[path_max];
|
||||||
|
|
||||||
::SDL_RWops * open_rw(core::path const & file_path, rules const & file_rules) {
|
::SDL_RWops * open_rw(coral::path const & file_path, rules const & file_rules) {
|
||||||
core::u8 * const path_begin = this->path_buffer + this->prefix_length;
|
coral::u8 * const path_begin = this->path_buffer + this->prefix_length;
|
||||||
|
|
||||||
core::slice const path_remaining =
|
coral::slice const path_remaining =
|
||||||
{path_begin, path_begin + (path_max - this->prefix_length) - 1};
|
{path_begin, path_begin + (path_max - this->prefix_length) - 1};
|
||||||
|
|
||||||
if (path_remaining.length < file_path.byte_size()) return nullptr;
|
if (path_remaining.length < file_path.byte_size()) return nullptr;
|
||||||
|
|
||||||
core::copy(path_remaining, core::slice{file_path.begin(), file_path.end()}.as_bytes());
|
coral::copy(path_remaining, coral::slice{file_path.begin(), file_path.end()}.as_bytes());
|
||||||
|
|
||||||
return ::SDL_RWFromFile(reinterpret_cast<char const *>(this->path_buffer), "r");
|
return ::SDL_RWFromFile(reinterpret_cast<char const *>(this->path_buffer), "r");
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ export namespace app {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct system {
|
struct system {
|
||||||
system(core::path const & title) : res_archive{} {
|
system(coral::path const & title) : res_archive{} {
|
||||||
constexpr directory::rules read_only_rules = {.can_read = true};
|
constexpr directory::rules read_only_rules = {.can_read = true};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -116,7 +116,7 @@ export namespace app {
|
||||||
if (path == nullptr) {
|
if (path == nullptr) {
|
||||||
this->cwd_directory.target("./", read_only_rules);
|
this->cwd_directory.target("./", read_only_rules);
|
||||||
} else {
|
} else {
|
||||||
core::usize path_length = 0;
|
coral::usize path_length = 0;
|
||||||
|
|
||||||
while (path[path_length] != 0) path_length += 1;
|
while (path[path_length] != 0) path_length += 1;
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ export namespace app {
|
||||||
char * const path = ::SDL_GetPrefPath("ona", title.begin());
|
char * const path = ::SDL_GetPrefPath("ona", title.begin());
|
||||||
|
|
||||||
if (path != nullptr) {
|
if (path != nullptr) {
|
||||||
core::usize path_length = 0;
|
coral::usize path_length = 0;
|
||||||
|
|
||||||
while (path[path_length] != 0) path_length += 1;
|
while (path[path_length] != 0) path_length += 1;
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ export namespace app {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core::fs & cwd_fs() {
|
coral::fs & cwd_fs() {
|
||||||
return this->cwd_directory;
|
return this->cwd_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,32 +161,32 @@ export namespace app {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::fs & res_fs() {
|
coral::fs & res_fs() {
|
||||||
return this->res_archive;
|
return this->res_archive;
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(app::log_level level, core::slice<char const> const & message) {
|
void log(app::log_level level, coral::slice<char const> const & message) {
|
||||||
core::i32 const length = static_cast<core::i32>(
|
coral::i32 const length = static_cast<coral::i32>(
|
||||||
core::min(message.length, static_cast<size_t>(core::i32_max)));
|
coral::min(message.length, static_cast<size_t>(coral::i32_max)));
|
||||||
|
|
||||||
::SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,
|
::SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
SDL_LOG_PRIORITY_INFO, "%.*s", length, message.pointer);
|
SDL_LOG_PRIORITY_INFO, "%.*s", length, message.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
core::allocator & thread_safe_allocator() {
|
coral::allocator & thread_safe_allocator() {
|
||||||
return this->allocator;
|
return this->allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::fs & user_fs() {
|
coral::fs & user_fs() {
|
||||||
return this->user_directory;
|
return this->user_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::SDL_Event sdl_event;
|
::SDL_Event sdl_event;
|
||||||
|
|
||||||
struct : public core::allocator {
|
struct : public coral::allocator {
|
||||||
core::u8 * reallocate(core::u8 * maybe_allocation, core::usize requested_size) override {
|
coral::u8 * reallocate(coral::u8 * maybe_allocation, coral::usize requested_size) override {
|
||||||
return reinterpret_cast<core::u8 *>(::SDL_malloc(requested_size));
|
return reinterpret_cast<coral::u8 *>(::SDL_malloc(requested_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(void * allocation) override {
|
void deallocate(void * allocation) override {
|
||||||
|
@ -208,10 +208,10 @@ export namespace app {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct canvas {
|
struct canvas {
|
||||||
core::color background_color;
|
coral::color background_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
graphics(core::path const & title) {
|
graphics(coral::path const & title) {
|
||||||
this->retitle(title);
|
this->retitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,17 +225,17 @@ export namespace app {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void retitle(core::path const & title) {
|
void retitle(coral::path const & title) {
|
||||||
this->title = title;
|
this->title = title;
|
||||||
|
|
||||||
if (this->sdl_window != nullptr)
|
if (this->sdl_window != nullptr)
|
||||||
::SDL_SetWindowTitle(this->sdl_window, this->title.begin());
|
::SDL_SetWindowTitle(this->sdl_window, this->title.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
show_result show(core::u16 physical_width, core::u16 physical_height) {
|
show_result show(coral::u16 physical_width, coral::u16 physical_height) {
|
||||||
if (this->sdl_window == nullptr) {
|
if (this->sdl_window == nullptr) {
|
||||||
constexpr int sdl_windowpos = SDL_WINDOWPOS_UNDEFINED;
|
constexpr int sdl_windowpos = SDL_WINDOWPOS_UNDEFINED;
|
||||||
constexpr core::u32 sdl_windowflags = 0;
|
constexpr coral::u32 sdl_windowflags = 0;
|
||||||
|
|
||||||
this->sdl_window = ::SDL_CreateWindow(this->title.begin(), sdl_windowpos,
|
this->sdl_window = ::SDL_CreateWindow(this->title.begin(), sdl_windowpos,
|
||||||
sdl_windowpos, static_cast<int>(physical_width), static_cast<int>(physical_height),
|
sdl_windowpos, static_cast<int>(physical_width), static_cast<int>(physical_height),
|
||||||
|
@ -247,7 +247,7 @@ export namespace app {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->sdl_renderer == nullptr) {
|
if (this->sdl_renderer == nullptr) {
|
||||||
constexpr core::u32 sdl_rendererflags = 0;
|
constexpr coral::u32 sdl_rendererflags = 0;
|
||||||
|
|
||||||
this->sdl_renderer = ::SDL_CreateRenderer(this->sdl_window, -1, sdl_rendererflags);
|
this->sdl_renderer = ::SDL_CreateRenderer(this->sdl_window, -1, sdl_rendererflags);
|
||||||
|
|
||||||
|
@ -264,16 +264,16 @@ export namespace app {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::path title;
|
coral::path title;
|
||||||
|
|
||||||
::SDL_Window * sdl_window = nullptr;
|
::SDL_Window * sdl_window = nullptr;
|
||||||
|
|
||||||
::SDL_Renderer * sdl_renderer = nullptr;
|
::SDL_Renderer * sdl_renderer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
using graphical_runnable = core::callable<int(system &, graphics &)>;
|
using graphical_runnable = coral::callable<int(system &, graphics &)>;
|
||||||
|
|
||||||
int display(core::path const & title, graphical_runnable const & run) {
|
int display(coral::path const & title, graphical_runnable const & run) {
|
||||||
system app_system{title};
|
system app_system{title};
|
||||||
graphics app_graphics{title};
|
graphics app_graphics{title};
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ module;
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
export module core;
|
export module coral;
|
||||||
|
|
||||||
// Runtime utilities.
|
// Runtime utilities.
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Triggers safety-checked behavior in debug mode.
|
* Triggers safety-checked behavior in debug mode.
|
||||||
*
|
*
|
||||||
|
@ -19,7 +19,7 @@ export namespace core {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concrete and interface types.
|
// Concrete and interface types.
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
using usize = size_t;
|
using usize = size_t;
|
||||||
|
|
||||||
using size = __ssize_t;
|
using size = __ssize_t;
|
||||||
|
@ -180,7 +180,7 @@ export namespace core {
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr type & operator[](usize index) const {
|
constexpr type & operator[](usize index) const {
|
||||||
if (this->length <= index) core::unreachable();
|
if (this->length <= index) unreachable();
|
||||||
|
|
||||||
return this->pointer[index];
|
return this->pointer[index];
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ export namespace core {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Math functions.
|
// Math functions.
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Returns the maximum value between `a` and `b`.
|
* Returns the maximum value between `a` and `b`.
|
||||||
*/
|
*/
|
||||||
|
@ -225,8 +225,8 @@ export namespace core {
|
||||||
* *Note*: passing an `buffer` smaller than `requested_size` will result in safety-checked
|
* *Note*: passing an `buffer` smaller than `requested_size` will result in safety-checked
|
||||||
* behavior.
|
* behavior.
|
||||||
*/
|
*/
|
||||||
export void * operator new(core::usize requested_size, core::slice<core::u8> const & buffer) {
|
export void * operator new(coral::usize requested_size, coral::slice<coral::u8> const & buffer) {
|
||||||
if (buffer.length < requested_size) core::unreachable();
|
if (buffer.length < requested_size) coral::unreachable();
|
||||||
|
|
||||||
return buffer.pointer;
|
return buffer.pointer;
|
||||||
}
|
}
|
||||||
|
@ -239,8 +239,8 @@ export void * operator new(core::usize requested_size, core::slice<core::u8> con
|
||||||
* *Note*: passing an `buffer` smaller than `requested_size` will result in safety-checked
|
* *Note*: passing an `buffer` smaller than `requested_size` will result in safety-checked
|
||||||
* behavior.
|
* behavior.
|
||||||
*/
|
*/
|
||||||
export void * operator new[](core::usize requested_size, core::slice<core::u8> const & buffer) {
|
export void * operator new[](coral::usize requested_size, coral::slice<coral::u8> const & buffer) {
|
||||||
if (buffer.length < requested_size) core::unreachable();
|
if (buffer.length < requested_size) coral::unreachable();
|
||||||
|
|
||||||
return buffer.pointer;
|
return buffer.pointer;
|
||||||
}
|
}
|
||||||
|
@ -249,10 +249,10 @@ export void * operator new[](core::usize requested_size, core::slice<core::u8> c
|
||||||
* Attempts to allocate and initialize a type of `requested_size` using `allocator`.
|
* Attempts to allocate and initialize a type of `requested_size` using `allocator`.
|
||||||
*
|
*
|
||||||
* *Note*: If the returned address is a non-`nullptr`, it should be deallocated prior to program
|
* *Note*: If the returned address is a non-`nullptr`, it should be deallocated prior to program
|
||||||
* exit. This may be achieved through either [core::allocator::deallocate] or implementation-
|
* exit. This may be achieved through either [coral::allocator::deallocate] or implementation-
|
||||||
* specific allocator functionality.
|
* specific allocator functionality.
|
||||||
*/
|
*/
|
||||||
export [[nodiscard]] void * operator new(core::usize requested_size, core::allocator & allocator) {
|
export [[nodiscard]] void * operator new(coral::usize requested_size, coral::allocator & allocator) {
|
||||||
return allocator.reallocate(nullptr, requested_size);
|
return allocator.reallocate(nullptr, requested_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,15 +260,15 @@ export [[nodiscard]] void * operator new(core::usize requested_size, core::alloc
|
||||||
* Attempts to allocate and initialize a series of types of `requested_size` using `allocator`.
|
* Attempts to allocate and initialize a series of types of `requested_size` using `allocator`.
|
||||||
*
|
*
|
||||||
* *Note*: If the returned address is a non-`nullptr`, it should be deallocated prior to program
|
* *Note*: If the returned address is a non-`nullptr`, it should be deallocated prior to program
|
||||||
* exit. This may be achieved through either [core::allocator::deallocate] or implementation-
|
* exit. This may be achieved through either [coral::allocator::deallocate] or implementation-
|
||||||
* specific allocator functionality.
|
* specific allocator functionality.
|
||||||
*/
|
*/
|
||||||
export [[nodiscard]] void * operator new[](core::usize requested_size, core::allocator & allocator) {
|
export [[nodiscard]] void * operator new[](coral::usize requested_size, coral::allocator & allocator) {
|
||||||
return allocator.reallocate(nullptr, requested_size);
|
return allocator.reallocate(nullptr, requested_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper types.
|
// Wrapper types.
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Monadic container for a single-`element` value or nothing.
|
* Monadic container for a single-`element` value or nothing.
|
||||||
*/
|
*/
|
||||||
|
@ -456,7 +456,7 @@ export namespace core {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input/output operations.
|
// Input/output operations.
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Compares `a` and `b`, returning the difference between them or `0` if they are identical.
|
* Compares `a` and `b`, returning the difference between them or `0` if they are identical.
|
||||||
*/
|
*/
|
||||||
|
@ -478,7 +478,7 @@ export namespace core {
|
||||||
* *Note*: safety-checked behavior is triggered if `target` is smaller than `origin`.
|
* *Note*: safety-checked behavior is triggered if `target` is smaller than `origin`.
|
||||||
*/
|
*/
|
||||||
void copy(slice<u8> const & target, slice<u8 const> const & origin) {
|
void copy(slice<u8> const & target, slice<u8 const> const & origin) {
|
||||||
if (target.length < origin.length) core::unreachable();
|
if (target.length < origin.length) coral::unreachable();
|
||||||
|
|
||||||
for (usize i = 0; i < origin.length; i += 1) target[i] = origin[i];
|
for (usize i = 0; i < origin.length; i += 1) target[i] = origin[i];
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
export module core.files;
|
export module coral.files;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
|
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Platform-generalized identifier for a resource in a [file_store].
|
* Platform-generalized identifier for a resource in a [file_store].
|
||||||
*/
|
*/
|
||||||
|
@ -50,7 +50,7 @@ export namespace core {
|
||||||
* they are identical.
|
* they are identical.
|
||||||
*/
|
*/
|
||||||
constexpr size compare(path const & that) const {
|
constexpr size compare(path const & that) const {
|
||||||
return core::compare(slice{this->begin(), this->end()}.as_bytes(),
|
return coral::compare(slice{this->begin(), this->end()}.as_bytes(),
|
||||||
slice{that.begin(), that.end()}.as_bytes());
|
slice{that.begin(), that.end()}.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ export namespace core {
|
||||||
* otherwise `false`.
|
* otherwise `false`.
|
||||||
*/
|
*/
|
||||||
constexpr bool equals(path const & that) const {
|
constexpr bool equals(path const & that) const {
|
||||||
return core::equals(slice{this->begin(), this->end()}.as_bytes(),
|
return coral::equals(slice{this->begin(), this->end()}.as_bytes(),
|
||||||
slice{that.begin(), that.end()}.as_bytes());
|
slice{that.begin(), that.end()}.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ export namespace core {
|
||||||
* *Note:* the returned hash code is not guaranteed to be unique.
|
* *Note:* the returned hash code is not guaranteed to be unique.
|
||||||
*/
|
*/
|
||||||
constexpr u64 hash() const {
|
constexpr u64 hash() const {
|
||||||
return core::hash(slice{this->begin(), this->end()}.as_bytes());
|
return coral::hash(slice{this->begin(), this->end()}.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -1,8 +1,8 @@
|
||||||
export module core.image;
|
export module coral.image;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
|
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* All-purpose color value for red, green, blue, alpha channel-encoded values.
|
* All-purpose color value for red, green, blue, alpha channel-encoded values.
|
||||||
*/
|
*/
|
|
@ -1,8 +1,8 @@
|
||||||
export module core.math;
|
export module coral.math;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
|
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Two-component vector type backed by 32-bit floating point values.
|
* Two-component vector type backed by 32-bit floating point values.
|
||||||
*/
|
*/
|
|
@ -1,8 +1,8 @@
|
||||||
export module core.sequence;
|
export module coral.sequence;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
|
|
||||||
export namespace core {
|
export namespace coral {
|
||||||
/**
|
/**
|
||||||
* Result codes used by [sequence]-derived types when they are appended to in any way.
|
* Result codes used by [sequence]-derived types when they are appended to in any way.
|
||||||
*
|
*
|
||||||
|
@ -179,7 +179,7 @@ export namespace core {
|
||||||
return append_result::out_of_memory;
|
return append_result::out_of_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::copy({buffer, buffer_size}, this->elements.as_bytes());
|
coral::copy({buffer, buffer_size}, this->elements.as_bytes());
|
||||||
|
|
||||||
this->elements = {reinterpret_cast<element *>(buffer), requested_capacity};
|
this->elements = {reinterpret_cast<element *>(buffer), requested_capacity};
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
export module kym;
|
export module kym;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
import core.math;
|
import coral.math;
|
||||||
|
|
||||||
export namespace kym {
|
export namespace kym {
|
||||||
enum class value_type {
|
enum class value_type {
|
||||||
|
@ -20,22 +20,22 @@ export namespace kym {
|
||||||
union {
|
union {
|
||||||
bool boolean;
|
bool boolean;
|
||||||
|
|
||||||
core::i64 integer;
|
coral::i64 integer;
|
||||||
|
|
||||||
core::f64 scalar;
|
coral::f64 scalar;
|
||||||
|
|
||||||
core::vector2 vector2;
|
coral::vector2 vector2;
|
||||||
|
|
||||||
core::vector3 vector3;
|
coral::vector3 vector3;
|
||||||
|
|
||||||
void * object;
|
void * object;
|
||||||
} as;
|
} as;
|
||||||
|
|
||||||
core::optional<core::u16> as_u16() const {
|
coral::optional<coral::u16> as_u16() const {
|
||||||
if ((this->type == value_type::integer) &&
|
if ((this->type == value_type::integer) &&
|
||||||
(this->as.integer >= 0) && (this->as.integer <= core::u16_max)) {
|
(this->as.integer >= 0) && (this->as.integer <= coral::u16_max)) {
|
||||||
|
|
||||||
return static_cast<core::u16>(this->as.integer);
|
return static_cast<coral::u16>(this->as.integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
export module kym.environment;
|
export module kym.environment;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
import core.sequence;
|
import coral.sequence;
|
||||||
|
|
||||||
import kym;
|
import kym;
|
||||||
|
|
||||||
using loggable = core::callable<void(core::slice<char const> const &)>;
|
using loggable = coral::callable<void(coral::slice<char const> const &)>;
|
||||||
|
|
||||||
export namespace kym {
|
export namespace kym {
|
||||||
struct vm;
|
struct vm;
|
||||||
|
@ -16,18 +16,18 @@ enum class token_kind {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct token {
|
struct token {
|
||||||
core::slice<char const> text;
|
coral::slice<char const> text;
|
||||||
|
|
||||||
token_kind kind;
|
token_kind kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tokenizer {
|
struct tokenizer {
|
||||||
core::slice<char const> source;
|
coral::slice<char const> source;
|
||||||
|
|
||||||
tokenizer(core::slice<char const> const & source) : source{source} {}
|
tokenizer(coral::slice<char const> const & source) : source{source} {}
|
||||||
|
|
||||||
token next() {
|
token next() {
|
||||||
core::usize cursor = 0;
|
coral::usize cursor = 0;
|
||||||
|
|
||||||
while (cursor < source.length) {
|
while (cursor < source.length) {
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ struct tokenizer {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bytecode {
|
struct bytecode {
|
||||||
bytecode(core::allocator * allocator) : error_message_buffer{allocator} {
|
bytecode(coral::allocator * allocator) : error_message_buffer{allocator} {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,26 +51,26 @@ struct bytecode {
|
||||||
switch (initial_token.kind) {
|
switch (initial_token.kind) {
|
||||||
case token_kind::end: return true;
|
case token_kind::end: return true;
|
||||||
|
|
||||||
default: core::unreachable();
|
default: coral::unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kym::value execute(kym::vm & vm, core::slice<kym::value const> const & arguments) {
|
kym::value execute(kym::vm & vm, coral::slice<kym::value const> const & arguments) {
|
||||||
return kym::nil;
|
return kym::nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::stack<char> error_message_buffer;
|
coral::stack<char> error_message_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
export namespace kym {
|
export namespace kym {
|
||||||
value default_call(vm & owning_vm, void * userdata, core::slice<value const> const & arguments) {
|
value default_call(vm & owning_vm, void * userdata, coral::slice<value const> const & arguments) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::expected<core::usize, core::io_error> default_stringify(vm & owning_vm, void * userdata, core::writable const & output) {
|
coral::expected<coral::usize, coral::io_error> default_stringify(vm & owning_vm, void * userdata, coral::writable const & output) {
|
||||||
return output(core::slice{"[object]"}.as_bytes());
|
return output(coral::slice{"[object]"}.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bound_object {
|
struct bound_object {
|
||||||
|
@ -79,9 +79,9 @@ export namespace kym {
|
||||||
struct {
|
struct {
|
||||||
void(*cleanup)(vm &, void *);
|
void(*cleanup)(vm &, void *);
|
||||||
|
|
||||||
value(*call)(vm &, void *, core::slice<value const> const &);
|
value(*call)(vm &, void *, coral::slice<value const> const &);
|
||||||
|
|
||||||
core::expected<core::usize, core::io_error>(*stringify)(vm &, void *, core::writable const &);
|
coral::expected<coral::usize, coral::io_error>(*stringify)(vm &, void *, coral::writable const &);
|
||||||
} behavior;
|
} behavior;
|
||||||
|
|
||||||
bound_object(vm * owning_vm) : userdata{nullptr}, owning_vm{owning_vm}, behavior{
|
bound_object(vm * owning_vm) : userdata{nullptr}, owning_vm{owning_vm}, behavior{
|
||||||
|
@ -94,15 +94,15 @@ export namespace kym {
|
||||||
this->behavior.cleanup(*this->owning_vm, this->userdata);
|
this->behavior.cleanup(*this->owning_vm, this->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
value call(core::slice<value const> const & arguments) {
|
value call(coral::slice<value const> const & arguments) {
|
||||||
return this->behavior.call(*this->owning_vm, this->userdata, arguments);
|
return this->behavior.call(*this->owning_vm, this->userdata, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
core::expected<core::usize, core::io_error> stringify(core::writable const & output) {
|
coral::expected<coral::usize, coral::io_error> stringify(coral::writable const & output) {
|
||||||
return this->behavior.stringify(*this->owning_vm, this->userdata, output);
|
return this->behavior.stringify(*this->owning_vm, this->userdata, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
value get_field(core::slice<char const> const & field_name) {
|
value get_field(coral::slice<char const> const & field_name) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,12 +112,12 @@ export namespace kym {
|
||||||
|
|
||||||
struct vm {
|
struct vm {
|
||||||
struct init_options {
|
struct init_options {
|
||||||
core::u16 datastack_size;
|
coral::u16 datastack_size;
|
||||||
|
|
||||||
core::u16 callstack_size;
|
coral::u16 callstack_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
vm(core::allocator * allocator, auto log) : allocator{allocator}, log{log}, data_stack{} {}
|
vm(coral::allocator * allocator, auto log) : allocator{allocator}, log{log}, data_stack{} {}
|
||||||
|
|
||||||
~vm() {
|
~vm() {
|
||||||
if (this->data_stack.pointer != nullptr)
|
if (this->data_stack.pointer != nullptr)
|
||||||
|
@ -125,8 +125,8 @@ export namespace kym {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(init_options const & options) {
|
bool init(init_options const & options) {
|
||||||
core::u8 * const data_stack_buffer = this->allocator->reallocate(reinterpret_cast
|
coral::u8 * const data_stack_buffer = this->allocator->reallocate(reinterpret_cast
|
||||||
<core::u8 *>(this->data_stack.pointer), options.datastack_size * sizeof(value));
|
<coral::u8 *>(this->data_stack.pointer), options.datastack_size * sizeof(value));
|
||||||
|
|
||||||
if (data_stack_buffer == nullptr) return false;
|
if (data_stack_buffer == nullptr) return false;
|
||||||
|
|
||||||
|
@ -136,12 +136,12 @@ export namespace kym {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
value compile(core::slice<char const> const & source) {
|
value compile(coral::slice<char const> const & source) {
|
||||||
bytecode * source_bytecode = new (*this->allocator) bytecode{allocator};
|
bytecode * source_bytecode = new (*this->allocator) bytecode{allocator};
|
||||||
|
|
||||||
if (source_bytecode == nullptr) return nil;
|
if (source_bytecode == nullptr) return nil;
|
||||||
|
|
||||||
if (!source_bytecode->compile(tokenizer{source}, [&](core::slice<char const> error_message) {
|
if (!source_bytecode->compile(tokenizer{source}, [&](coral::slice<char const> error_message) {
|
||||||
this->log(error_message);
|
this->log(error_message);
|
||||||
})) {
|
})) {
|
||||||
this->allocator->deallocate(source_bytecode);
|
this->allocator->deallocate(source_bytecode);
|
||||||
|
@ -156,7 +156,7 @@ export namespace kym {
|
||||||
owning_vm.allocator->deallocate(userdata);
|
owning_vm.allocator->deallocate(userdata);
|
||||||
};
|
};
|
||||||
|
|
||||||
object.behavior.call = [](vm & owning_vm, void * userdata, core::slice<value const> const & arguments) -> value {
|
object.behavior.call = [](vm & owning_vm, void * userdata, coral::slice<value const> const & arguments) -> value {
|
||||||
return reinterpret_cast<bytecode *>(userdata)->execute(owning_vm, arguments);
|
return reinterpret_cast<bytecode *>(userdata)->execute(owning_vm, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,19 +164,19 @@ export namespace kym {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
value new_object(core::callable<void(bound_object &)> const & then) {
|
value new_object(coral::callable<void(bound_object &)> const & then) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
void with_object(value object_value, core::callable<void(bound_object &)> const & then) {
|
void with_object(value object_value, coral::callable<void(bound_object &)> const & then) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::slice<value> data_stack;
|
coral::slice<value> data_stack;
|
||||||
|
|
||||||
loggable log;
|
loggable log;
|
||||||
|
|
||||||
core::allocator * allocator;
|
coral::allocator * allocator;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
export module oar;
|
export module oar;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
import core.files;
|
import coral.files;
|
||||||
|
|
||||||
export namespace oar {
|
export namespace oar {
|
||||||
constexpr core::usize signature_length{4};
|
constexpr coral::usize signature_length{4};
|
||||||
|
|
||||||
constexpr core::u8 signature_magic[signature_length]{'o', 'a', 'r', 0};
|
constexpr coral::u8 signature_magic[signature_length]{'o', 'a', 'r', 0};
|
||||||
|
|
||||||
struct entry {
|
struct entry {
|
||||||
core::u8 signature_magic[signature_length];
|
coral::u8 signature_magic[signature_length];
|
||||||
|
|
||||||
core::path path;
|
coral::path path;
|
||||||
|
|
||||||
core::u64 data_offset;
|
coral::u64 data_offset;
|
||||||
|
|
||||||
core::u64 data_length;
|
coral::u64 data_length;
|
||||||
|
|
||||||
core::u8 padding[244];
|
coral::u8 padding[244];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct archive : public core::fs {
|
struct archive : public coral::fs {
|
||||||
using core::fs::access_result;
|
using coral::fs::access_result;
|
||||||
|
|
||||||
archive() {
|
archive() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
access_result read_file(core::path const & file_path,
|
access_result read_file(coral::path const & file_path,
|
||||||
core::callable<void(core::readable const &)> const & then) override {
|
coral::callable<void(coral::readable const &)> const & then) override {
|
||||||
|
|
||||||
return access_result::access_denied;
|
return access_result::access_denied;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual access_result write_file(core::path const & file_path,
|
virtual access_result write_file(coral::path const & file_path,
|
||||||
core::callable<void(core::writable const &)> const & then) override {
|
coral::callable<void(coral::writable const &)> const & then) override {
|
||||||
|
|
||||||
return access_result::access_denied;
|
return access_result::access_denied;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,22 @@ export module runtime;
|
||||||
|
|
||||||
import app;
|
import app;
|
||||||
|
|
||||||
import core;
|
import coral;
|
||||||
import core.files;
|
import coral.files;
|
||||||
import core.math;
|
import coral.math;
|
||||||
import core.sequence;
|
import coral.sequence;
|
||||||
|
|
||||||
import kym;
|
import kym;
|
||||||
import kym.environment;
|
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 core::path config_path{"config.kym"};
|
constexpr coral::path config_path{"config.kym"};
|
||||||
bool is_config_loaded{false};
|
bool is_config_loaded{false};
|
||||||
|
|
||||||
if ((system.res_fs().read_file(config_path, [&](core::readable const & file) {
|
if ((system.res_fs().read_file(config_path, [&](coral::readable const & file) {
|
||||||
kym::vm vm{&system.thread_safe_allocator(),
|
kym::vm vm{&system.thread_safe_allocator(),
|
||||||
[&system](core::slice<char const> const & error_message) {
|
[&system](coral::slice<char const> const & error_message) {
|
||||||
system.log(app::log_level::error, error_message);
|
system.log(app::log_level::error, error_message);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -30,20 +30,20 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::stack<core::u8> script_source{&system.thread_safe_allocator()};
|
coral::stack<coral::u8> script_source{&system.thread_safe_allocator()};
|
||||||
core::u8 stream_buffer[1024]{0};
|
coral::u8 stream_buffer[1024]{0};
|
||||||
|
|
||||||
if (!core::stream(core::sequence_writer{&script_source}, file, stream_buffer).is_ok())
|
if (!coral::stream(coral::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(coral::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)};
|
coral::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)};
|
coral::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");
|
||||||
|
@ -52,9 +52,9 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
return system.log(app::log_level::error, "failed to initialize window");
|
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()};
|
coral::stack<coral::u8, 128> title_buffer{&system.thread_safe_allocator()};
|
||||||
|
|
||||||
if (!title.stringify(core::sequence_writer(&title_buffer)).is_ok()) {
|
if (!title.stringify(coral::sequence_writer(&title_buffer)).is_ok()) {
|
||||||
system.log(app::log_level::error,
|
system.log(app::log_level::error,
|
||||||
"failed to decode `title` property of config");
|
"failed to decode `title` property of config");
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}) != core::fs::access_result::ok) || (!is_config_loaded)) return core::u8_max;
|
}) != coral::fs::access_result::ok) || (!is_config_loaded)) return coral::u8_max;
|
||||||
|
|
||||||
// app::canvas canvas_2d();
|
// app::canvas canvas_2d();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue