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 setEntityScriptSourceAllowlist(
const QString& entityScriptSourceAllowlist);
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;
91 void fixupTerseEditLogging(EntityItemProperties& properties, QList<QString>& changedProperties);
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);
119 EntityItemPointer addEntity(
const EntityItemID& entityID,
const EntityItemProperties& properties,
bool isClone =
false,
const bool isImport =
false);
122 bool updateEntity(
const EntityItemID& entityID,
const EntityItemProperties& properties,
const SharedNodePointer& senderNode = SharedNodePointer(
nullptr));
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 evalEntitiesInSphereWithTags(
const glm::vec3& center,
float radius,
const QVector<QString>& tags,
bool caseSensitive, PickFilter searchFilter, QVector<QUuid>& foundEntities);
143 void evalEntitiesInCube(
const AACube& cube, PickFilter searchFilter, QVector<QUuid>& foundEntities);
144 void evalEntitiesInBox(
const AABox& box, PickFilter searchFilter, QVector<QUuid>& foundEntities);
145 void evalEntitiesInFrustum(
const ViewFrustum& frustum, PickFilter searchFilter, QVector<QUuid>& foundEntities);
147 void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
148 void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
150 bool hasAnyDeletedEntities()
const {
151 QReadLocker locker(&_recentlyDeletedEntitiesLock);
152 return _recentlyDeletedEntityItemIDs.size() > 0;
155 bool hasEntitiesDeletedSince(quint64 sinceTime);
156 static quint64 getAdjustedConsiderSince(quint64 sinceTime);
158 QMultiMap<quint64, QUuid> getRecentlyDeletedEntityIDs()
const {
159 QReadLocker locker(&_recentlyDeletedEntitiesLock);
160 return _recentlyDeletedEntityItemIDs;
163 void forgetEntitiesDeletedBefore(quint64 sinceTime);
165 int processEraseMessage(ReceivedMessage& message,
const SharedNodePointer& sourceNode);
166 int processEraseMessageDetails(
const QByteArray& buffer,
const SharedNodePointer& sourceNode);
167 bool shouldEraseEntity(
EntityItemID entityID,
const SharedNodePointer& sourceNode);
170 EntityTreeElementPointer getContainingElement(
const EntityItemID& entityItemID) ;
171 void addEntityMapEntry(EntityItemPointer entity);
174 virtual void dumpTree()
override;
175 virtual void pruneTree()
override;
177 static QByteArray remapActionDataIDs(QByteArray actionData, QHash<EntityItemID, EntityItemID>& map);
180 const QString& entityHostType,
float x,
float y,
float z);
182 void entityChanged(EntityItemPointer entity);
184 void emitEntityScriptChanging(
const EntityItemID& entityItemID,
bool reload);
185 void emitEntityServerScriptChanging(
const EntityItemID& entityItemID,
bool reload);
187 void setSimulation(EntitySimulationPointer simulation);
188 EntitySimulationPointer getSimulation()
const {
return _simulation; }
190 bool wantEditLogging()
const {
return _wantEditLogging; }
191 void setWantEditLogging(
bool value) { _wantEditLogging = value; }
193 bool wantTerseEditLogging()
const {
return _wantTerseEditLogging; }
194 void setWantTerseEditLogging(
bool value) { _wantTerseEditLogging = value; }
196 virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element,
bool skipDefaultValues,
197 bool skipThoseWithBadParents)
override;
198 virtual bool readFromMap(QVariantMap& entityDescription,
const bool isImport =
false)
override;
199 virtual bool writeToJSON(QString& jsonString,
const OctreeElementPointer& element)
override;
202 glm::vec3 getContentsDimensions();
203 float getContentsLargestDimension();
205 virtual void resetEditStats()
override {
206 _totalEditMessages = 0;
209 _totalDecodeTime = 0;
210 _totalLookupTime = 0;
211 _totalUpdateTime = 0;
212 _totalCreateTime = 0;
213 _totalLoggingTime = 0;
216 virtual quint64 getAverageDecodeTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalDecodeTime / _totalEditMessages; }
217 virtual quint64 getAverageLookupTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalLookupTime / _totalEditMessages; }
218 virtual quint64 getAverageUpdateTime()
const override {
return _totalUpdates == 0 ? 0 : _totalUpdateTime / _totalUpdates; }
219 virtual quint64 getAverageCreateTime()
const override {
return _totalCreates == 0 ? 0 : _totalCreateTime / _totalCreates; }
220 virtual quint64 getAverageLoggingTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; }
221 virtual quint64 getAverageFilterTime()
const override {
return _totalEditMessages == 0 ? 0 : _totalFilterTime / _totalEditMessages; }
223 void trackIncomingEntityLastEdited(quint64 lastEditedTime,
int bytesRead);
224 quint64 getAverageEditDeltas()
const
225 {
return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; }
226 quint64 getAverageEditBytes()
const
227 {
return _totalTrackedEdits == 0 ? 0 : _totalEditBytes / _totalTrackedEdits; }
228 quint64 getMaxEditDelta()
const {
return _maxEditDelta; }
229 quint64 getTotalTrackedEdits()
const {
return _totalTrackedEdits; }
231 EntityTreePointer getThisPointer() {
return std::static_pointer_cast<EntityTree>(shared_from_this()); }
233 bool isDeletedEntity(
const QUuid&
id) {
234 QReadLocker locker(&_deletedEntitiesLock);
235 return _deletedEntityItemIDs.contains(
id);
239 Q_INVOKABLE
int getJointIndex(
const QUuid& entityID,
const QString& name)
const;
240 Q_INVOKABLE QStringList getJointNames(
const QUuid& entityID)
const;
242 void knowAvatarID(
const QUuid& avatarID);
243 void forgetAvatarID(
const QUuid& avatarID);
244 void deleteDescendantsOfAvatar(
const QUuid& avatarID);
245 void removeFromChildrenOfAvatars(EntityItemPointer entity);
247 void addToNeedsParentFixupList(EntityItemPointer entity);
249 void notifyNewCollisionSoundURL(
const QString& newCollisionSoundURL,
const EntityItemID& entityID);
251 static const float DEFAULT_MAX_TMP_ENTITY_LIFETIME;
253 QUuid getMyAvatarSessionUUID() {
return _myAvatar ? _myAvatar->getSessionUUID() : QUuid(); }
254 void setMyAvatar(std::shared_ptr<AvatarData> myAvatar) { _myAvatar = myAvatar; }
256 void swapStaleProxies(std::vector<int>& proxies) { proxies.swap(_staleProxies); }
258 void setIsServerlessMode(
bool value) { _serverlessDomain = value; }
259 bool isServerlessMode()
const {
return _serverlessDomain; }
261 void setIsEntityServer(
bool value) { _entityServer = value; }
262 bool isEntityServer()
const {
return _entityServer; }
264 static void setGetEntityObjectOperator(std::function<QObject*(
const QUuid&)> getEntityObjectOperator) { _getEntityObjectOperator = getEntityObjectOperator; }
265 static QObject* getEntityObject(
const QUuid&
id);
267 static void setTextSizeOperator(std::function<QSizeF(
const QUuid&,
const QString&)> textSizeOperator) { _textSizeOperator = textSizeOperator; }
268 static QSizeF textSize(
const QUuid&
id,
const QString& text);
270 static void setEntityClicksCapturedOperator(std::function<
bool()> areEntityClicksCapturedOperator) { _areEntityClicksCapturedOperator = areEntityClicksCapturedOperator; }
271 static bool areEntityClicksCaptured();
273 static void setEmitScriptEventOperator(std::function<
void(
const QUuid&,
const QVariant&)> emitScriptEventOperator) { _emitScriptEventOperator = emitScriptEventOperator; }
274 static void emitScriptEvent(
const QUuid&
id,
const QVariant& message);
276 static void setGetUnscaledDimensionsForIDOperator(std::function<glm::vec3(
const QUuid&)> getUnscaledDimensionsForIDOperator) { _getUnscaledDimensionsForIDOperator = getUnscaledDimensionsForIDOperator; }
277 static glm::vec3 getUnscaledDimensionsForID(
const QUuid&
id);
279 std::map<QString, QString> getNamedPaths()
const {
return _namedPaths; }
282 bool force,
bool tellServer);
286 void deletingEntityPointer(EntityItem* entityID);
288 void addingEntityPointer(EntityItem* entityID);
289 void editingEntityPointer(
const EntityItemPointer& entityID);
290 void entityScriptChanging(
const EntityItemID& entityItemID,
const bool reload);
291 void entityServerScriptChanging(
const EntityItemID& entityItemID,
const bool reload);
292 void newCollisionSoundURL(
const QUrl& url,
const EntityItemID& entityID);
293 void clearingEntities();
294 void killChallengeOwnershipTimeoutTimer(
const EntityItemID& certID);
298 void recursivelyFilterAndCollectForDelete(
const EntityItemPointer& entity, std::vector<EntityItemPointer>& entitiesToDelete,
bool force)
const;
299 void processRemovedEntities(
const DeleteEntityOperator& theOperator);
300 bool updateEntity(EntityItemPointer entity,
const EntityItemProperties& properties,
301 const SharedNodePointer& senderNode = SharedNodePointer(
nullptr));
302 static bool sendEntitiesOperation(
const OctreeElementPointer& element,
void* extraData);
303 static void bumpTimestamp(EntityItemProperties& properties);
305 void notifyNewlyCreatedEntity(
const EntityItem& newEntity,
const SharedNodePointer& senderNode);
307 bool isScriptInAllowlist(
const QString& scriptURL);
309 QReadWriteLock _newlyCreatedHooksLock;
310 QVector<NewlyCreatedEntityHook*> _newlyCreatedHooks;
312 mutable QReadWriteLock _recentlyDeletedEntitiesLock;
313 QMultiMap<quint64, QUuid> _recentlyDeletedEntityItemIDs;
315 mutable QReadWriteLock _deletedEntitiesLock;
316 QSet<QUuid> _deletedEntityItemIDs;
318 void clearDeletedEntities() {
319 QWriteLocker locker(&_deletedEntitiesLock);
320 _deletedEntityItemIDs.clear();
323 void trackDeletedEntity(
const QUuid&
id) {
324 QWriteLocker locker(&_deletedEntitiesLock);
325 _deletedEntityItemIDs << id;
328 mutable QReadWriteLock _entityMapLock;
329 QHash<EntityItemID, EntityItemPointer> _entityMap;
331 EntitySimulationPointer _simulation;
333 bool _wantEditLogging =
false;
334 bool _wantTerseEditLogging =
false;
338 int _totalEditMessages = 0;
339 int _totalUpdates = 0;
340 int _totalCreates = 0;
341 mutable quint64 _totalDecodeTime = 0;
342 mutable quint64 _totalLookupTime = 0;
343 mutable quint64 _totalUpdateTime = 0;
344 mutable quint64 _totalCreateTime = 0;
345 mutable quint64 _totalLoggingTime = 0;
346 mutable quint64 _totalFilterTime = 0;
349 void resetClientEditStats();
350 int _totalTrackedEdits = 0;
351 quint64 _totalEditBytes = 0;
352 quint64 _totalEditDeltas = 0;
353 quint64 _maxEditDelta = 0;
354 quint64 _treeResetTime = 0;
356 void fixupNeedsParentFixups();
357 QVector<EntityItemWeakPointer> _needsParentFixup;
358 mutable QReadWriteLock _needsParentFixupLock;
360 std::mutex _avatarIDsLock;
362 QSet<QUuid> _avatarIDs;
363 std::mutex _childrenOfAvatarsLock;
364 QHash<QUuid, QSet<EntityItemID>> _childrenOfAvatars;
366 float _maxTmpEntityLifetime { DEFAULT_MAX_TMP_ENTITY_LIFETIME };
368 bool filterProperties(
const EntityItemPointer& existingEntity, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut,
bool& wasChanged, FilterType filterType)
const;
369 bool _hasEntityEditFilter{
false };
370 QStringList _entityScriptSourceAllowlist;
372 MovingEntitiesOperator _entityMover;
373 QHash<EntityItemID, EntityItemPointer> _entitiesToAdd;
376 std::shared_ptr<AvatarData> _myAvatar{
nullptr };
378 static std::function<QObject*(
const QUuid&)> _getEntityObjectOperator;
379 static std::function<QSizeF(
const QUuid&,
const QString&)> _textSizeOperator;
380 static std::function<bool()> _areEntityClicksCapturedOperator;
381 static std::function<void(
const QUuid&,
const QVariant&)> _emitScriptEventOperator;
382 static std::function<glm::vec3(
const QUuid&)> _getUnscaledDimensionsForIDOperator;
384 std::vector<int32_t> _staleProxies;
386 bool _serverlessDomain {
false };
387 bool _entityServer {
false };
389 std::map<QString, QString> _namedPaths;
392 AACube updateEntityQueryAACubeWorker(SpatiallyNestablePointer
object,
EntityEditPacketSender* packetSender,
393 MovingEntitiesOperator& moveOperator,
bool force,
bool tellServer);
399 void convertGrabUserDataToProperties(EntityItemProperties& properties);
Utility for processing, packing, queueing and sending of outbound edit voxel messages.
Definition: EntityEditPacketSender.h:25
Abstract ID for editing model items. Used in EntityItem JS API.
Definition: EntityItemID.h:28
Provides a wrapper around script engine that does not have ScriptManager.
Definition: HelperScriptEngine.h:31