Merge pull request 'Replace `coral::callable` with `coral::closure`' (#9) from replace-callable into main
continuous-integration/drone/push Build is passing Details

Reviewed-on: #9
This commit is contained in:
kayomn 2023-02-23 16:12:29 +01:00
commit 388a98e654
4 changed files with 34 additions and 27 deletions

View File

@ -154,7 +154,7 @@ struct sandboxed_fs : public coral::fs {
return this->access_rules; return this->access_rules;
} }
void read_file(coral::path const & file_path, coral::callable<void(coral::file_reader &)> const & then) override { void read_file(coral::path const & file_path, coral::closure<void(coral::file_reader &)> const & then) override {
if (!this->access_rules.can_read) return; if (!this->access_rules.can_read) return;
native_path sandbox_file_path; native_path sandbox_file_path;
@ -183,7 +183,7 @@ struct sandboxed_fs : public coral::fs {
return; return;
} }
void write_file(coral::path const & file_path, coral::callable<void(coral::file_writer &)> const & then) override { void write_file(coral::path const & file_path, coral::closure<void(coral::file_writer &)> const & then) override {
if (!this->access_rules.can_write) return; if (!this->access_rules.can_write) return;
native_path sandbox_file_path; native_path sandbox_file_path;
@ -260,7 +260,7 @@ export namespace app {
return this->resources_archive; return this->resources_archive;
} }
static int run(coral::path const & title, coral::callable<int(client &)> const & start) { static int run(coral::path const & title, coral::closure<int(client &)> const & start) {
constexpr int windowpos {SDL_WINDOWPOS_UNDEFINED}; constexpr int windowpos {SDL_WINDOWPOS_UNDEFINED};
constexpr coral::u32 windowflags {SDL_WINDOW_HIDDEN}; constexpr coral::u32 windowflags {SDL_WINDOW_HIDDEN};
constexpr int window_width {640}; constexpr int window_width {640};

View File

@ -420,45 +420,52 @@ export namespace coral {
u8 buffer[buffer_size + 1]; u8 buffer[buffer_size + 1];
}; };
template<typename> struct callable; template<typename> struct closure;
/** /**
* Type-erasing wrapper for functor types that have a call operator with a return value * Type-erasing view wrapper for both function and functor types that have a call operator with
* matching `return_value` and arguments matching `argument_values`. * a return value matching `return_value` and arguments matching `argument_values`.
*
* **Note**: closures take no ownership of allocated memory, making it the responsibility of
* the caller to manage the lifetime of any functor assigned to it.
*/ */
template<typename returns, typename... arguments> struct callable<returns(arguments...)> { template<typename returns, typename... arguments> struct closure<returns(arguments...)> {
using function = returns(*)(arguments...); using function = returns(*)(arguments...);
callable(function callable_function) { closure(function callable_function) {
this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns { this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<function const *>(context))(dispatch_arguments...); return (reinterpret_cast<function const *>(context))(dispatch_arguments...);
}; };
new (this->capture) function{callable_function}; this->context = callable_function;
} }
callable(callable const &) = delete; template<typename functor> closure(functor * callable_functor) {
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
template<typename functor> callable(functor const & callable_functor) {
static_assert(sizeof(functor) < capture_size);
this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...); return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...);
}; };
new (this->capture) functor{callable_functor}; this->context = callable_functor;
}
closure(closure const &) = delete;
template<typename functor> closure(functor && callable_functor) {
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...);
};
this->context = &callable_functor;
} }
returns operator()(arguments const &... call_arguments) const { returns operator()(arguments const &... call_arguments) const {
return this->dispatcher(this->capture, call_arguments...); return this->dispatch(this->context, call_arguments...);
} }
private: private:
static constexpr usize capture_size = 24; void const * context;
returns(* dispatcher)(u8 const *, arguments...); returns(* dispatch)(void const *, arguments...);
u8 capture[capture_size];
}; };
/** /**

View File

@ -144,7 +144,7 @@ export namespace coral {
* *
* Once `then` returns, access to the file is closed automatically. * Once `then` returns, access to the file is closed automatically.
*/ */
virtual void read_file(path const & file_path, callable<void(file_reader &)> const & then) = 0; virtual void read_file(path const & file_path, closure<void(file_reader &)> 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
@ -152,6 +152,6 @@ export namespace coral {
* *
* Once `then` returns, access to the file is closed automatically. * Once `then` returns, access to the file is closed automatically.
*/ */
virtual void write_file(path const & file_path, callable<void(file_writer &)> const & then) = 0; virtual void write_file(path const & file_path, closure<void(file_writer &)> const & then) = 0;
}; };
} }

View File

@ -179,7 +179,7 @@ export namespace oar {
} }
void read_file(coral::path const & file_path, void read_file(coral::path const & file_path,
coral::callable<void(coral::file_reader &)> const & then) override { coral::closure<void(coral::file_reader &)> const & then) override {
if ((this->backing_fs == nullptr) || (this->archive_path.byte_size() == 0)) return; if ((this->backing_fs == nullptr) || (this->archive_path.byte_size() == 0)) return;
@ -195,7 +195,7 @@ export namespace oar {
} }
void write_file(coral::path const & file_path, void write_file(coral::path const & file_path,
coral::callable<void(coral::file_writer &)> const & then) override { coral::closure<void(coral::file_writer &)> const & then) override {
// Read-only file system. // Read-only file system.
} }