12 #ifndef hifi_EntityTree_h
13 #define hifi_EntityTree_h
18 #include <HelperScriptEngine.h>
20 #include <SpatialParentFinder.h>
22 #include "AddEntityOperator.h"
23 #include "EntityTreeElement.h"
24 #include "DeleteEntityOperator.h"
25 #include "MovingEntitiesOperator.h"
28 using EntityTreePointer = std::shared_ptr<EntityTree>;
30 class EntitySimulation;
32 namespace EntityQueryFilterSymbol {
33 static const QString NonDefault =
"+";
36 class NewlyCreatedEntityHook {
38 virtual void entityCreated(
const EntityItem& newEntity,
const SharedNodePointer& senderNode) = 0;
41 class SendEntitiesOperationArgs {
44 QString entityHostType;
46 EntityTreePointer otherTree;
47 QHash<EntityItemID, EntityItemID>* map;
50 class EntityTree :
public Octree,
public SpatialParentTree {
59 EntityTree(
bool shouldReaverage =
false);
60 virtual ~EntityTree();
62 void createRootElement();
65 void setEntityMaxTmpLifetime(
float maxTmpEntityLifetime) { _maxTmpEntityLifetime = maxTmpEntityLifetime; }
66 void setEntityScriptSourceWhitelist(
const QString& entityScriptSourceWhitelist);
69 virtual OctreeElementPointer createNewElement(
unsigned char* octalCode = NULL)
override;
72 EntityTreeElementPointer getRoot() {
76 return std::static_pointer_cast<EntityTreeElement>(_rootElement);
80 virtual void eraseDomainAndNonOwnedEntities()
override;
81 virtual void eraseAllOctreeElements(
bool createNewRoot =
true)
override;
83 virtual void readBitstreamToTree(
const unsigned char* bitstream,
84 uint64_t bufferSizeBytes, ReadBitstreamToTreeParams& args)
override;
85 int readEntityDataFromBuffer(
const unsigned char* data,
int bytesLeftToRead, ReadBitstreamToTreeParams& args);
89 virtual PacketType expectedDataPacketType()
const override {
return PacketType::EntityData; }
90 virtual bool handlesEditPacketType(PacketType packetType)
const override;
92 virtual int processEditPacketData(ReceivedMessage& message,
const unsigned char* editData,
int maxLength,
93 const SharedNodePointer& senderNode)
override;
95 virtual EntityItemID evalRayIntersection(
const glm::vec3& origin,
const glm::vec3& direction,
96 QVector<EntityItemID> entityIdsToInclude, QVector<EntityItemID> entityIdsToDiscard,
97 PickFilter searchFilter, OctreeElementPointer& element,
float& distance,
98 BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo,
99 Octree::lockType lockType = Octree::TryLock,
bool* accurateResult = NULL);
101 virtual EntityItemID evalParabolaIntersection(
const PickParabola& parabola,
102 QVector<EntityItemID> entityIdsToInclude, QVector<EntityItemID> entityIdsToDiscard,
103 PickFilter searchFilter, OctreeElementPointer& element, glm::vec3& intersection,
104 float& distance,
float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo,
105 Octree::lockType lockType = Octree::TryLock,
bool* accurateResult = NULL);
107 virtual bool rootElementHasData()
const override {
return true; }
109 virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData)
const override;
113 void preUpdate()
override;
114 void update(
bool simulate =
true)
override;
117 void postAddEntity(EntityItemPointer entityItem);
127 void deleteEntity(
const EntityItemID& entityID,
bool force =
false,
bool ignoreWarnings =
true);
129 void deleteEntitiesByID(
const std::vector<EntityItemID>& entityIDs,
bool force =
false,
bool ignoreWarnings =
true);
130 void deleteEntitiesByPointer(
const std::vector<EntityItemPointer>& entities);
132 EntityItemPointer findEntityByID(
const QUuid&
id)
const;
133 EntityItemPointer findEntityByEntityItemID(
const EntityItemID& entityID)
const;
134 virtual SpatiallyNestablePointer findByID(
const QUuid&
id)
const override {
return findEntityByID(
id); }
138 QUuid evalClosestEntity(
const glm::vec3& position,
float targetRadius, PickFilter searchFilter);
139 void evalEntitiesInSphere(
const glm::vec3& center,
float radius, PickFilter searchFilter, QVector<QUuid>& foundEntities);
140 void evalEntitiesInSphereWithType(
const glm::vec3& center,
float radius, EntityTypes::EntityType type, PickFilter searchFilter, QVector<QUuid>& foundEntities);
141 void evalEntitiesInSphereWithName(
const glm::vec3& center,
float radius,
const QString& name,
bool caseSensitive, PickFilter searchFilter, QVector<QUuid>& foundEntities);
142 void evalEntitiesInCube(
const AACube& cube, PickFilter searchFilter, QVector<QUuid>& foundEntities);
143 void evalEntitiesInBox(
const AABox& box, PickFilter searchFilter, QVector<QUuid>& foundEntities);
144 void evalEntitiesInFrustum(
const ViewFrustum& frustum, PickFilter searchFilter, QVector<QUuid>& foundEntities);
146 void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
147 void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
149 bool hasAnyDeletedEntities()
const {
150 QReadLocker locker(&_recentlyDeletedEntitiesLock);
151 return _recentlyDeletedEntityItemIDs.size() > 0;
154 bool hasEntitiesDeletedSince(quint64 sinceTime);
155 static quint64 getAdjustedConsiderSince(quint64 sinceTime);
157 QMultiMap<quint64, QUuid> getRecentlyDeletedEntityIDs()
const {
158 QReadLocker locker(&_recentlyDeletedEntitiesLock);
159 return _recentlyDeletedEntityItemIDs;
162 void forgetEntitiesDeletedBefore(quint64 sinceTime);
164 int processEraseMessage(ReceivedMessage& message,
const SharedNodePointer& sourceNode);
165 int processEraseMessageDetails(
const QByteArray& buffer,
const SharedNodePointer& sourceNode);
166 bool shouldEraseEntity(
EntityItemID entityID,
const SharedNodePointer& sourceNode);
169 EntityTreeElementPointer getContainingElement(
const EntityItemID& entityItemID) ;
170 void addEntityMapEntry(EntityItemPointer entity);
173 virtual void dumpTree()
override;
174 virtual void pruneTree()
override;
176 static QByteArray remapActionDataIDs(QByteArray actionData, QHash<EntityItemID, EntityItemID>& map);
179 const QString& entityHostType,
float x,
float y,
float z);
181 void entityChanged(EntityItemPointer entity);
183 void emitEntityScriptChanging(
const EntityItemID& entityItemID,
bool reload);
184 void emitEntityServerScriptChanging(
const EntityItemID& entityItemID,
bool reload);
186 void setSimulation(EntitySimulationPointer simulation);
187 EntitySimulationPointer getSimulation()
const {
return _simulation; }
189 bool wantEditLogging()
const {
return _wantEditLogging; }
190 void setWantEditLogging(
bool value) { _wantEditLogging = value; }
192 bool wantTerseEditLogging()
const {
return _wantTerseEditLogging; }
193 void setWantTerseEditLogging(
bool value) { _wantTerseEditLogging = value; }
195 virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element,
bool skipDefaultValues,
196 bool skipThoseWithBadParents)
override;
197 virtual bool readFromMap(QVariantMap& entityDescription,
const bool isImport =
false)
override;
198 virtual bool writeToJSON(QString& jsonString,
const OctreeElementPointer& element)
override;
201 glm::vec3 getContentsDimensions();
202 float getContentsLargestDimension();
204 virtual void resetEditStats()
override {
205 _totalEditMessages = 0;
208 _totalDecodeTime = 0;
209 _totalLookupTime = 0;
210 _totalUpdateTime = 0;
211 _totalCreateTime = 0;
212 _totalLoggingTime = 0;
215 virtual quint64 getAverageDecodeTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalDecodeTime / _totalEditMessages; }
216 virtual quint64 getAverageLookupTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalLookupTime / _totalEditMessages; }
217 virtual quint64 getAverageUpdateTime()
const override {
return _totalUpdates == 0 ? 0 : _totalUpdateTime / _totalUpdates; }
218 virtual quint64 getAverageCreateTime()
const override {
return _totalCreates == 0 ? 0 : _totalCreateTime / _totalCreates; }
219 virtual quint64 getAverageLoggingTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; }
220 virtual quint64 getAverageFilterTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalFilterTime / _totalEditMessages; }
222 void trackIncomingEntityLastEdited(quint64 lastEditedTime,
int bytesRead);
223 quint64 getAverageEditDeltas()
const
224 {
return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; }
225 quint64 getAverageEditBytes()
const
226 {
return _totalTrackedEdits == 0 ? 0 : _totalEditBytes / _totalTrackedEdits; }
227 quint64 getMaxEditDelta()
const {
return _maxEditDelta; }
228 quint64 getTotalTrackedEdits()
const {
return _totalTrackedEdits; }
230 EntityTreePointer getThisPointer() {
return std::static_pointer_cast<EntityTree>(shared_from_this()); }
232 bool isDeletedEntity(
const QUuid&
id) {
233 QReadLocker locker(&_deletedEntitiesLock);
234 return _deletedEntityItemIDs.contains(
id);
238 Q_INVOKABLE
int getJointIndex(
const QUuid& entityID,
const QString& name)
const;
239 Q_INVOKABLE QStringList getJointNames(
const QUuid& entityID)
const;
241 void knowAvatarID(
const QUuid& avatarID);
242 void forgetAvatarID(
const QUuid& avatarID);
243 void deleteDescendantsOfAvatar(
const QUuid& avatarID);
244 void removeFromChildrenOfAvatars(EntityItemPointer entity);
246 void addToNeedsParentFixupList(EntityItemPointer entity);
248 void notifyNewCollisionSoundURL(
const QString& newCollisionSoundURL,
const EntityItemID& entityID);
250 static const float DEFAULT_MAX_TMP_ENTITY_LIFETIME;
252 QUuid getMyAvatarSessionUUID() {
return _myAvatar ? _myAvatar->getSessionUUID() : QUuid(); }
253 void setMyAvatar(std::shared_ptr<AvatarData> myAvatar) { _myAvatar = myAvatar; }
255 void swapStaleProxies(std::vector<int>& proxies) { proxies.swap(_staleProxies); }
257 void setIsServerlessMode(
bool value) { _serverlessDomain = value; }
258 bool isServerlessMode()
const {
return _serverlessDomain; }
260 static void setGetEntityObjectOperator(std::function<QObject*(
const QUuid&)> getEntityObjectOperator) { _getEntityObjectOperator = getEntityObjectOperator; }
261 static QObject* getEntityObject(
const QUuid&
id);
263 static void setTextSizeOperator(std::function<QSizeF(
const QUuid&,
const QString&)> textSizeOperator) { _textSizeOperator = textSizeOperator; }
264 static QSizeF textSize(
const QUuid&
id,
const QString& text);
266 static void setEntityClicksCapturedOperator(std::function<
bool()> areEntityClicksCapturedOperator) { _areEntityClicksCapturedOperator = areEntityClicksCapturedOperator; }
267 static bool areEntityClicksCaptured();
269 static void setEmitScriptEventOperator(std::function<
void(
const QUuid&,
const QVariant&)> emitScriptEventOperator) { _emitScriptEventOperator = emitScriptEventOperator; }
270 static void emitScriptEvent(
const QUuid&
id,
const QVariant& message);
272 static void setGetUnscaledDimensionsForIDOperator(std::function<glm::vec3(
const QUuid&)> getUnscaledDimensionsForIDOperator) { _getUnscaledDimensionsForIDOperator = getUnscaledDimensionsForIDOperator; }
273 static glm::vec3 getUnscaledDimensionsForID(
const QUuid&
id);
275 std::map<QString, QString> getNamedPaths()
const {
return _namedPaths; }
278 bool force,
bool tellServer);
282 void deletingEntityPointer(
EntityItem* entityID);
284 void addingEntityPointer(
EntityItem* entityID);
285 void editingEntityPointer(
const EntityItemPointer& entityID);
286 void entityScriptChanging(
const EntityItemID& entityItemID,
const bool reload);
287 void entityServerScriptChanging(
const EntityItemID& entityItemID,
const bool reload);
288 void newCollisionSoundURL(
const QUrl& url,
const EntityItemID& entityID);
289 void clearingEntities();
290 void killChallengeOwnershipTimeoutTimer(
const EntityItemID& certID);
294 void recursivelyFilterAndCollectForDelete(
const EntityItemPointer& entity, std::vector<EntityItemPointer>& entitiesToDelete,
bool force)
const;
295 void processRemovedEntities(
const DeleteEntityOperator& theOperator);
297 const SharedNodePointer& senderNode = SharedNodePointer(
nullptr));
298 static bool sendEntitiesOperation(
const OctreeElementPointer& element,
void* extraData);
301 void notifyNewlyCreatedEntity(
const EntityItem& newEntity,
const SharedNodePointer& senderNode);
303 bool isScriptInWhitelist(
const QString& scriptURL);
305 QReadWriteLock _newlyCreatedHooksLock;
306 QVector<NewlyCreatedEntityHook*> _newlyCreatedHooks;
308 mutable QReadWriteLock _recentlyDeletedEntitiesLock;
309 QMultiMap<quint64, QUuid> _recentlyDeletedEntityItemIDs;
311 mutable QReadWriteLock _deletedEntitiesLock;
312 QSet<QUuid> _deletedEntityItemIDs;
314 void clearDeletedEntities() {
315 QWriteLocker locker(&_deletedEntitiesLock);
316 _deletedEntityItemIDs.clear();
319 void trackDeletedEntity(
const QUuid&
id) {
320 QWriteLocker locker(&_deletedEntitiesLock);
321 _deletedEntityItemIDs << id;
324 mutable QReadWriteLock _entityMapLock;
325 QHash<EntityItemID, EntityItemPointer> _entityMap;
327 EntitySimulationPointer _simulation;
329 bool _wantEditLogging =
false;
330 bool _wantTerseEditLogging =
false;
334 int _totalEditMessages = 0;
335 int _totalUpdates = 0;
336 int _totalCreates = 0;
337 mutable quint64 _totalDecodeTime = 0;
338 mutable quint64 _totalLookupTime = 0;
339 mutable quint64 _totalUpdateTime = 0;
340 mutable quint64 _totalCreateTime = 0;
341 mutable quint64 _totalLoggingTime = 0;
342 mutable quint64 _totalFilterTime = 0;
345 void resetClientEditStats();
346 int _totalTrackedEdits = 0;
347 quint64 _totalEditBytes = 0;
348 quint64 _totalEditDeltas = 0;
349 quint64 _maxEditDelta = 0;
350 quint64 _treeResetTime = 0;
352 void fixupNeedsParentFixups();
353 QVector<EntityItemWeakPointer> _needsParentFixup;
354 mutable QReadWriteLock _needsParentFixupLock;
356 std::mutex _avatarIDsLock;
358 QSet<QUuid> _avatarIDs;
359 std::mutex _childrenOfAvatarsLock;
360 QHash<QUuid, QSet<EntityItemID>> _childrenOfAvatars;
362 float _maxTmpEntityLifetime { DEFAULT_MAX_TMP_ENTITY_LIFETIME };
365 bool _hasEntityEditFilter{
false };
366 QStringList _entityScriptSourceWhitelist;
368 MovingEntitiesOperator _entityMover;
369 QHash<EntityItemID, EntityItemPointer> _entitiesToAdd;
372 std::shared_ptr<AvatarData> _myAvatar{
nullptr };
374 static std::function<QObject*(
const QUuid&)> _getEntityObjectOperator;
375 static std::function<QSizeF(
const QUuid&,
const QString&)> _textSizeOperator;
376 static std::function<bool()> _areEntityClicksCapturedOperator;
377 static std::function<void(
const QUuid&,
const QVariant&)> _emitScriptEventOperator;
378 static std::function<glm::vec3(
const QUuid&)> _getUnscaledDimensionsForIDOperator;
380 std::vector<int32_t> _staleProxies;
382 bool _serverlessDomain {
false };
384 std::map<QString, QString> _namedPaths;
387 AACube updateEntityQueryAACubeWorker(SpatiallyNestablePointer
object,
EntityEditPacketSender* packetSender,
388 MovingEntitiesOperator& moveOperator,
bool force,
bool tellServer);
Utility for processing, packing, queueing and sending of outbound edit voxel messages.
Definition: EntityEditPacketSender.h:25
Definition: EntityItem.h:82
Abstract ID for editing model items. Used in EntityItem JS API.
Definition: EntityItemID.h:28
Definition: EntityItemProperties.h:106
Provides a wrapper around script engine that does not have ScriptManager.
Definition: HelperScriptEngine.h:31