Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
operation-stream.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2
5
6#include <chrono>
7#include <exception>
8#include <functional>
9#include <memory>
10#include <sigc++/connection.h>
11#include <sigc++/signal.h>
12#include <tuple>
13#include <utility>
14#include <variant>
16#include "async/progress.h"
17#include <sigc++/scoped_connection.h>
18
19namespace Inkscape {
20namespace Async {
21
22namespace Msg {
23
25template<typename R>
27template<typename... T>
28struct OperationProgress { std::tuple<T...> progress; };
30struct OperationException { std::exception_ptr exception; };
32
33template<typename R, typename... T>
34using Message = std::variant<
41>;
42
43// helpers to retrieve individual messages; to be retired after pattern matching becomes available
44template<typename R, typename... T>
46 if (auto&& r = std::get_if<OperationResult<R>>(&msg)) {
47 return &r->result;
48 }
49 return nullptr;
50}
51
52template<typename R, typename... T>
53const std::tuple<T...>* get_progress(const Msg::Message<R, T...>& msg) {
54 if (auto&& p = std::get_if<OperationProgress<T...>>(&msg)) {
55 return &p->progress;
56 }
57 return nullptr;
58}
59
60template<typename R, typename... T>
62 return !!std::get_if<OperationFinished>(&msg);
63}
64
65} // Msg
66
67
68template<typename R, typename... T>
70 using duration = std::chrono::steady_clock::duration;
71public:
74
77
78 void start(std::function<R (Progress<T...>&)> work, duration throttle_interval = duration::zero()) {
80 .work = std::move(work),
81 .on_started = [this]() { emit(Msg::OperationStarted {}); },
82 .on_progress = [this](T... p) { emit(Msg::OperationProgress<T...> {std::tuple<T...>(p...)}); },
83 .throttle_time = throttle_interval,
84 .on_complete = [this](R result) { emit(Msg::OperationResult<R> {result = std::move(result)}); },
85 .on_cancelled = [this]() { emit(Msg::OperationCancelled {}); },
86 .on_exception = [this](std::exception_ptr ex) { emit(Msg::OperationException {ex}); },
87 .on_finished = [this]() { emit(Msg::OperationFinished {}); },
88 }));
89 }
90
91 bool is_running() const { return _task && _task->is_running(); }
92
93 sigc::connection subscribe(std::function<void (const Msg::Message<R, T...>&)> fn) {
94 return _signal.connect(fn);
95 }
96
97 void cancel() {
98 if (_task) {
99 _task->cancel();
100 _task.reset();
101 }
102 }
103
104private:
106 _signal.emit(msg);
107 }
108
109 std::unique_ptr<BackgroundTask<R, T...>> _task;
110 sigc::signal<void (const Msg::Message<R, T...>&)> _signal;
111};
112
113
114} // namespace Async
115} // namespace Inkscape
void emit(Msg::Message< R, T... > msg)
sigc::connection subscribe(std::function< void(const Msg::Message< R, T... > &)> fn)
std::unique_ptr< BackgroundTask< R, T... > > _task
void start(std::function< R(Progress< T... > &)> work, duration throttle_interval=duration::zero())
sigc::signal< void(const Msg::Message< R, T... > &)> _signal
std::chrono::steady_clock::duration duration
An interface for tasks to report progress and check for cancellation.
Definition progress.h:23
Css & result
Glib::ustring msg
const R * get_result(const Msg::Message< R, T... > &msg)
bool is_finished(const Msg::Message< R, T... > &msg)
std::variant< OperationStarted, OperationProgress< T... >, OperationResult< R >, OperationCancelled, OperationException, OperationFinished > Message
const std::tuple< T... > * get_progress(const Msg::Message< R, T... > &msg)
Helper class to stream background task notifications as a series of messages.