From 237c0b4d197e4eb7ac09246e2ff1ef1578ba5761 Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 23 Feb 2023 14:59:29 +0000 Subject: [PATCH] Replace coral::callable with coral::closure --- source/app.cpp | 6 +++--- source/coral.cpp | 37 ++++++++++++++++++------------------- source/coral/files.cpp | 4 ++-- source/oar.cpp | 4 ++-- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/source/app.cpp b/source/app.cpp index a97f08a..de3f7d2 100644 --- a/source/app.cpp +++ b/source/app.cpp @@ -154,7 +154,7 @@ struct sandboxed_fs : public coral::fs { return this->access_rules; } - void read_file(coral::path const & file_path, coral::callable const & then) override { + void read_file(coral::path const & file_path, coral::closure const & then) override { if (!this->access_rules.can_read) return; native_path sandbox_file_path; @@ -183,7 +183,7 @@ struct sandboxed_fs : public coral::fs { return; } - void write_file(coral::path const & file_path, coral::callable const & then) override { + void write_file(coral::path const & file_path, coral::closure const & then) override { if (!this->access_rules.can_write) return; native_path sandbox_file_path; @@ -260,7 +260,7 @@ export namespace app { return this->resources_archive; } - static int run(coral::path const & title, coral::callable const & start) { + static int run(coral::path const & title, coral::closure const & start) { constexpr int windowpos {SDL_WINDOWPOS_UNDEFINED}; constexpr coral::u32 windowflags {SDL_WINDOW_HIDDEN}; constexpr int window_width {640}; diff --git a/source/coral.cpp b/source/coral.cpp index 1fcf1ea..7839d95 100644 --- a/source/coral.cpp +++ b/source/coral.cpp @@ -420,45 +420,44 @@ export namespace coral { u8 buffer[buffer_size + 1]; }; - template struct callable; + template struct closure; /** - * Type-erasing wrapper for functor types that have a call operator with a return value - * matching `return_value` and arguments matching `argument_values`. + * Type-erasing view wrapper for both function and functor types that have a call operator with + * 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 struct callable { + template struct closure { using function = returns(*)(arguments...); - callable(function callable_function) { - this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns { - return (*reinterpret_cast(context))(dispatch_arguments...); + closure(function callable_function) { + this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns { + return (reinterpret_cast(context))(dispatch_arguments...); }; - new (this->capture) function{callable_function}; + this->context = callable_function; } - callable(callable const &) = delete; + closure(closure const &) = delete; - template callable(functor const & callable_functor) { - static_assert(sizeof(functor) < capture_size); - - this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns { + template closure(functor && callable_functor) { + this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns { return (*reinterpret_cast(context))(dispatch_arguments...); }; - new (this->capture) functor{callable_functor}; + this->context = &callable_functor; } returns operator()(arguments const &... call_arguments) const { - return this->dispatcher(this->capture, call_arguments...); + return this->dispatch(this->context, call_arguments...); } private: - static constexpr usize capture_size = 24; + void const * context; - returns(* dispatcher)(u8 const *, arguments...); - - u8 capture[capture_size]; + returns(* dispatch)(void const *, arguments...); }; /** diff --git a/source/coral/files.cpp b/source/coral/files.cpp index ae07d07..100a35c 100644 --- a/source/coral/files.cpp +++ b/source/coral/files.cpp @@ -144,7 +144,7 @@ export namespace coral { * * Once `then` returns, access to the file is closed automatically. */ - virtual void read_file(path const & file_path, callable const & then) = 0; + virtual void read_file(path const & file_path, closure const & then) = 0; /** * 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. */ - virtual void write_file(path const & file_path, callable const & then) = 0; + virtual void write_file(path const & file_path, closure const & then) = 0; }; } diff --git a/source/oar.cpp b/source/oar.cpp index 9dc338d..4f8c5f8 100644 --- a/source/oar.cpp +++ b/source/oar.cpp @@ -179,7 +179,7 @@ export namespace oar { } void read_file(coral::path const & file_path, - coral::callable const & then) override { + coral::closure const & then) override { 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, - coral::callable const & then) override { + coral::closure const & then) override { // Read-only file system. }