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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
// Copyright 2020-2021 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_CHANNEL_LISTENER_H_
#define MUMBLE_CHANNEL_LISTENER_H_
#include <QtCore/QHash>
#include <QtCore/QObject>
#include <QtCore/QReadWriteLock>
#include <QtCore/QSet>
#include <atomic>
class User;
class Channel;
/// This class serves as a namespace for storing information about ChannelListeners. This is a feature
/// that allows a user to listen to a channel without being in it. Kinda similar to linked channels
/// except that this is something each user can do individually.
class ChannelListener : public QObject {
private:
Q_OBJECT
Q_DISABLE_COPY(ChannelListener)
protected:
/// A lock for guarding m_listeningUsers as well as m_listenedChannels
mutable QReadWriteLock m_listenerLock;
/// A map between a user's session and a list of IDs of all channels the user is listening to
QHash< unsigned int, QSet< int > > m_listeningUsers;
/// A map between a channel's ID and a list of all user-sessions of users listening to that channel
QHash< int, QSet< unsigned int > > m_listenedChannels;
#ifdef MUMBLE
/// A lock for guarding m_listenerVolumeAdjustments
mutable QReadWriteLock m_volumeLock;
/// A map between channel IDs and local volume adjustments to be made for ChannelListeners
/// in that channel
QHash< int, float > m_listenerVolumeAdjustments;
/// A flag indicating whether the initial synchronization with the server has finished yet
std::atomic< bool > m_initialSyncDone;
#endif
/// The static ChannelListener instance returned by ChannelListener::get()
static ChannelListener s_instance;
/// Constructor
ChannelListener();
/// Adds a listener to the channel.
///
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
void addListenerImpl(unsigned int userSession, int channelID);
/// Removes a listener from the channel.
///
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
void removeListenerImpl(unsigned int userSession, int channelID);
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
/// @returns Whether the given user is listening to the given channel
bool isListeningImpl(unsigned int userSession, int channelID) const;
/// @param userSession The session ID of the user
/// @returns Whether this user is listening to any channel via the ChannelListener feature
bool isListeningToAnyImpl(unsigned int userSession) const;
/// @param channelID The ID of the channel
/// @returns Whether any user listens to this channel via the ChannelListener feature
bool isListenedByAnyImpl(int channelID) const;
/// @param channelID The ID of the channel
/// @returns A set of user sessions of users listening to the given channel
const QSet< unsigned int > getListenersForChannelImpl(int channelID) const;
/// @param userSession The session ID of the user
/// @returns A set of channel IDs of channels the given user is listening to
const QSet< int > getListenedChannelsForUserImpl(unsigned int userSession) const;
/// @param channelID The ID of the channel
/// @returns The amount of users that are listening to the given channel
int getListenerCountForChannelImpl(int channelID) const;
/// @param userSession The session ID of the user
/// @returns The amount of channels the given user is listening to
int getListenedChannelCountForUserImpl(unsigned int userSession) const;
#ifdef MUMBLE
/// Sets the local volume adjustment for any channelListener in the given channel.
///
/// @param channelID The ID of the channel
/// @param volumeAdjustment The volume adjustment to apply
void setListenerLocalVolumeAdjustmentImpl(int channelID, float volumeAdjustment);
/// @param channelID The ID of the channel
/// @param The local volume adjustment for the given channel. If none has been set,
/// 1.0f is being returned.
float getListenerLocalVolumeAdjustmentImpl(int channelID) const;
/// @param filter Whether to filter out adjustments of 1 (which have no effect)
/// @returns A map between channel IDs and the currently set volume adjustment
QHash< int, float > getAllListenerLocalVolumeAdjustmentsImpl(bool filter = false) const;
/// @done Whether the initial synchronization with the server is done yet
void setInitialServerSyncDoneImpl(bool done);
#endif
/// Clears all ChannelListeners and volume adjustments
void clearImpl();
public:
/// @returns The static ChannelListener instance
static ChannelListener &get();
/// Adds a listener to the channel.
///
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
static void addListener(unsigned int userSession, int channelID);
/// Adds a listener to the channel.
///
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
static void addListener(const User *user, const Channel *channel);
/// Removes a listener from the channel.
///
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
static void removeListener(unsigned int userSession, int channelID);
/// Removes a listener from the channel.
///
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
static void removeListener(const User *user, const Channel *channel);
/// @param userSession The session ID of the user
/// @param channelID The ID of the channel
/// @returns Whether the given user is listening to the given channel
static bool isListening(unsigned int userSession, int channelID);
/// @param channel A pointer to the channel object
/// @param user A pointer to the user object
/// @returns Whether the given user is listening to the given channel
static bool isListening(const User *user, const Channel *channel);
/// @param userSession The session ID of the user
/// @returns Whether this user is listening to any channel via the ChannelListener feature
static bool isListeningToAny(unsigned int userSession);
/// @param user A pointer to the user object
/// @returns Whether this user is listening to any channel via the ChannelListener feature
static bool isListeningToAny(const User *user);
/// @param channelID The ID of the channel
/// @returns Whether any user listens to this channel via the ChannelListener feature
static bool isListenedByAny(int channelID);
/// @param channel A pointer to the channel object
/// @returns Whether any user listens to this channel via the ChannelListener feature
static bool isListenedByAny(const Channel *channel);
/// @param channelID The ID of the channel
/// @returns A set of user sessions of users listening to the given channel
static const QSet< unsigned int > getListenersForChannel(int channelID);
/// @param channel A pointer to the channel object
/// @returns A set of user sessions of users listening to the given channel
static const QSet< unsigned int > getListenersForChannel(const Channel *channel);
/// @param userSession The session ID of the user
/// @returns A set of channel IDs of channels the given user is listening to
static const QSet< int > getListenedChannelsForUser(unsigned int userSession);
/// @param user A pointer to the user object
/// @returns A set of channel IDs of channels the given user is listening to
static const QSet< int > getListenedChannelsForUser(const User *user);
/// @param channelID The ID of the channel
/// @returns The amount of users that are listening to the given channel
static int getListenerCountForChannel(int channelID);
/// @param channel A pointer to the channel object
/// @returns The amount of users that are listening to the given channel
static int getListenerCountForChannel(const Channel *channel);
/// @param userSession The session ID of the user
/// @returns The amount of channels the given user is listening to
static int getListenedChannelCountForUser(unsigned int userSession);
/// @param user A pointer to the user object
/// @returns The amount of channels the given user is listening to
static int getListenedChannelCountForUser(const User *user);
#ifdef MUMBLE
/// Sets the local volume adjustment for any channelListener in the given channel.
///
/// @param channelID The ID of the channel
/// @param volumeAdjustment The volume adjustment to apply
static void setListenerLocalVolumeAdjustment(int channelID, float volumeAdjustment);
/// Sets the local volume adjustment for any channelListener in the given channel.
///
/// @param channel A pointer to the channel object
/// @param volumeAdjustment The volume adjustment to apply
static void setListenerLocalVolumeAdjustment(const Channel *channel, float volumeAdjustment);
/// @param channelID The ID of the channel
/// @param The local volume adjustment for the given channel. If none has been set,
/// 1.0f is being returned.
static float getListenerLocalVolumeAdjustment(int channelID);
/// @param channel A pointer to the channel object
/// @param The local volume adjustment for the given channel. If none has been set,
/// 1.0f is being returned.
static float getListenerLocalVolumeAdjustment(const Channel *channel);
/// @param filter Whether to filter out adjustments of 1 (which have no effect)
/// @returns A map between channel IDs and the currently set volume adjustment
static QHash< int, float > getAllListenerLocalVolumeAdjustments(bool filter = false);
/// @done Whether the initial synchronization with the server is done yet
static void setInitialServerSyncDone(bool done);
/// Saves the current ChannelListener state to the database.
/// NOTE: This function may only be called from the main thread!
static void saveToDB();
#endif
/// Clears all ChannelListeners and volume adjustments
static void clear();
signals:
#ifdef MUMBLE
void localVolumeAdjustmentsChanged(int channelID, float newAdjustment, float oldAdjustment);
#endif
};
#endif // MUMBLE_CHANNEL_LISTENER_H_
|