libQuotient
A Qt library for building matrix clients
Loading...
Searching...
No Matches
roomstateview.h
Go to the documentation of this file.
1
// SPDX-FileCopyrightText: 2021 Kitsune Ral <kitsune-ral@users.sf.net>
2
// SPDX-License-Identifier: LGPL-2.1-or-later
3
4
#
pragma
once
5
6
#
include
"events/stateevent.h"
7
#
include
"ranges_extras.h"
8
9
#
include
<
QtCore
/
QHash
>
10
11
namespace
Quotient
{
12
13
class
Room;
14
15
// NB: Both concepts below expect EvT::needsStateKey to exist so you can't
16
// express one via negation of the other (there's still an invalid case of
17
// a non-state event where needsStateKey is not even defined).
18
19
template
<
typename
FnT,
class
EvT = std::decay_t<fn_arg_t<FnT>>>
20
concept Keyed_State_Fn =
EvT
::
needsStateKey
;
21
22
template
<
typename
FnT,
class
EvT = std::decay_t<fn_arg_t<FnT>>>
23
concept Keyless_State_Fn = !
EvT
::
needsStateKey
;
24
25
class
QUOTIENT_API
RoomStateView
26
:
private
QHash
<
StateEventKey
,
const
StateEvent
*> {
27
Q_GADGET
28
public
:
29
const
QHash
<
StateEventKey
,
const
StateEvent
*>&
events
()
const
30
{
31
return
*
this
;
32
}
33
34
//! \brief Get a state event with the given event type and state key
35
//! \return A state event corresponding to the pair of event type
36
//! \p evtType and state key \p stateKey, or `nullptr` if there's
37
//! no such \p evtType / \p stateKey combination in the current
38
//! state.
39
//! \warning The returned value is not guaranteed to be non-`nullptr`; you
40
//! MUST check it before using or use other methods of this class
41
//! such as query() and content() to access state safely.
42
//! \sa content, contentJson, query
43
const
StateEvent
*
get
(
const
QString
&
evtType
,
44
const
QString
&
stateKey
= {})
const
;
45
46
//! \brief Get a state event with the given event type and state key
47
//!
48
//! This is a typesafe overload that accepts a C++ event type instead of
49
//! its Matrix name. It is only defined for events with state key (i.e.,
50
//! derived from KeyedStateEvent).
51
template
<
Keyed_State_Event
EvT
>
52
const
EvT
*
get
(
const
QString
&
stateKey
= {})
const
53
{
54
if
(
const
auto
*
evt
=
get
(
EvT
::
TypeId
,
stateKey
)) {
55
Q_ASSERT
(
evt
->
matrixType
() ==
EvT
::
TypeId
56
&&
evt
->
stateKey
() ==
stateKey
);
57
return
eventCast
<
const
EvT
>(
evt
);
58
}
59
return
nullptr
;
60
}
61
62
//! \brief Get a state event with the given event type
63
//!
64
//! This is a typesafe overload that accepts a C++ event type instead of
65
//! its Matrix name. This overload only defined for events that do not use
66
//! state key (i.e., derived from KeylessStateEvent).
67
template
<
Keyless_State_Event
EvT
>
68
const
EvT
*
get
()
const
69
{
70
if
(
const
auto
*
evt
=
get
(
EvT
::
TypeId
)) {
71
Q_ASSERT
(
evt
->
matrixType
() ==
EvT
::
TypeId
);
72
return
eventCast
<
const
EvT
>(
evt
);
73
}
74
return
nullptr
;
75
}
76
77
using
QHash
::
contains
;
78
79
bool
contains
(
const
QString
&
evtType
,
const
QString
&
stateKey
= {})
const
;
80
81
template
<
Keyed_State_Event
EvT
>
82
bool
contains
(
const
QString
&
stateKey
= {})
const
83
{
84
return
contains
(
EvT
::
TypeId
,
stateKey
);
85
}
86
87
template
<
Keyless_State_Event
EvT
>
88
bool
contains
()
const
89
{
90
return
contains
(
EvT
::
TypeId
);
91
}
92
93
template
<
Keyed_State_Event
EvT
>
94
auto
content
(
const
QString
&
stateKey
,
95
typename
EvT
::
content_type
defaultValue
= {})
const
96
{
97
// EventBase<>::content is special in that it returns a const-ref,
98
// and lift() inside queryOr() can't wrap that in a temporary optional.
99
if
(
const
auto
evt
=
get
<
EvT
>(
stateKey
))
100
return
evt
->
content
();
101
return
std
::
move
(
defaultValue
);
102
}
103
104
template
<
Keyless_State_Event
EvT
>
105
auto
content
(
typename
EvT
::
content_type
defaultValue
= {})
const
106
{
107
// Same as above
108
if
(
const
auto
evt
=
get
<
EvT
>())
109
return
evt
->
content
();
110
return
defaultValue
;
111
}
112
113
//! \brief Get the content of the current state event with the given
114
//! event type and state key
115
//! \return An empty object if there's no event in the current state with
116
//! this event type and state key; the contents of the event
117
//! <tt>'content'</tt> object otherwise
118
Q_INVOKABLE
QJsonObject
contentJson
(
const
QString
&
evtType
,
119
const
QString
&
stateKey
= {})
const
;
120
121
//! \brief Get all state events in the room of a certain type
122
//!
123
//! This function allows to retrieve all events of one type regardless of their state key.
124
//! \note To do its job, the function has to look through the entire list of state events
125
//! currently in the room; this may have implications in performance-sensitive code.
126
//! \return all known state events of \p evtType that have occurred in the room
127
QVector
<
const
StateEvent
*>
eventsOfType
(
const
QString
&
evtType
)
const
;
128
129
//! \brief Get all state events in the room of a certain type
130
//!
131
//! This is a type-safe overload for the case when the event type is known at compile time.
132
//! \note This overload is only defined for event types that expect a state key.
133
//! \note Same as the other overload, this one has to look through the entire list of state
134
//! events, although it is slightly faster thanks to the event type known at compile time.
135
//! \return all known state events of type \p EvT that have occurred in the room
136
template
<
Keyed_State_Event
EvT
>
137
QVector
<
const
EvT
*>
eventsOfType
()
const
138
{
139
using
namespace
std
::
ranges
::
views
;
140
return
rangeTo
<
QVector
>(
filter
(*
this
, &
Event
::
is
<
EvT
>) |
transform
([](
const
StateEvent
*
e
) {
141
return
static_cast
<
const
EvT
*>(
e
); }));
142
}
143
144
//! \brief Run a function on a state event with the given type and key
145
//!
146
//! Use this overload when there's no predefined event type or the event
147
//! type is unknown at compile time.
148
//! \return an optional with the result of the function call, or std::nullopt if the event
149
//! is not found or \p fn fails
150
template
<
typename
FnT
>
151
auto
query
(
const
QString
&
evtType
,
const
QString
&
stateKey
,
FnT
&&
fn
)
const
152
{
153
return
lift
(
std
::
forward
<
FnT
>(
fn
),
get
(
evtType
,
stateKey
));
154
}
155
156
//! \brief Run a function on a state event with the given type and key
157
//!
158
//! This is an overload for keyed state events (those that have
159
//! `needsStateKey == true`) with type defined at compile time.
160
//! \return an optional with the result of the function call, or std::nullopt if the event
161
//! is not found or \p fn fails
162
template
<
Keyed_State_Fn
FnT
>
163
auto
query
(
const
QString
&
stateKey
,
FnT
&&
fn
)
const
164
{
165
using
EventT
=
std
::
decay_t
<
fn_arg_t
<
FnT
>>;
166
return
lift
(
std
::
forward
<
FnT
>(
fn
),
get
<
EventT
>(
stateKey
));
167
}
168
169
//! \brief Run a function on a keyless state event with the given type
170
//!
171
//! This is an overload for keyless state events (those having
172
//! `needsStateKey == false`) with type defined at compile time.
173
//! \return an optional with the result of the function call, or std::nullopt if the event
174
//! is not found or \p fn fails
175
template
<
Keyless_State_Fn
FnT
>
176
auto
query
(
FnT
&&
fn
)
const
177
{
178
using
EventT
=
std
::
decay_t
<
fn_arg_t
<
FnT
>>;
179
return
lift
(
std
::
forward
<
FnT
>(
fn
),
get
<
EventT
>());
180
}
181
182
//! \brief Run a function on each event of the given type
183
//!
184
//! This is effectively a combination of query and eventsOfType() except that it doesn't create
185
//! a new container. The return value of \p FnT is ignored.
186
template
<
Keyed_State_Fn
FnT
>
187
void
queryAll
(
FnT
&&
fn
)
const
188
{
189
using
EventT
=
std
::
decay_t
<
fn_arg_t
<
FnT
>>;
190
for
(
const
auto
*
e
:
std
::
ranges
::
filter_view
(
events
(), &
Event
::
is
<
EventT
>))
191
fn
(
static_cast
<
const
EventT
&>(*
e
));
192
}
193
194
//! \brief Same as query() but with a fallback value
195
//!
196
//! This is a shortcut for `query().value_or()`, passing respective
197
//! arguments to the respective functions. This is an overload for the case
198
//! when the event type cannot be fixed at compile time.
199
//! \return the result of \p fn execution, or \p fallback if the requested
200
//! event doesn't exist or the function fails
201
template
<
typename
FnT
,
typename
FallbackT
>
202
auto
queryOr
(
const
QString
&
evtType
,
const
QString
&
stateKey
,
FnT
&&
fn
,
203
FallbackT
&&
fallback
)
const
204
{
205
return
query
(
evtType
,
stateKey
,
std
::
forward
<
FnT
>(
fn
))
206
.
value_or
(
std
::
forward
<
FallbackT
>(
fallback
));
207
}
208
209
//! \brief Same as query() but with a fallback value
210
//!
211
//! This is a shortcut for `query().value_or()`, passing respective
212
//! arguments to the respective functions. This is an overload for the case
213
//! when the event type cannot be fixed at compile time.
214
//! \return the result of \p fn execution, or \p fallback if the requested
215
//! event doesn't exist or the function fails
216
template
<
typename
FnT
,
typename
FallbackT
>
217
auto
queryOr
(
const
QString
&
stateKey
,
FnT
&&
fn
,
FallbackT
&&
fallback
)
const
218
{
219
return
query
(
stateKey
,
std
::
forward
<
FnT
>(
fn
))
220
.
value_or
(
std
::
forward
<
FallbackT
>(
fallback
));
221
}
222
223
//! \brief Same as query() but with a fallback value
224
//!
225
//! This is a shortcut for `query().value_or()`, passing respective
226
//! arguments to the respective functions. This is an overload for the case
227
//! when the event type cannot be fixed at compile time.
228
//! \return the result of \p fn execution, or \p fallback if the requested
229
//! event doesn't exist or the function fails
230
template
<
typename
FnT
,
typename
FallbackT
>
231
auto
queryOr
(
FnT
&&
fn
,
FallbackT
&&
fallback
)
const
232
{
233
return
query
(
std
::
forward
<
FnT
>(
fn
))
234
.
value_or
(
std
::
forward
<
FallbackT
>(
fallback
));
235
}
236
237
private
:
238
friend
class
Room
;
// Factory class for RoomStateView
239
using
QHash
<
StateEventKey
,
const
StateEvent
*>::
QHash
;
240
};
241
}
// namespace Quotient
Quotient::RoomStateView
Definition
roomstateview.h:26
Quotient
Definition
accountregistry.h:13
QUOTIENT_API
#define QUOTIENT_API
Definition
quotient_export.h:22
Quotient
roomstateview.h
Generated by
1.9.8