libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
future.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <future>
14#include <chrono>
15#include <promeki/namespace.h>
16#include <promeki/result.h>
17
18PROMEKI_NAMESPACE_BEGIN
19
30struct PromiseError {
31 Error error;
32 explicit PromiseError(Error e) : error(e) {}
33};
34
64template <typename T> class Future {
65 public:
67 Future() = default;
68
70 Future(std::future<T> &&f) : _future(std::move(f)) {}
71
73 ~Future() = default;
74
75 Future(const Future &) = delete;
76 Future &operator=(const Future &) = delete;
77
79 Future(Future &&other) = default;
80
82 Future &operator=(Future &&other) = default;
83
88 bool isReady() const {
89 return _future.valid() &&
90 _future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
91 }
92
103 Result<T> result(unsigned int timeoutMs = 0) {
104 if (!_future.valid()) return Result<T>(T{}, Error::Invalid);
105 if (timeoutMs != 0) {
106 if (_future.wait_for(std::chrono::milliseconds(timeoutMs)) !=
107 std::future_status::ready) {
108 return Result<T>(T{}, Error::Timeout);
109 }
110 }
111 try {
112 return Result<T>(_future.get(), Error::Ok);
113 } catch (const PromiseError &pe) {
114 return Result<T>(T{}, pe.error);
115 } catch (const std::future_error &) {
116 return Result<T>(T{}, Error::Invalid);
117 } catch (...) {
118 return Result<T>(T{}, Error::LibraryFailure);
119 }
120 }
121
125 void waitForFinished() {
126 if (_future.valid()) _future.wait();
127 }
128
134 Error waitForFinished(unsigned int timeoutMs) {
135 if (!_future.valid()) return Error::Invalid;
136 if (_future.wait_for(std::chrono::milliseconds(timeoutMs)) == std::future_status::ready) {
137 return Error::Ok;
138 }
139 return Error::Timeout;
140 }
141
146 bool isValid() const { return _future.valid(); }
147
148 private:
149 mutable std::future<T> _future;
150};
151
157template <> class Future<void> {
158 public:
160 Future() = default;
161
163 Future(std::future<void> &&f) : _future(std::move(f)) {}
164
166 ~Future() = default;
167
168 Future(const Future &) = delete;
169 Future &operator=(const Future &) = delete;
170 Future(Future &&other) = default;
171 Future &operator=(Future &&other) = default;
172
177 bool isReady() const {
178 return _future.valid() &&
179 _future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
180 }
181
189 Error result(unsigned int timeoutMs = 0) {
190 if (!_future.valid()) return Error::Invalid;
191 if (timeoutMs != 0) {
192 if (_future.wait_for(std::chrono::milliseconds(timeoutMs)) !=
193 std::future_status::ready) {
194 return Error::Timeout;
195 }
196 }
197 try {
198 _future.get();
199 return Error::Ok;
200 } catch (const PromiseError &pe) {
201 return pe.error;
202 } catch (const std::future_error &) {
203 return Error::Invalid;
204 } catch (...) {
205 return Error::LibraryFailure;
206 }
207 }
208
212 void waitForFinished() {
213 if (_future.valid()) _future.wait();
214 }
215
221 Error waitForFinished(unsigned int timeoutMs) {
222 if (!_future.valid()) return Error::Invalid;
223 if (_future.wait_for(std::chrono::milliseconds(timeoutMs)) == std::future_status::ready) {
224 return Error::Ok;
225 }
226 return Error::Timeout;
227 }
228
233 bool isValid() const { return _future.valid(); }
234
235 private:
236 mutable std::future<void> _future;
237};
238
239PROMEKI_NAMESPACE_END
240
241#endif // PROMEKI_ENABLE_CORE