mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
132 lines
6 KiB
C++
132 lines
6 KiB
C++
//
|
|
// EntityTreeSendThread.cpp
|
|
// assignment-client/src/entities
|
|
//
|
|
// Created by Stephen Birarda on 2/15/17.
|
|
// Copyright 2017 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "EntityTreeSendThread.h"
|
|
|
|
#include <EntityNodeData.h>
|
|
#include <EntityTypes.h>
|
|
|
|
#include "EntityServer.h"
|
|
|
|
void EntityTreeSendThread::preDistributionProcessing() {
|
|
auto node = _node.toStrongRef();
|
|
auto nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
|
|
|
if (nodeData) {
|
|
auto jsonQuery = nodeData->getJSONParameters();
|
|
|
|
// check if we have a JSON query with flags
|
|
auto flags = jsonQuery[EntityJSONQueryProperties::FLAGS_PROPERTY].toObject();
|
|
if (!flags.isEmpty()) {
|
|
// check the flags object for specific flags that require special pre-processing
|
|
|
|
bool includeAncestors = flags[EntityJSONQueryProperties::INCLUDE_ANCESTORS_PROPERTY].toBool();
|
|
bool includeDescendants = flags[EntityJSONQueryProperties::INCLUDE_DESCENDANTS_PROPERTY].toBool();
|
|
|
|
if (includeAncestors || includeDescendants) {
|
|
// we need to either include the ancestors, descendants, or both for entities matching the filter
|
|
// included in the JSON query
|
|
|
|
// first reset our flagged extra entities so we start with an empty set
|
|
nodeData->resetFlaggedExtraEntities();
|
|
|
|
auto entityTree = std::static_pointer_cast<EntityTree>(_myServer->getOctree());
|
|
|
|
bool requiresFullScene = false;
|
|
|
|
// enumerate the set of entity IDs we know currently match the filter
|
|
foreach(const QUuid& entityID, nodeData->getSentFilteredEntities()) {
|
|
if (includeAncestors) {
|
|
// we need to include ancestors - recurse up to reach them all and add their IDs
|
|
// to the set of extra entities to include for this node
|
|
entityTree->withReadLock([&]{
|
|
auto filteredEntity = entityTree->findEntityByID(entityID);
|
|
if (filteredEntity) {
|
|
requiresFullScene |= addAncestorsToExtraFlaggedEntities(entityID, *filteredEntity, *nodeData);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (includeDescendants) {
|
|
// we need to include descendants - recurse down to reach them all and add their IDs
|
|
// to the set of extra entities to include for this node
|
|
entityTree->withReadLock([&]{
|
|
auto filteredEntity = entityTree->findEntityByID(entityID);
|
|
if (filteredEntity) {
|
|
requiresFullScene |= addDescendantsToExtraFlaggedEntities(entityID, *filteredEntity, *nodeData);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (requiresFullScene) {
|
|
// for one or more of the entities matching our filter we found new extra entities to include
|
|
|
|
// because it is possible that one of these entities hasn't changed since our last send
|
|
// and therefore would not be recursed to, we need to force a full traversal for this pass
|
|
// of the tree to allow it to grab all of the extra entities we're asking it to include
|
|
nodeData->setShouldForceFullScene(requiresFullScene);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool EntityTreeSendThread::addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID,
|
|
EntityItem& entityItem, EntityNodeData& nodeData) {
|
|
// check if this entity has a parent that is also an entity
|
|
bool success = false;
|
|
auto entityParent = entityItem.getParentPointer(success);
|
|
|
|
if (success && entityParent && entityParent->getNestableType() == NestableType::Entity) {
|
|
// we found a parent that is an entity item
|
|
|
|
// first add it to the extra list of things we need to send
|
|
bool parentWasNew = nodeData.insertFlaggedExtraEntity(filteredEntityID, entityParent->getID());
|
|
|
|
// now recursively call ourselves to get its ancestors added too
|
|
auto parentEntityItem = std::static_pointer_cast<EntityItem>(entityParent);
|
|
bool ancestorsWereNew = addAncestorsToExtraFlaggedEntities(filteredEntityID, *parentEntityItem, nodeData);
|
|
|
|
// return boolean if our parent or any of our ancestors were new additions (via insertFlaggedExtraEntity)
|
|
return parentWasNew || ancestorsWereNew;
|
|
}
|
|
|
|
// since we didn't have a parent niether of our parents or ancestors could be new additions
|
|
return false;
|
|
}
|
|
|
|
bool EntityTreeSendThread::addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID,
|
|
EntityItem& entityItem, EntityNodeData& nodeData) {
|
|
bool hasNewChild = false;
|
|
bool hasNewDescendants = false;
|
|
|
|
// enumerate the immediate children of this entity
|
|
foreach (SpatiallyNestablePointer child, entityItem.getChildren()) {
|
|
|
|
if (child && child->getNestableType() == NestableType::Entity) {
|
|
// this is a child that is an entity
|
|
|
|
// first add it to the extra list of things we need to send
|
|
hasNewChild |= nodeData.insertFlaggedExtraEntity(filteredEntityID, child->getID());
|
|
|
|
// now recursively call ourselves to get its descendants added too
|
|
auto childEntityItem = std::static_pointer_cast<EntityItem>(child);
|
|
hasNewDescendants |= addDescendantsToExtraFlaggedEntities(filteredEntityID, *childEntityItem, nodeData);
|
|
}
|
|
}
|
|
|
|
// return our boolean indicating if we added new children or descendants as extra entities to send
|
|
// (via insertFlaggedExtraEntity)
|
|
return hasNewChild || hasNewDescendants;
|
|
}
|
|
|
|
|