// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #pragma once #include #ifdef CRL_USE_DISPATCH #include #include namespace crl::details { void *background_queue_dispatch(); void *main_queue_dispatch(); void on_queue_async(void *queue, void (*callable)(void*), void *argument); void on_queue_sync(void *queue, void (*callable)(void*), void *argument); template < typename Wrapper, typename Invoker, typename Callable, typename Return = decltype(std::declval()())> inline void on_queue_invoke( void *queue, Invoker invoker, Callable &&callable) { using Function = std::decay_t; if constexpr (details::is_plain_function_v) { using Plain = Return(*)(); static_assert(sizeof(Plain) <= sizeof(void*)); const auto copy = static_cast(callable); invoker(queue, [](void *passed) { Wrapper::Invoke([](void *passed) { const auto callable = reinterpret_cast(passed); (*callable)(); }, passed); }, reinterpret_cast(copy)); } else { const auto copy = new Function(std::forward(callable)); invoker(queue, [](void *passed) { Wrapper::Invoke([](void *passed) { const auto callable = static_cast(passed); const auto guard = details::finally([=] { delete callable; }); (*callable)(); }, passed); }, static_cast(copy)); } } struct EmptyWrapper { template static inline void Invoke(Callable &&callable, void *argument) { callable(argument); } }; inline void async_plain(void (*callable)(void*), void *argument) { return on_queue_async( background_queue_dispatch(), callable, argument); } } // namespace crl::details namespace crl { template inline void async(Callable &&callable) { return details::on_queue_invoke( details::background_queue_dispatch(), details::on_queue_async, std::forward(callable)); } template inline void sync(Callable &&callable) { return details::on_queue_invoke( details::background_queue_dispatch(), details::on_queue_sync, std::forward(callable)); } } // namespace crl #endif // CRL_USE_DISPATCH