Overte C++ Documentation
AvatarHashMap.h
1 //
2 // AvatarHashMap.h
3 // libraries/avatars/src
4 //
5 // Created by Andrew Meadows on 1/28/2014.
6 // Copyright 2014 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 
13 #ifndef hifi_AvatarHashMap_h
14 #define hifi_AvatarHashMap_h
15 
16 #include <QtCore/QHash>
17 #include <QtCore/QSharedPointer>
18 #include <QtCore/QUuid>
19 
20 #include <functional>
21 #include <memory>
22 #include <chrono>
23 
24 #include <glm/glm.hpp>
25 
26 #include <DependencyManager.h>
27 #include <NLPacket.h>
28 #include <Node.h>
29 
30 #include "ScriptAvatarData.h"
31 
32 #include "AvatarData.h"
33 #include "AssociatedTraitValues.h"
34 
35 const int CLIENT_TO_AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND = 50;
36 const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = USECS_PER_SECOND / CLIENT_TO_AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND;
37 
38 /*@jsdoc
39  * The <code>AvatarList</code> API provides information about avatars within the current domain.
40  *
41  * <p><strong>Warning:</strong> An API named "<code>AvatarList</code>" is also provided for Interface, client entity, and avatar
42  * scripts, however, it is a synonym for the {@link AvatarManager} API.</p>
43  *
44  * @namespace AvatarList
45  *
46  * @hifi-assignment-client
47  * @hifi-server-entity
48  */
49 
50 class AvatarReplicas {
51 public:
52  AvatarReplicas() {}
53  void addReplica(const QUuid& parentID, AvatarSharedPointer replica);
54  std::vector<QUuid> getReplicaIDs(const QUuid& parentID);
55  void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer);
56  void processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged);
57  void removeReplicas(const QUuid& parentID);
58  std::vector<AvatarSharedPointer> takeReplicas(const QUuid& parentID);
59  void processTrait(const QUuid& parentID, AvatarTraits::TraitType traitType, QByteArray traitBinaryData);
60  void processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID);
61  void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType,
62  AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData);
63  void setReplicaCount(int count) { _replicaCount = count; }
64  int getReplicaCount() { return _replicaCount; }
65 
66 private:
67  std::map<QUuid, std::vector<AvatarSharedPointer>> _replicasMap;
68  int _replicaCount { 0 };
69 };
70 
71 
72 class AvatarHashMap : public QObject, public Dependency {
73  Q_OBJECT
74  SINGLETON_DEPENDENCY
75 
76 public:
77  AvatarHash getHashCopy() { QReadLocker lock(&_hashLock); return _avatarHash; }
78  const AvatarHash getHashCopy() const { QReadLocker lock(&_hashLock); return _avatarHash; }
79  int size() { QReadLocker lock(&_hashLock); return _avatarHash.size(); }
80 
81  // Currently, your own avatar will be included as the null avatar id.
82 
83  /*@jsdoc
84  * Gets the IDs of all avatars in the domain.
85  * <p><strong>Warning:</strong> If the AC script is acting as an avatar (i.e., <code>Agent.isAvatar == true</code>) the
86  * avatar's ID is NOT included in results.</p>
87  * @function AvatarList.getAvatarIdentifiers
88  * @returns {Uuid[]} The IDs of all avatars in the domain (excluding AC script's avatar).
89  * @example <caption>Report the IDS of all avatars within the domain.</caption>
90  * var avatars = AvatarList.getAvatarIdentifiers();
91  * print("Avatars in the domain: " + JSON.stringify(avatars));
92  */
93  Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers();
94 
95  /*@jsdoc
96  * Gets the IDs of all avatars within a specified distance from a point.
97  * <p><strong>Warning:</strong> If the AC script is acting as an avatar (i.e., <code>Agent.isAvatar == true</code>) the
98  * avatar's ID is NOT included in results.</p>
99  * @function AvatarList.getAvatarsInRange
100  * @param {Vec3} position - The point about which the search is performed.
101  * @param {number} range - The search radius.
102  * @returns {Uuid[]} The IDs of all avatars within the search distance from the position (excluding AC script's avatar).
103  * @example <caption>Report the IDs of all avatars within 10m of the origin.</caption>
104  * var RANGE = 10;
105  * var avatars = AvatarList.getAvatarsInRange(Vec3.ZERO, RANGE);
106  * print("Avatars near the origin: " + JSON.stringify(avatars));
107  */
108  Q_INVOKABLE QVector<QUuid> getAvatarsInRange(const glm::vec3& position, float rangeMeters) const;
109 
110  /*@jsdoc
111  * Gets information about an avatar.
112  * @function AvatarList.getAvatar
113  * @param {Uuid} avatarID - The ID of the avatar.
114  * @returns {ScriptAvatar} Information about the avatar.
115  */
116  // Null/Default-constructed QUuids will return MyAvatar
117  Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
118 
119  virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); }
120  int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters);
121 
122  void setReplicaCount(int count);
123  int getReplicaCount() { return _replicas.getReplicaCount(); };
124 
125  virtual void clearOtherAvatars();
126 
127 signals:
128 
129  /*@jsdoc
130  * Triggered when an avatar arrives in the domain.
131  * @function AvatarList.avatarAddedEvent
132  * @param {Uuid} sessionUUID - The ID of the avatar that arrived in the domain.
133  * @returns {Signal}
134  * @example <caption>Report when an avatar arrives in the domain.</caption>
135  * AvatarManager.avatarAddedEvent.connect(function (sessionID) {
136  * print("Avatar arrived: " + sessionID);
137  * });
138  *
139  * // Note: If using from the AvatarList API, replace "AvatarManager" with "AvatarList".
140  */
141  void avatarAddedEvent(const QUuid& sessionUUID);
142 
143  /*@jsdoc
144  * Triggered when an avatar leaves the domain.
145  * @function AvatarList.avatarRemovedEvent
146  * @param {Uuid} sessionUUID - The ID of the avatar that left the domain.
147  * @returns {Signal}
148  * @example <caption>Report when an avatar leaves the domain.</caption>
149  * AvatarManager.avatarRemovedEvent.connect(function (sessionID) {
150  * print("Avatar left: " + sessionID);
151  * });
152  *
153  * // Note: If using from the AvatarList API, replace "AvatarManager" with "AvatarList".
154  */
155  void avatarRemovedEvent(const QUuid& sessionUUID);
156 
157  /*@jsdoc
158  * Triggered when an avatar's session ID changes.
159  * @function AvatarList.avatarSessionChangedEvent
160  * @param {Uuid} newSessionUUID - The new session ID.
161  * @param {Uuid} oldSessionUUID - The old session ID.
162  * @returns {Signal}
163  * @example <caption>Report when an avatar's session ID changes.</caption>
164  * AvatarManager.avatarSessionChangedEvent.connect(function (newSessionID, oldSessionID) {
165  * print("Avatar session ID changed from " + oldSessionID + " to " + newSessionID);
166  * });
167  *
168  * // Note: If using from the AvatarList API, replace "AvatarManager" with "AvatarList".
169  */
170  void avatarSessionChangedEvent(const QUuid& sessionUUID,const QUuid& oldUUID);
171 
172 public slots:
173 
174  /*@jsdoc
175  * Checks whether there is an avatar within a specified distance from a point.
176  * @function AvatarList.isAvatarInRange
177  * @param {string} position - The test position.
178  * @param {string} range - The test distance.
179  * @returns {boolean} <code>true</code> if there's an avatar within the specified distance of the point, <code>false</code>
180  * if not.
181  */
182  bool isAvatarInRange(const glm::vec3 & position, const float range);
183 
184 protected slots:
185 
186  /*@jsdoc
187  * @function AvatarList.sessionUUIDChanged
188  * @param {Uuid} sessionUUID - New session ID.
189  * @param {Uuid} oldSessionUUID - Old session ID.
190  * @deprecated This function is deprecated and will be removed.
191  */
192  void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
193 
194  /*@jsdoc
195  * @function AvatarList.processAvatarDataPacket
196  * @param {object} message - Message.
197  * @param {object} sendingNode - Sending node.
198  * @deprecated This function is deprecated and will be removed.
199  */
200  void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
201 
202  /*@jsdoc
203  * @function AvatarList.processAvatarIdentityPacket
204  * @param {object} message - Message.
205  * @param {object} sendingNode - Sending node.
206  * @deprecated This function is deprecated and will be removed.
207  */
208  void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
209 
210  /*@jsdoc
211  * @function AvatarList.processBulkAvatarTraits
212  * @param {object} message - Message.
213  * @param {object} sendingNode - Sending node.
214  * @deprecated This function is deprecated and will be removed.
215  */
216  void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
217 
218  /*@jsdoc
219  * @function AvatarList.processKillAvatar
220  * @param {object} message - Message.
221  * @param {object} sendingNode - Sending node.
222  * @deprecated This function is deprecated and will be removed.
223  */
224  void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
225 
226 protected:
227  AvatarHashMap();
228 
229  virtual AvatarSharedPointer parseAvatarData(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
230  virtual AvatarSharedPointer newSharedAvatar(const QUuid& sessionUUID);
231  virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
232  AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer,
233  bool& isNew);
234  virtual AvatarSharedPointer findAvatar(const QUuid& sessionUUID) const; // uses a QReadLocker on the hashLock
235  virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason);
236 
237  virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
238 
239  mutable QReadWriteLock _hashLock;
240  AvatarHash _avatarHash;
241 
242  std::unordered_map<QUuid, AvatarTraits::TraitVersions> _processedTraitVersions;
243  AvatarReplicas _replicas;
244 
245 private:
246  QUuid _lastOwnerSessionUUID;
247 };
248 
249 #endif // hifi_AvatarHashMap_h