summaryrefslogtreecommitdiff
path: root/zen/async_task.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/async_task.h')
-rw-r--r--zen/async_task.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/zen/async_task.h b/zen/async_task.h
new file mode 100644
index 00000000..b4123b5d
--- /dev/null
+++ b/zen/async_task.h
@@ -0,0 +1,70 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
+// **************************************************************************
+
+#ifndef ASYNC_JOB_839147839170432143214321
+#define ASYNC_JOB_839147839170432143214321
+
+#include <list>
+#include <functional>
+#include <zen/thread.h>
+#include <zen/scope_guard.h>
+
+namespace zen
+{
+//run a job in an async thread, but process result on GUI event loop
+class AsyncTasks
+{
+public:
+ AsyncTasks() : inRecursion(false) {}
+
+ template <class Fun, class Fun2>
+ void add(Fun doAsync, Fun2 evalOnGui)
+ //equivalent to "evalOnGui(doAsync())"
+ // -> doAsync: the usual thread-safety requirements apply!
+ // -> evalOnGui: no thread-safety concerns, but must only reference variables with greater-equal lifetime than the AsyncTask instance!
+ {
+ tasks.push_back(zen::async([=]() -> std::function<void()>
+ {
+ auto result = doAsync();
+ return [=]{ evalOnGui(result); };
+ }));
+ }
+
+ template <class Fun, class Fun2>
+ void add2(Fun doAsync, Fun2 evalOnGui) //for doAsync returning void
+ {
+ tasks.push_back(zen::async([=]() -> std::function<void()> { doAsync(); return [=]{ evalOnGui(); }; }));
+ }
+
+ void evalResults() //call from gui thread repreatedly
+ {
+ if (!inRecursion) //prevent implicit recursion, e.g. if we're called from an idle event and spawn another one via the callback below
+ {
+ inRecursion = true;
+ ZEN_ON_SCOPE_EXIT(inRecursion = false);
+
+ tasks.remove_if([](boost::unique_future<std::function<void()>>& ft) -> bool
+ {
+ if (ft.is_ready())
+ {
+ (ft.get())();
+ return true;
+ }
+ return false;
+ });
+ }
+ }
+
+ bool empty() const { return tasks.empty(); }
+
+private:
+ bool inRecursion;
+ std::list<boost::unique_future<std::function<void()>>> tasks;
+};
+
+}
+
+#endif //ASYNC_JOB_839147839170432143214321
bgstack15