Compare commits
3 Commits
cba6e26995
...
c45a270a0b
Author | SHA1 | Date |
---|---|---|
kayomn | c45a270a0b | |
kayomn | 3856a03ec1 | |
kayomn | 8ced8440fc |
|
@ -13,8 +13,6 @@ import oar;
|
||||||
|
|
||||||
export namespace app {
|
export namespace app {
|
||||||
struct directory : public coral::fs {
|
struct directory : public coral::fs {
|
||||||
using coral::fs::access_result;
|
|
||||||
|
|
||||||
struct rules {
|
struct rules {
|
||||||
bool can_read;
|
bool can_read;
|
||||||
|
|
||||||
|
@ -23,24 +21,22 @@ export namespace app {
|
||||||
|
|
||||||
directory() : path_buffer{0} {}
|
directory() : path_buffer{0} {}
|
||||||
|
|
||||||
access_result read_file(coral::path const & file_path,
|
void read_file(coral::path const & file_path,
|
||||||
coral::callable<void(coral::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;
|
||||||
|
|
||||||
if (!this->access_rules.can_read) return access_result::access_denied;
|
if (!this->access_rules.can_read) return;
|
||||||
|
|
||||||
::SDL_RWops * rw_ops = this->open_rw(file_path, {.can_read = true});
|
::SDL_RWops * rw_ops{this->open_rw(file_path, {.can_read = true})};
|
||||||
|
|
||||||
if (rw_ops == nullptr) return access_result::not_found;
|
if (rw_ops == nullptr) return;
|
||||||
|
|
||||||
then([rw_ops](coral::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);
|
||||||
});
|
});
|
||||||
|
|
||||||
::SDL_RWclose(rw_ops);
|
::SDL_RWclose(rw_ops);
|
||||||
|
|
||||||
return access_result::ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void target(coral::slice<char const> const & directory_path, rules const & access_rules) {
|
void target(coral::slice<char const> const & directory_path, rules const & access_rules) {
|
||||||
|
@ -57,24 +53,22 @@ export namespace app {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
access_result write_file(coral::path const & file_path,
|
void write_file(coral::path const & file_path,
|
||||||
coral::callable<void(coral::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;
|
||||||
|
|
||||||
if (!this->access_rules.can_write) return access_result::access_denied;
|
if (!this->access_rules.can_write) return;
|
||||||
|
|
||||||
::SDL_RWops * rw_ops = this->open_rw(file_path, {.can_write = true});
|
::SDL_RWops * rw_ops{this->open_rw(file_path, {.can_write = true})};
|
||||||
|
|
||||||
if (rw_ops == nullptr) return access_result::not_found;
|
if (rw_ops == nullptr) return;
|
||||||
|
|
||||||
then([rw_ops](coral::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);
|
||||||
});
|
});
|
||||||
|
|
||||||
::SDL_RWclose(rw_ops);
|
::SDL_RWclose(rw_ops);
|
||||||
|
|
||||||
return access_result::ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -87,14 +81,14 @@ export namespace app {
|
||||||
coral::u8 path_buffer[path_max];
|
coral::u8 path_buffer[path_max];
|
||||||
|
|
||||||
::SDL_RWops * open_rw(coral::path const & file_path, rules const & file_rules) {
|
::SDL_RWops * open_rw(coral::path const & file_path, rules const & file_rules) {
|
||||||
coral::u8 * const path_begin = this->path_buffer + this->prefix_length;
|
coral::u8 * const path_begin{this->path_buffer + this->prefix_length};
|
||||||
|
|
||||||
coral::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;
|
||||||
|
|
||||||
coral::copy(path_remaining, coral::slice{file_path.begin(), file_path.end()}.as_bytes());
|
coral::copy(path_remaining, file_path.as_slice().as_bytes());
|
||||||
|
|
||||||
return ::SDL_RWFromFile(reinterpret_cast<char const *>(this->path_buffer), "r");
|
return ::SDL_RWFromFile(reinterpret_cast<char const *>(this->path_buffer), "r");
|
||||||
}
|
}
|
||||||
|
@ -111,12 +105,12 @@ export namespace app {
|
||||||
constexpr directory::rules read_only_rules = {.can_read = true};
|
constexpr directory::rules read_only_rules = {.can_read = true};
|
||||||
|
|
||||||
{
|
{
|
||||||
char * const path = ::SDL_GetBasePath();
|
char * const path{::SDL_GetBasePath()};
|
||||||
|
|
||||||
if (path == nullptr) {
|
if (path == nullptr) {
|
||||||
this->cwd_directory.target("./", read_only_rules);
|
this->cwd_directory.target("./", read_only_rules);
|
||||||
} else {
|
} else {
|
||||||
coral::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;
|
||||||
|
|
||||||
|
@ -131,10 +125,10 @@ 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) {
|
||||||
coral::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;
|
||||||
|
|
||||||
|
@ -166,8 +160,8 @@ export namespace app {
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(app::log_level level, coral::slice<char const> const & message) {
|
void log(app::log_level level, coral::slice<char const> const & message) {
|
||||||
coral::i32 const length = static_cast<coral::i32>(
|
coral::i32 const length{static_cast<coral::i32>(
|
||||||
coral::min(message.length, static_cast<size_t>(coral::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);
|
||||||
|
@ -215,6 +209,12 @@ export namespace app {
|
||||||
this->retitle(title);
|
this->retitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void present() {
|
||||||
|
if (this->sdl_renderer != nullptr) {
|
||||||
|
::SDL_RenderPresent(this->sdl_renderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void render(canvas & source_canvas) {
|
void render(canvas & source_canvas) {
|
||||||
if (this->sdl_renderer != nullptr) {
|
if (this->sdl_renderer != nullptr) {
|
||||||
SDL_SetRenderDrawColor(this->sdl_renderer, source_canvas.background_color.to_r8(),
|
SDL_SetRenderDrawColor(this->sdl_renderer, source_canvas.background_color.to_r8(),
|
||||||
|
@ -257,12 +257,6 @@ export namespace app {
|
||||||
return show_result::ok;
|
return show_result::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void present() {
|
|
||||||
if (this->sdl_renderer != nullptr) {
|
|
||||||
::SDL_RenderPresent(this->sdl_renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
coral::path title;
|
coral::path title;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,13 @@ export namespace coral {
|
||||||
this->buffer[max] = max - text_size;
|
this->buffer[max] = max - text_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a weak reference to the [path] as a [slice].
|
||||||
|
*/
|
||||||
|
constexpr slice<char const> as_slice() const {
|
||||||
|
return {this->buffer, this->byte_size()};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the base pointer of the path name.
|
* Returns the base pointer of the path name.
|
||||||
*
|
*
|
||||||
|
@ -50,8 +57,7 @@ export namespace coral {
|
||||||
* they are identical.
|
* they are identical.
|
||||||
*/
|
*/
|
||||||
constexpr size compare(path const & that) const {
|
constexpr size compare(path const & that) const {
|
||||||
return coral::compare(slice{this->begin(), this->end()}.as_bytes(),
|
return coral::compare(this->as_slice().as_bytes(), that.as_slice().as_bytes());
|
||||||
slice{that.begin(), that.end()}.as_bytes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,8 +72,7 @@ export namespace coral {
|
||||||
* otherwise `false`.
|
* otherwise `false`.
|
||||||
*/
|
*/
|
||||||
constexpr bool equals(path const & that) const {
|
constexpr bool equals(path const & that) const {
|
||||||
return coral::equals(slice{this->begin(), this->end()}.as_bytes(),
|
return coral::equals(this->as_slice().as_bytes(), that.as_slice().as_bytes());
|
||||||
slice{that.begin(), that.end()}.as_bytes());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,7 +81,7 @@ export namespace coral {
|
||||||
* *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 coral::hash(slice{this->begin(), this->end()}.as_bytes());
|
return coral::hash(this->as_slice().as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,43 +110,22 @@ export namespace coral {
|
||||||
* Platform-generalized file system interface.
|
* Platform-generalized file system interface.
|
||||||
*/
|
*/
|
||||||
struct fs {
|
struct fs {
|
||||||
/**
|
|
||||||
* The result from a file access operation.
|
|
||||||
*
|
|
||||||
* [file_result::ok] indicates a successful file access operation.
|
|
||||||
*
|
|
||||||
* [file_result::not_found] signals that the file was not found.
|
|
||||||
*
|
|
||||||
* [file_result::access_denied] warns that the file was found but cannot be opened through
|
|
||||||
* the file system interface. The most common scenario for this error is a lack of required
|
|
||||||
* file permissions.
|
|
||||||
*/
|
|
||||||
enum class [[nodiscard]] access_result {
|
|
||||||
ok,
|
|
||||||
not_found,
|
|
||||||
access_denied,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to read the file in the file system located at `file_path` relative, calling
|
* Attempts to read the file in the file system located at `file_path` relative, calling
|
||||||
* `then` if it was successfully opened for reading.
|
* `then` if it was successfully opened for reading.
|
||||||
*
|
*
|
||||||
* The returned [access_result] indicates whether the operation was successful or not.
|
|
||||||
*
|
|
||||||
* Once `then` returns, access to the file is closed automatically.
|
* Once `then` returns, access to the file is closed automatically.
|
||||||
*/
|
*/
|
||||||
virtual access_result read_file(path const & file_path,
|
virtual void read_file(path const & file_path,
|
||||||
callable<void(readable const &)> const & then) = 0;
|
callable<void(readable const &)> const & then) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to write the file in the file system located at `file_path` relative, calling
|
* Attempts to write the file in the file system located at `file_path` relative, calling
|
||||||
* `then` if it was successfully opened for writing.
|
* `then` if it was successfully opened for writing.
|
||||||
*
|
*
|
||||||
* The returned [access_result] indicates whether the operation was successful or not.
|
|
||||||
*
|
|
||||||
* Once `then` returns, access to the file is closed automatically.
|
* Once `then` returns, access to the file is closed automatically.
|
||||||
*/
|
*/
|
||||||
virtual access_result write_file(path const & file_path,
|
virtual void write_file(path const & file_path,
|
||||||
callable<void(writable const &)> const & then) = 0;
|
callable<void(writable const &)> const & then) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,22 +21,16 @@ export namespace oar {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct archive : public coral::fs {
|
struct archive : public coral::fs {
|
||||||
using coral::fs::access_result;
|
|
||||||
|
|
||||||
archive() {
|
archive() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
access_result read_file(coral::path const & file_path,
|
void read_file(coral::path const & file_path,
|
||||||
coral::callable<void(coral::readable const &)> const & then) override {
|
coral::callable<void(coral::readable const &)> const & then) override {
|
||||||
|
|
||||||
return access_result::access_denied;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual access_result write_file(coral::path const & file_path,
|
void write_file(coral::path const & file_path,
|
||||||
coral::callable<void(coral::writable const &)> const & then) override {
|
coral::callable<void(coral::writable const &)> const & then) override {
|
||||||
|
|
||||||
return access_result::access_denied;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,22 +15,20 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
constexpr coral::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, [&](coral::readable const & file) {
|
system.res_fs().read_file(config_path, [&](coral::readable const & file) {
|
||||||
kym::vm vm{&system.thread_safe_allocator(),
|
coral::allocator * const allocator{&system.thread_safe_allocator()};
|
||||||
[&system](coral::slice<char const> const & error_message) {
|
|
||||||
|
kym::vm vm{allocator, [&system](coral::slice<char const> const & error_message) {
|
||||||
system.log(app::log_level::error, error_message);
|
system.log(app::log_level::error, error_message);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
if (!vm.init({
|
if (!vm.init({.datastack_size = 64, .callstack_size = 64})) {
|
||||||
.datastack_size = 64,
|
|
||||||
.callstack_size = 64,
|
|
||||||
})) {
|
|
||||||
system.log(app::log_level::error, "failed to allocate memory for config vm");
|
system.log(app::log_level::error, "failed to allocate memory for config vm");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
coral::stack<coral::u8> script_source{&system.thread_safe_allocator()};
|
coral::stack<coral::u8> script_source{allocator};
|
||||||
coral::u8 stream_buffer[1024]{0};
|
coral::u8 stream_buffer[1024]{0};
|
||||||
|
|
||||||
if (!coral::stream(coral::sequence_writer{&script_source}, file, stream_buffer).is_ok())
|
if (!coral::stream(coral::sequence_writer{&script_source}, file, stream_buffer).is_ok())
|
||||||
|
@ -54,7 +52,7 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
vm.with_object(config.get_field("title"), [&](kym::bound_object & title) {
|
vm.with_object(config.get_field("title"), [&](kym::bound_object & title) {
|
||||||
coral::stack<coral::u8, 128> title_buffer{&system.thread_safe_allocator()};
|
coral::stack<coral::u8, 128> title_buffer{&system.thread_safe_allocator()};
|
||||||
|
|
||||||
if (!title.stringify(coral::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 +63,23 @@ extern "C" int main(int argc, char const * const * argv) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}) != coral::fs::access_result::ok) || (!is_config_loaded)) return coral::u8_max;
|
});
|
||||||
|
|
||||||
|
if (!is_config_loaded) {
|
||||||
|
coral::stack<coral::u8> error_message{&system.thread_safe_allocator()};
|
||||||
|
|
||||||
|
{
|
||||||
|
coral::sequence_writer error_writer{&error_message};
|
||||||
|
|
||||||
|
if (!error_writer(coral::slice{"failed to load "}.as_bytes()).is_ok())
|
||||||
|
return coral::u8_max;
|
||||||
|
|
||||||
|
if (!error_writer(config_path.as_slice().as_bytes()).is_ok())
|
||||||
|
return coral::u8_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coral::u8_max;
|
||||||
|
}
|
||||||
|
|
||||||
// app::canvas canvas_2d();
|
// app::canvas canvas_2d();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue