blob: b4123b5dcb3b08e3aeb0ac688e125e50b94af6e1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
|