LeechCraft
0.6.70-18808-g3467692359
Modular cross-platform feature rich live environment.
Toggle main menu visibility
Loading...
Searching...
No Matches
async.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 <QDBusConnection>
12
#include <QDBusPendingReply>
13
#include <
util/sll/qtutil.h
>
14
#include <
util/sll/typegetter.h
>
15
#include <
util/threads/coro/task.h
>
16
#include <
util/threads/coro/either.h
>
17
#include <
util/threads/coro/dbus.h
>
18
#include "
dbusconfig.h
"
19
20
namespace
LC::Util::DBus
21
{
22
struct
Endpoint
23
{
24
QString
Service
;
25
QString
Path
;
26
QString
Interface
;
27
QDBusConnection
Conn
= QDBusConnection::sessionBus ();
28
29
UTIL_DBUS_API
AsyncReply<QVariant>
GetRawProperty
(
const
QString& property)
const
;
30
UTIL_DBUS_API
AsyncReply<QVariantMap>
GetAllProperties
()
const
;
31
32
template
<
typename
T>
33
Task<Either<QDBusError, T>
>
GetProperty
(QString property)
const
34
{
35
const
auto
eitherPropVar =
co_await
GetRawProperty
(property);
36
const
QVariant propVar =
co_await
eitherPropVar;
37
if
(!propVar.canConvert<T> ())
38
{
39
const
auto
& errorMsg =
"Property `%1` expected type %2 but has type %3."
_qs
40
.arg (property, QMetaType::fromType<T> ().name (), propVar.typeName ());
41
co_return
Left
{ QDBusError { QDBusError::InvalidSignature, errorMsg } };
42
}
43
44
co_return
propVar.value<T> ();
45
}
46
47
template
<
typename
... Rets,
typename
... Args>
48
AsyncReply
<Rets...>
Call
(
const
QString& method, Args&&... args)
const
49
{
50
auto
msg = QDBusMessage::createMethodCall (
Service
,
Path
,
Interface
, method);
51
msg.setArguments ({ std::forward<Args> (args)... });
52
return
{
Conn
.asyncCall (msg) };
53
}
54
};
55
56
UTIL_DBUS_API
AsyncReply<>
StartService
(
const
QDBusConnection& conn,
const
QString& name);
57
58
class
UTIL_DBUS_API
TypedSignals
:
public
QObject
59
{
60
Q_OBJECT
61
62
Endpoint
Endpoint_;
63
64
QHash<QString,
QList
<std::function<void (
const
QDBusMessage&)>>> Handlers_;
65
public
:
66
explicit
TypedSignals
(
Endpoint
endpoint, QObject *parent)
67
: QObject { parent }
68
, Endpoint_ { std::move (endpoint) }
69
{
70
}
71
72
template
<
typename
F>
73
bool
Connect
(
const
QString& name, F&& handler)
74
{
75
auto
& handlers = Handlers_ [name];
76
if
(handlers.isEmpty ())
77
{
78
const
auto
connected = Endpoint_.Conn.connect (Endpoint_.Service,
79
Endpoint_.Path,
80
Endpoint_.Interface,
81
name,
82
this
,
83
SLOT (invokeHandlers (QDBusMessage)));
84
if
(!connected)
85
return
false
;
86
}
87
88
auto
unwrapper = [
this
, name, handler = std::forward<F> (handler)] (
const
QDBusMessage& msg)
89
{
90
[&,
this
]<
size_t
... Ixs> (std::index_sequence<Ixs...>)
91
{
92
QDBusPendingReply<std::decay_t<ArgType_t<F, Ixs>>...> payload { msg };
93
if
(payload.isError ())
94
{
95
qWarning () << Endpoint_.Service << Endpoint_.Path << Endpoint_.Interface << name
96
<<
"mismatching arguments:"
<< payload.error ();
97
return
;
98
}
99
handler (payload.template argumentAt<Ixs> ()...);
100
} (std::make_index_sequence<ArgCount_v<F>> {});
101
};
102
handlers << std::move (unwrapper);
103
104
return
true
;
105
}
106
private
slots:
107
void
invokeHandlers (
const
QDBusMessage& msg)
const
108
{
109
const
auto
& name = msg.member ();
110
const
auto
& handlers = Handlers_ [name];
111
if
(handlers.isEmpty ())
112
qWarning () <<
"no handlers for"
<< name;
113
for
(
const
auto
& handler : handlers)
114
handler (msg);
115
}
116
};
117
118
struct
EndpointWithSignals
:
Endpoint
119
{
120
std::unique_ptr<TypedSignals>
TypedSignals_
{};
121
122
template
<
typename
F>
123
bool
Connect
(
const
QString& name, F&& handler)
124
{
125
if
(!
TypedSignals_
)
126
TypedSignals_
= std::make_unique<TypedSignals> (*
this
,
nullptr
);
127
return
TypedSignals_
->Connect (name, std::forward<F> (handler));
128
}
129
130
template
<std::derived_from<QObject> Ctx,
typename
C,
typename
R,
typename
... Args>
131
requires
std::derived_from<Ctx, C>
132
bool
Connect
(
const
QString& name, Ctx *ctx, R (C::*handler) (Args...))
133
{
134
return
Connect
(name, [ctx, handler] (Args... args) { std::invoke (handler, ctx, args...); });
135
}
136
};
137
}
LC::Util::DBus::TypedSignals::TypedSignals
TypedSignals(Endpoint endpoint, QObject *parent)
Definition
async.h:66
LC::Util::DBus::TypedSignals::Connect
bool Connect(const QString &name, F &&handler)
Definition
async.h:73
LC::Util::Task
Definition
task.h:151
QList
Definition
ianrulesstorage.h:14
dbus.h
dbusconfig.h
UTIL_DBUS_API
#define UTIL_DBUS_API
Definition
dbusconfig.h:16
LC::Util::DBus
Definition
async.cpp:15
LC::Util::DBus::StartService
AsyncReply StartService(const QDBusConnection &conn, const QString &name)
Definition
async.cpp:36
qtutil.h
LC::Util::DBus::AsyncReply
Definition
dbus.h:108
LC::Util::DBus::Endpoint
Definition
async.h:23
LC::Util::DBus::Endpoint::Path
QString Path
Definition
async.h:25
LC::Util::DBus::Endpoint::Interface
QString Interface
Definition
async.h:26
LC::Util::DBus::Endpoint::GetAllProperties
UTIL_DBUS_API AsyncReply< QVariantMap > GetAllProperties() const
Definition
async.cpp:26
LC::Util::DBus::Endpoint::GetRawProperty
UTIL_DBUS_API AsyncReply< QVariant > GetRawProperty(const QString &property) const
Definition
async.cpp:16
LC::Util::DBus::Endpoint::Service
QString Service
Definition
async.h:24
LC::Util::DBus::Endpoint::Call
AsyncReply< Rets... > Call(const QString &method, Args &&... args) const
Definition
async.h:48
LC::Util::DBus::Endpoint::GetProperty
Task< Either< QDBusError, T > > GetProperty(QString property) const
Definition
async.h:33
LC::Util::DBus::Endpoint::Conn
QDBusConnection Conn
Definition
async.h:27
LC::Util::DBus::EndpointWithSignals
Definition
async.h:119
LC::Util::DBus::EndpointWithSignals::TypedSignals_
std::unique_ptr< TypedSignals > TypedSignals_
Definition
async.h:120
LC::Util::DBus::EndpointWithSignals::Connect
bool Connect(const QString &name, F &&handler)
Definition
async.h:123
LC::Util::DBus::EndpointWithSignals::Connect
bool Connect(const QString &name, Ctx *ctx, R(C::*handler)(Args...))
Definition
async.h:132
LC::Util::Left
Definition
either.h:21
task.h
either.h
typegetter.h
src
util
dbus
async.h
Generated by
1.17.0