cesium-native 0.43.0
Loading...
Searching...
No Matches
SharedFuture.h
1#pragma once
2
3#include "Impl/AsyncSystemSchedulers.h"
4#include "Impl/CatchFunction.h"
5#include "Impl/ContinuationFutureType.h"
6#include "Impl/WithTracing.h"
7#include "ThreadPool.h"
8
9#include <CesiumUtility/Tracing.h>
10
11#include <type_traits>
12#include <variant>
13
14namespace CesiumAsync {
15
16namespace CesiumImpl {
17
18template <typename R> struct ParameterizedTaskUnwrapper;
19struct TaskUnwrapper;
20
21} // namespace CesiumImpl
22
31template <typename T> class SharedFuture final {
32public:
51 template <typename Func>
52 CesiumImpl::ContinuationFutureType_t<Func, T> thenInWorkerThread(Func&& f) {
53 return this->thenWithScheduler(
54 this->_pSchedulers->workerThread.immediate,
55 "waiting for worker thread",
56 std::forward<Func>(f));
57 }
58
77 template <typename Func>
78 CesiumImpl::ContinuationFutureType_t<Func, T> thenInMainThread(Func&& f) {
79 return this->thenWithScheduler(
80 this->_pSchedulers->mainThread.immediate,
81 "waiting for main thread",
82 std::forward<Func>(f));
83 }
84
100 template <typename Func>
101 CesiumImpl::ContinuationFutureType_t<Func, T> thenImmediately(Func&& f) {
102 return CesiumImpl::ContinuationFutureType_t<Func, T>(
103 this->_pSchedulers,
104 _task.then(
105 async::inline_scheduler(),
106 CesiumImpl::WithTracingShared<T>::end(
107 nullptr,
108 std::forward<Func>(f))));
109 }
110
130 template <typename Func>
131 CesiumImpl::ContinuationFutureType_t<Func, T>
132 thenInThreadPool(const ThreadPool& threadPool, Func&& f) {
133 return this->thenWithScheduler(
134 threadPool._pScheduler->immediate,
135 "waiting for thread pool thread",
136 std::forward<Func>(f));
137 }
138
160 template <typename Func> Future<T> catchInMainThread(Func&& f) {
161 return this->catchWithScheduler(
162 this->_pSchedulers->mainThread.immediate,
163 std::forward<Func>(f));
164 }
165
185 template <typename Func> Future<T> catchImmediately(Func&& f) {
186 return this->catchWithScheduler(
187 async::inline_scheduler(),
188 std::forward<Func>(f));
189 }
190
203 template <typename... TPassThrough>
204 Future<std::tuple<TPassThrough..., T>>
205 thenPassThrough(TPassThrough&&... values) {
206 return this->thenImmediately(
207 [values = std::tuple(std::forward<TPassThrough>(values)...)](
208 const T& result) mutable {
209 return std::tuple_cat(std::move(values), std::make_tuple(result));
210 });
211 }
212
226 template <
227 typename U = T,
228 std::enable_if_t<std::is_same_v<U, T>, int> = 0,
229 std::enable_if_t<!std::is_same_v<U, void>, int> = 0>
230 const U& wait() const {
231 return this->_task.get();
232 }
233
246 template <
247 typename U = T,
248 std::enable_if_t<std::is_same_v<U, T>, int> = 0,
249 std::enable_if_t<std::is_same_v<U, void>, int> = 0>
250 void wait() const {
251 this->_task.get();
252 }
253
269 return this->_pSchedulers->mainThread.dispatchUntilTaskCompletes(
270 std::move(this->_task));
271 }
272
283 bool isReady() const { return this->_task.ready(); }
284
285private:
287 const std::shared_ptr<CesiumImpl::AsyncSystemSchedulers>& pSchedulers,
288 async::shared_task<T>&& task) noexcept
289 : _pSchedulers(pSchedulers), _task(std::move(task)) {}
290
291 template <typename Func, typename Scheduler>
292 CesiumImpl::ContinuationFutureType_t<Func, T>
293 thenWithScheduler(Scheduler& scheduler, const char* tracingName, Func&& f) {
294 // It would be nice if tracingName were a template parameter instead of a
295 // function parameter, but that triggers a bug in VS2017. It was previously
296 // a bug in VS2019, too, but has been fixed there:
297 // https://developercommunity.visualstudio.com/t/internal-compiler-error-when-compiling-a-template-1/534210
298#if CESIUM_TRACING_ENABLED
299 // When tracing is enabled, we measure the time between scheduling and
300 // dispatching of the work.
301 auto task = this->_task.then(
302 async::inline_scheduler(),
303 CesiumImpl::WithTracingShared<T>::begin(
304 tracingName,
305 std::forward<Func>(f)));
306#else
307 auto& task = this->_task;
308#endif
309
310 return CesiumImpl::ContinuationFutureType_t<Func, T>(
311 this->_pSchedulers,
312 task.then(
313 scheduler,
314 CesiumImpl::WithTracingShared<T>::end(
315 tracingName,
316 std::forward<Func>(f))));
317 }
318
319 template <typename Func, typename Scheduler>
320 CesiumImpl::ContinuationFutureType_t<Func, std::exception>
321 catchWithScheduler(Scheduler& scheduler, Func&& f) {
322 return CesiumImpl::ContinuationFutureType_t<Func, std::exception>(
323 this->_pSchedulers,
324 this->_task.then(
325 async::inline_scheduler(),
326 CesiumImpl::
327 CatchFunction<Func, T, Scheduler, const async::shared_task<T>&>{
328 scheduler,
329 std::forward<Func>(f)}));
330 }
331
332 std::shared_ptr<CesiumImpl::AsyncSystemSchedulers> _pSchedulers;
333 async::shared_task<T> _task;
334
335 friend class AsyncSystem;
336
337 template <typename R> friend struct CesiumImpl::ParameterizedTaskUnwrapper;
338
339 friend struct CesiumImpl::TaskUnwrapper;
340
341 template <typename R> friend class Future;
342 template <typename R> friend class SharedFuture;
343};
344
345} // namespace CesiumAsync
A value that will be available in the future, as produced by AsyncSystem.
Definition Promise.h:11
A value that will be available in the future, as produced by AsyncSystem. Unlike Future,...
CesiumImpl::ContinuationFutureType_t< Func, T > thenImmediately(Func &&f)
Registers a continuation function to be invoked immediately in whichever thread causes the Future to ...
bool isReady() const
Determines if this future is already resolved or rejected.
T waitInMainThread()
Waits for this future to resolve or reject in the main thread while also processing main-thread tasks...
CesiumImpl::ContinuationFutureType_t< Func, T > thenInThreadPool(const ThreadPool &threadPool, Func &&f)
Registers a continuation function to be invoked in a thread pool when this Future resolves.
const U & wait() const
Waits for the future to resolve or reject and returns the result.
Future< T > catchInMainThread(Func &&f)
Registers a continuation function to be invoked in the main thread when this Future rejects.
Future< std::tuple< TPassThrough..., T > > thenPassThrough(TPassThrough &&... values)
Passes through one or more additional values to the next continuation.
CesiumImpl::ContinuationFutureType_t< Func, T > thenInWorkerThread(Func &&f)
Registers a continuation function to be invoked in a worker thread when this Future resolves.
CesiumImpl::ContinuationFutureType_t< Func, T > thenInMainThread(Func &&f)
Registers a continuation function to be invoked in the main thread when this Future resolves.
Future< T > catchImmediately(Func &&f)
Registers a continuation function to be invoked immediately, and invalidates this Future.
void wait() const
Waits for the future to resolve or reject.
A thread pool created by AsyncSystem::createThreadPool.
Definition ThreadPool.h:18
Classes that support asynchronous operations.