ReactivePlusPlus
ReactiveX implementation for C++20
Loading...
Searching...
No Matches
main_thread.hpp
1// ReactivePlusPlus library
2//
3// Copyright Aleksey Loginov 2022 - present.
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// https://www.boost.org/LICENSE_1_0.txt)
7//
8// Project home: https://github.com/victimsnino/ReactivePlusPlus
9//
10
11#pragma once
12
13#include <rpp/schedulers/details/worker.hpp> // worker
14
15#include <rppqt/schedulers/fwd.hpp> // own forwarding
16#include <rppqt/utils/exceptions.hpp>
17
18#include "rpp/schedulers/fwd.hpp"
19
20#include <QCoreApplication>
21#include <QTimer>
22#include <chrono>
23#include <concepts>
24
25namespace rppqt::schedulers
26{
32 {
33 private:
34 class worker_strategy
35 {
36 public:
37 template<rpp::schedulers::constraint::schedulable_handler Handler, typename... Args, rpp::schedulers::constraint::schedulable_fn<Handler, Args...> Fn>
38 static void defer_for(rpp::schedulers::duration duration, Fn&& fn, Handler&& handler, Args&&... args)
39 {
40 const auto application = QCoreApplication::instance();
41 if (!application)
42 {
43 handler.on_error(std::make_exception_ptr(utils::no_active_qapplication{"Pointer to application is null. Create QApplication before using main_thread_scheduler!"}));
44 return;
45 }
46
47 QTimer::singleShot(std::chrono::duration_cast<std::chrono::milliseconds>(std::max(rpp::schedulers::duration{}, duration)), application, [fn = std::forward<Fn>(fn), handler = std::forward<Handler>(handler), ... args = std::forward<Args>(args)]() mutable {
48 if (!handler.is_disposed())
49 invoke(std::move(fn), std::move(handler), std::move(args)...);
50 });
51 }
52
53 static rpp::schedulers::time_point now() { return rpp::schedulers::clock_type::now(); }
54
55 private:
57 static void invoke(Fn&& fn, Handler&& handler, Args&&... args)
58 {
59 if (const auto new_duration = fn(handler, args...))
60 defer_for(new_duration->value, std::forward<Fn>(fn), std::forward<Handler>(handler), std::forward<Args>(args)...);
61 }
62
64 static void invoke(Fn&& fn, Handler&& handler, Args&&... args)
65 {
66 const auto now = rpp::schedulers::clock_type::now();
67 if (const auto new_duration = fn(handler, args...))
68 defer_for(now + new_duration->value - rpp::schedulers::clock_type::now(), std::forward<Fn>(fn), std::forward<Handler>(handler), std::forward<Args>(args)...);
69 }
70
72 static void invoke(Fn&& fn, Handler&& handler, Args&&... args)
73 {
74 if (const auto new_tp = fn(handler, args...))
75 defer_for(new_tp->value - rpp::schedulers::clock_type::now(), std::forward<Fn>(fn), std::forward<Handler>(handler), std::forward<Args>(args)...);
76 }
77 };
78
79 public:
80 static auto create_worker()
81 {
83 }
84 };
85} // namespace rppqt::schedulers
Definition fwd.hpp:157
Schedule provided schedulables to main GUI QT thread (where QApplication placed)
Definition main_thread.hpp:32
Definition exceptions.hpp:18