aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/AsyncTask.hpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/include/AsyncTask.hpp b/include/AsyncTask.hpp
new file mode 100644
index 0000000..0d9c453
--- /dev/null
+++ b/include/AsyncTask.hpp
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "Program.hpp"
+#include <thread>
+#include <future>
+
+namespace QuickMedia {
+ template <typename T>
+ class AsyncTask {
+ public:
+ using CallbackFunc = std::function<T()>;
+
+ AsyncTask() = default;
+
+ AsyncTask(CallbackFunc callback_func) {
+ std::promise<T> promise;
+ future = promise.get_future();
+ thread = std::thread(&AsyncTask::thread_handler, this, std::move(promise), std::move(callback_func));
+ }
+
+ AsyncTask& operator=(CallbackFunc callback_func) {
+ cancel();
+ std::promise<T> promise;
+ future = promise.get_future();
+ thread = std::thread(&AsyncTask::thread_handler, this, std::move(promise), std::move(callback_func));
+ return *this;
+ }
+
+ ~AsyncTask() {
+ cancel();
+ }
+
+ bool valid() {
+ return future.valid();
+ }
+
+ bool ready() {
+ return future.valid() && future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
+ }
+
+ T get() {
+ thread.join();
+ return future.get();
+ }
+
+ void cancel() {
+ if(valid()) {
+ program_kill_in_thread(thread.get_id());
+ get();
+ }
+ }
+ private:
+ void thread_handler(std::promise<T> &&promise, CallbackFunc callback_func) {
+ if constexpr(std::is_same<T, void>::value) {
+ callback_func();
+ promise.set_value();
+ } else {
+ promise.set_value(callback_func());
+ }
+ }
+ private:
+ std::thread thread;
+ std::future<T> future;
+ };
+} \ No newline at end of file