LeechCraft 0.6.70-18808-g3467692359
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
context.h
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <coroutine>
12#include <stdexcept>
13#include <vector>
14#include <QMetaObject>
15#include <QObject>
16#include <QVector>
18#include "../threadsconfig.h"
19
20namespace LC::Util
21{
22 namespace detail
23 {
25 {
26 std::string ClassName_;
27 QString ObjectName_;
28 };
29 }
30
31 class UTIL_THREADS_API ContextDeadException : public std::runtime_error
32 {
33 public:
34 explicit ContextDeadException (const detail::DeadObjectInfo& info);
35 };
36
37 namespace detail
38 {
39 template<typename T>
40 concept IsAwaiter = requires (T t)
41 {
42 t.await_ready ();
43 t.await_resume ();
44 };
45
46 template<typename T>
47 decltype (auto) Awaiter (T&& obj)
48 {
49 if constexpr (requires { operator co_await (std::forward<T> (obj)); })
50 return operator co_await (std::forward<T> (obj));
51 else if constexpr (requires { std::forward<T> (obj).operator co_await (); })
52 return std::forward<T> (obj).operator co_await ();
53 else
54 {
55 static_assert (IsAwaiter<std::remove_reference_t<T>>, "operand doesn't look like an Awaitable");
56 return std::forward<T> (obj);
57 }
58 }
59
60 UTIL_THREADS_API void CheckDeadObjects (const QVector<DeadObjectInfo>&);
61
62 template<typename Promise, typename OrigAwaiter>
64 {
65 Promise& Promise_;
66 OrigAwaiter Orig_;
67
69 {
70 return Orig_.await_ready ();
71 }
72
73 decltype (auto) await_suspend (auto handle)
74 {
75 return Orig_.await_suspend (handle);
76 }
77
78 decltype (auto) await_resume ()
79 {
80 CheckDeadObjects (Promise_.DeadObjects_);
81 return Orig_.await_resume ();
82 }
83 };
84 }
85
86 struct [[nodiscard]] AddContextObject
87 {
88 const QObject& Context_;
89
90 explicit AddContextObject (const QObject& context)
91 : Context_ { context }
92 {
93 }
94
95 bool await_ready () const noexcept
96 {
97 return false;
98 }
99
100 template<typename Promise>
101 requires requires { typename Promise::HasContextExtension; }
102 bool await_suspend (std::coroutine_handle<Promise> handle)
103 {
104 auto conn = QObject::connect (&Context_,
105 &QObject::destroyed,
106 [handle] (QObject *object)
107 {
108 auto className = object->metaObject ()->className ();
109 handle.promise ().DeadObjects_.push_back ({ className, object->objectName () });
110 handle.resume ();
111 });
112 handle.promise ().ContextConnections_.emplace_back (conn);
113 return false;
114 }
115
117 {
118 }
119 };
120
121 template<typename>
123 {
125
126 std::vector<RaiiSignalConnection> ContextConnections_;
127 QVector<detail::DeadObjectInfo> DeadObjects_;
128
130 {
131 return awaitable;
132 }
133
134 template<typename T>
135 auto await_transform (T&& awaitable)
136 {
137 using OrigAwaiter = decltype (detail::Awaiter (std::forward<T> (awaitable)));
138 return detail::AwaitableWrapper<ContextExtension, OrigAwaiter> { *this, detail::Awaiter (std::forward<T> (awaitable)) };
139 }
140 };
141}
ContextDeadException(const detail::DeadObjectInfo &info)
Definition context.cpp:25
decltype(auto) Awaiter(T &&obj)
Definition context.h:47
void CheckDeadObjects(const QVector< DeadObjectInfo > &deadObjects)
Definition context.cpp:32
const QObject & Context_
Definition context.h:88
AddContextObject(const QObject &context)
Definition context.h:90
bool await_ready() const noexcept
Definition context.h:95
bool await_suspend(std::coroutine_handle< Promise > handle)
Definition context.h:102
QVector< detail::DeadObjectInfo > DeadObjects_
Definition context.h:127
auto await_transform(T &&awaitable)
Definition context.h:135
std::vector< RaiiSignalConnection > ContextConnections_
Definition context.h:126
AddContextObject await_transform(AddContextObject awaitable) const
Definition context.h:129
decltype(auto) await_suspend(auto handle)
Definition context.h:73
decltype(auto) await_resume()
Definition context.h:78
#define UTIL_THREADS_API