LeechCraft 0.6.70-16373-g319c272718
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 <QMetaObject>
14#include <QObject>
15#include <QVector>
16#include "../threadsconfig.h"
17
18namespace LC::Util
19{
20 namespace detail
21 {
23 {
24 std::string ClassName_;
26 };
27 }
28
29 class UTIL_THREADS_API ContextDeadException : public std::runtime_error
30 {
31 public:
32 explicit ContextDeadException (const detail::DeadObjectInfo& info);
33 };
34
35 namespace detail
36 {
37 template<typename T>
38 auto Awaiter (T& obj)
39 {
40 if constexpr (requires { operator co_await (obj); })
41 return operator co_await (obj);
42 else if constexpr (requires { obj.operator co_await (); })
43 return obj.operator co_await ();
44 else
45 return obj;
46 }
47
48 UTIL_THREADS_API void CheckDeadObjects (const QVector<DeadObjectInfo>&);
49
50 template<typename Promise, typename T>
52 {
53 Promise& Promise_;
55
57 {
58 return Awaiter (Orig_).await_ready ();
59 }
60
61 decltype (auto) await_suspend (auto handle)
62 {
63 return Awaiter (Orig_).await_suspend (handle);
64 }
65
66 decltype (auto) await_resume ()
67 {
68 CheckDeadObjects (Promise_.DeadObjects_);
69 return Awaiter (Orig_).await_resume ();
70 }
71 };
72 }
73
74 template<typename>
76 {
78
79 QVector<QMetaObject::Connection> ContextConnections_;
80 QVector<detail::DeadObjectInfo> DeadObjects_;
81
83 {
84 for (auto conn : ContextConnections_)
85 QObject::disconnect (conn);
86 }
87
88 template<typename T>
90 {
91 return detail::AwaitableWrapper<ContextExtensions, T> { *this, std::forward<T> (awaitable) };
92 }
93 };
94
96 {
97 QObject& Context_;
98
99 explicit AddContextObject (QObject& context)
100 : Context_ { context }
101 {
102 }
103
105 {
106 return false;
107 }
108
109 template<typename Promise>
110 requires requires { typename Promise::HasContextExtensions; }
111 bool await_suspend (std::coroutine_handle<Promise> handle)
112 {
113 auto conn = QObject::connect (&Context_,
114 &QObject::destroyed,
115 [handle] (QObject *object)
116 {
117 auto className = object->metaObject ()->className ();
118 handle.promise ().DeadObjects_.push_back ({ className, object->objectName () });
119 });
120 handle.promise ().ContextConnections_.push_back (conn);
121 return false;
122 }
123
125 {
126 }
127 };
128}
void CheckDeadObjects(const QVector< DeadObjectInfo > &deadObjects)
Definition context.cpp:32
auto Awaiter(T &obj)
Definition context.h:38
Container< T > Filter(const Container< T > &c, F f)
Definition prelude.h:118
AddContextObject(QObject &context)
Definition context.h:99
bool await_ready() const noexcept
Definition context.h:104
bool await_suspend(std::coroutine_handle< Promise > handle)
Definition context.h:111
auto await_transform(T &&awaitable)
Definition context.h:89
void FinalSuspend() noexcept
Definition context.h:82
QVector< detail::DeadObjectInfo > DeadObjects_
Definition context.h:80
QVector< QMetaObject::Connection > ContextConnections_
Definition context.h:79
decltype(auto) await_resume()
Definition context.h:66
decltype(auto) await_suspend(auto handle)
Definition context.h:61
#define UTIL_THREADS_API