1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
// SPDX-FileCopyrightText: 2021 Kitsune Ral <kitsune-ral@users.sf.net>
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
#include "events/stateevent.h"
#include <QtCore/QHash>
namespace Quotient {
class Room;
class RoomStateView : private QHash<StateEventKey, const StateEventBase*> {
Q_GADGET
public:
const QHash<StateEventKey, const StateEventBase*>& events() const
{
return *this;
}
//! \brief Get a state event with the given event type and state key
//! \return A state event corresponding to the pair of event type
//! \p evtType and state key \p stateKey, or nullptr if there's
//! no such \p evtType / \p stateKey combination in the current
//! state.
//! \warning In libQuotient 0.7 the return type changed to an OmittableCref
//! which is effectively a nullable const reference wrapper. You
//! have to check that it has_value() before using. Alternatively
//! you can now use queryCurrentState() to access state safely.
//! \sa getCurrentStateContentJson
const StateEventBase* get(const QString& evtType,
const QString& stateKey = {}) const;
//! \brief Get a state event with the given event type and state key
//!
//! This is a typesafe overload that accepts a C++ event type instead of
//! its Matrix name.
//! \warning In libQuotient 0.7 the return type changed to an Omittable with
//! a reference wrapper inside - you have to check that it
//! has_value() before using. Alternatively you can now use
//! queryCurrentState() to access state safely.
template <typename EvT>
const EvT* get(const QString& stateKey = {}) const
{
static_assert(std::is_base_of_v<StateEventBase, EvT>);
if (const auto* evt = get(EvT::matrixTypeId(), stateKey)) {
Q_ASSERT(evt->matrixType() == EvT::matrixTypeId()
&& evt->stateKey() == stateKey);
return eventCast<const EvT>(evt);
}
return nullptr;
}
using QHash::contains;
bool contains(const QString& evtType, const QString& stateKey = {}) const;
template <typename EvT>
bool contains(const QString& stateKey = {}) const
{
return contains(EvT::matrixTypeId(), stateKey);
}
//! \brief Get the content of the current state event with the given
//! event type and state key
//! \return An empty object if there's no event in the current state with
//! this event type and state key; the contents of the event
//! <tt>'content'</tt> object otherwise
Q_INVOKABLE QJsonObject contentJson(const QString& evtType,
const QString& stateKey = {}) const;
//! \brief Get all state events in the room of a certain type.
//!
//! This method returns all known state events that have occured in
//! the room of the given type.
const QVector<const StateEventBase*>
eventsOfType(const QString& evtType) const;
template <typename FnT>
auto query(const QString& evtType, const QString& stateKey, FnT&& fn) const
{
return lift(std::forward<FnT>(fn), get(evtType, stateKey));
}
template <typename FnT>
auto query(const QString& stateKey, FnT&& fn) const
{
using EventT = std::decay_t<fn_arg_t<FnT>>;
static_assert(std::is_base_of_v<StateEventBase, EventT>);
return lift(std::forward<FnT>(fn), get<EventT>(stateKey));
}
template <typename FnT, typename FallbackT>
auto queryOr(const QString& evtType, const QString& stateKey, FnT&& fn,
FallbackT&& fallback) const
{
return lift(std::forward<FnT>(fn), get(evtType, stateKey))
.value_or(std::forward<FallbackT>(fallback));
}
template <typename FnT>
auto query(FnT&& fn) const
{
return query({}, std::forward<FnT>(fn));
}
template <typename FnT, typename FallbackT>
auto queryOr(const QString& stateKey, FnT&& fn, FallbackT&& fallback) const
{
using EventT = std::decay_t<fn_arg_t<FnT>>;
static_assert(std::is_base_of_v<StateEventBase, EventT>);
return lift(std::forward<FnT>(fn), get<EventT>(stateKey))
.value_or(std::forward<FallbackT>(fallback));
}
template <typename FnT, typename FallbackT>
auto queryOr(FnT&& fn, FallbackT&& fallback) const
{
return queryOr({}, std::forward<FnT>(fn),
std::forward<FallbackT>(fallback));
}
private:
friend class Room;
};
} // namespace Quotient
|