1#pragma once
2
3#include <mbgl/util/work_task.hpp>
4#include <mbgl/util/run_loop.hpp>
5
6#include <mutex>
7
8namespace mbgl {
9
10template <class F, class P>
11class WorkTaskImpl : public WorkTask {
12public:
13 WorkTaskImpl(F f, P p, std::shared_ptr<std::atomic<bool>> canceled_)
14 : canceled(std::move(canceled_)),
15 func(std::move(f)),
16 params(std::move(p)) {
17 }
18
19 void operator()() override {
20 // Lock the mutex while processing so that cancel() will block.
21 std::lock_guard<std::recursive_mutex> lock(mutex);
22 if (!*canceled) {
23 invoke(std::make_index_sequence<std::tuple_size<P>::value>{});
24 }
25 }
26
27 // If the task has not yet begun, this will cancel it.
28 // If the task is in progress, this will block until it completed. (Currently
29 // necessary because of shared state, but should be removed.) It will also
30 // cancel the after callback.
31 // If the task has completed, but the after callback has not executed, this
32 // will cancel the after callback.
33 // If the task has completed and the after callback has executed, this will
34 // do nothing.
35 void cancel() override {
36 std::lock_guard<std::recursive_mutex> lock(mutex);
37 *canceled = true;
38 }
39
40private:
41 template <std::size_t... I>
42 void invoke(std::index_sequence<I...>) {
43 func(std::move(std::get<I>(std::forward<P>(params)))...);
44 }
45
46 std::recursive_mutex mutex;
47 std::shared_ptr<std::atomic<bool>> canceled;
48
49 F func;
50 P params;
51};
52
53template <class Fn, class... Args>
54std::shared_ptr<WorkTask> WorkTask::make(Fn&& fn, Args&&... args) {
55 auto flag = std::make_shared<std::atomic<bool>>();
56 *flag = false;
57
58 auto tuple = std::make_tuple(std::forward<Args>(args)...);
59 return std::make_shared<WorkTaskImpl<std::decay_t<Fn>, decltype(tuple)>>(
60 std::forward<Fn>(fn),
61 std::move(tuple),
62 flag);
63}
64
65} // namespace mbgl
66

source code of qtlocation/src/3rdparty/mapbox-gl-native/include/mbgl/util/work_task_impl.hpp