feat support Async
This commit is contained in:
parent
5d07e41460
commit
07b790557b
@ -1,5 +1,6 @@
|
||||
|
||||
#include "sled/futures/future.h"
|
||||
#include "sled/system/thread_pool.h"
|
||||
|
||||
namespace sled {
|
||||
namespace future_detail {
|
||||
@ -12,4 +13,24 @@ DecrementFuturesUsage()
|
||||
{}
|
||||
|
||||
}// namespace future_detail
|
||||
|
||||
static ThreadPool g_default_thread_pool;
|
||||
TaskQueueBase *g_default_scheduler = &g_default_thread_pool;
|
||||
|
||||
void
|
||||
SetDefaultScheduler(TaskQueueBase *scheduler) noexcept
|
||||
{
|
||||
if (scheduler == nullptr) {
|
||||
g_default_scheduler = &g_default_thread_pool;
|
||||
} else {
|
||||
g_default_scheduler = scheduler;
|
||||
}
|
||||
}
|
||||
|
||||
TaskQueueBase *
|
||||
GetDefaultScheduler() noexcept
|
||||
{
|
||||
return g_default_scheduler;
|
||||
}
|
||||
|
||||
}// namespace sled
|
||||
|
@ -56,9 +56,10 @@ struct FutureData {
|
||||
};
|
||||
}// namespace future_detail
|
||||
|
||||
//
|
||||
void SetDefaultScheduler(TaskQueueBase *scheduler) noexcept;
|
||||
TaskQueueBase *GetDefaultScheduler() noexcept;
|
||||
|
||||
template<typename T, typename FailureT>
|
||||
template<typename T, typename FailureT = std::exception>
|
||||
class Future {
|
||||
static_assert(!std::is_same<T, void>::value, "Future<void, _> is not allowed. Use Future<bool, _> instead");
|
||||
static_assert(!std::is_same<FailureT, void>::value, "Future<_, void> is not allowed. Use Future<_, bool> instead");
|
||||
@ -329,6 +330,27 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Func, typename = future_detail::enable_if_t<future_detail::is_invocable<Func>::value>>
|
||||
static Future<T, FailureT> Async(Func &&f) noexcept
|
||||
{
|
||||
Future<T, FailureT> result = Future<T, FailureT>::Create();
|
||||
sled::GetDefaultScheduler()->PostTask([result, f]() mutable noexcept {
|
||||
try {
|
||||
result.FillSuccess(f());
|
||||
} catch (const std::exception &e) {
|
||||
result.FillFailure(future_detail::ExceptionFailure<FailureT>(e));
|
||||
} catch (...) {
|
||||
result.FillFailure(future_detail::ExceptionFailure<FailureT>());
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
static Future<T, FailureT> AsyncWithValue(const T &value) noexcept
|
||||
{
|
||||
return Async([value]() { return value; });
|
||||
}
|
||||
|
||||
static Future<typename std::decay<T>::type, FailureT> Successful(T &&value) noexcept
|
||||
{
|
||||
Future<typename std::decay<T>::type, FailureT> result
|
||||
@ -437,6 +459,7 @@ private:
|
||||
|
||||
std::shared_ptr<future_detail::FutureData<T, FailureT>> data_;
|
||||
};
|
||||
|
||||
}// namespace sled
|
||||
|
||||
#endif// SLED_FUTURES_FUTURE_H
|
||||
|
@ -102,4 +102,18 @@ TEST_SUITE("future")
|
||||
CHECK_EQ(tid, f.Result());
|
||||
CHECK_NE(self_tid, f.Result());
|
||||
}
|
||||
|
||||
TEST_CASE("Async")
|
||||
{
|
||||
auto f = sled::Future<int>::Async([]() { return 42; });
|
||||
CHECK_EQ(f.Result(), 42);
|
||||
|
||||
auto f2 = sled::Future<int>::Async([]() {
|
||||
throw std::runtime_error("test");
|
||||
return 1;
|
||||
});
|
||||
CHECK_FALSE(f2.IsFailed());
|
||||
auto f3 = sled::Future<std::string>::AsyncWithValue("11");
|
||||
CHECK_EQ(f3.Result(), "11");
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace sled {
|
||||
template<typename T, typename FailureT>
|
||||
class Future;
|
||||
|
||||
template<typename T, typename FailureT>
|
||||
template<typename T, typename FailureT = std::exception>
|
||||
class Promise {
|
||||
static_assert(!std::is_same<T, void>::value, "Promise<void, _> is not allowed. Use Promise<bool, _> instead");
|
||||
static_assert(!std::is_same<FailureT, void>::value,
|
||||
|
Loading…
Reference in New Issue
Block a user