mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 17:10:41 +02:00
keep some additional erase entities history and send to viewers
This commit is contained in:
parent
ff87a6ce6f
commit
006a1d60c8
3 changed files with 65 additions and 62 deletions
|
@ -18,9 +18,7 @@
|
||||||
|
|
||||||
class EntityNodeData : public OctreeQueryNode {
|
class EntityNodeData : public OctreeQueryNode {
|
||||||
public:
|
public:
|
||||||
EntityNodeData() :
|
EntityNodeData() : OctreeQueryNode() { }
|
||||||
OctreeQueryNode(),
|
|
||||||
_lastDeletedEntitiesSentAt(0) { }
|
|
||||||
|
|
||||||
virtual PacketType getMyPacketType() const { return PacketType::EntityData; }
|
virtual PacketType getMyPacketType() const { return PacketType::EntityData; }
|
||||||
|
|
||||||
|
@ -28,7 +26,7 @@ public:
|
||||||
void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; }
|
void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
quint64 _lastDeletedEntitiesSentAt;
|
quint64 _lastDeletedEntitiesSentAt { usecTimestampNow() };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityNodeData_h
|
#endif // hifi_EntityNodeData_h
|
||||||
|
|
|
@ -82,7 +82,6 @@ bool EntityServer::hasSpecialPacketsToSend(const SharedNodePointer& node) {
|
||||||
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
||||||
if (nodeData) {
|
if (nodeData) {
|
||||||
quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
|
quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
|
||||||
|
|
||||||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
shouldSendDeletedEntities = tree->hasEntitiesDeletedSince(deletedEntitiesSentAt);
|
shouldSendDeletedEntities = tree->hasEntitiesDeletedSince(deletedEntitiesSentAt);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +96,6 @@ int EntityServer::sendSpecialPackets(const SharedNodePointer& node, OctreeQueryN
|
||||||
if (nodeData) {
|
if (nodeData) {
|
||||||
quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
|
quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
|
||||||
quint64 deletePacketSentAt = usecTimestampNow();
|
quint64 deletePacketSentAt = usecTimestampNow();
|
||||||
|
|
||||||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
bool hasMoreToSend = true;
|
bool hasMoreToSend = true;
|
||||||
|
|
||||||
|
@ -127,7 +125,6 @@ void EntityServer::pruneDeletedEntities() {
|
||||||
if (tree->hasAnyDeletedEntities()) {
|
if (tree->hasAnyDeletedEntities()) {
|
||||||
|
|
||||||
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
|
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) {
|
DependencyManager::get<NodeList>()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) {
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
|
||||||
|
@ -138,6 +135,8 @@ void EntityServer::pruneDeletedEntities() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
int EXTRA_SECONDS_TO_KEEP = 4;
|
||||||
|
earliestLastDeletedEntitiesSent -= USECS_PER_SECOND * EXTRA_SECONDS_TO_KEEP;
|
||||||
tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
|
tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,16 +384,17 @@ void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool i
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) {
|
void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) {
|
||||||
|
quint64 deletedAt = usecTimestampNow();
|
||||||
const RemovedEntities& entities = theOperator.getEntities();
|
const RemovedEntities& entities = theOperator.getEntities();
|
||||||
foreach(const EntityToDeleteDetails& details, entities) {
|
foreach(const EntityToDeleteDetails& details, entities) {
|
||||||
EntityItemPointer theEntity = details.entity;
|
EntityItemPointer theEntity = details.entity;
|
||||||
|
|
||||||
if (getIsServer()) {
|
if (getIsServer()) {
|
||||||
// set up the deleted entities ID
|
// set up the deleted entities ID
|
||||||
quint64 deletedAt = usecTimestampNow();
|
{
|
||||||
_recentlyDeletedEntitiesLock.lockForWrite();
|
QWriteLocker locker(&_recentlyDeletedEntitiesLock);
|
||||||
_recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID());
|
_recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID());
|
||||||
_recentlyDeletedEntitiesLock.unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
|
@ -802,18 +803,23 @@ void EntityTree::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) {
|
bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) {
|
||||||
|
int EXTRA_SECONDS_TO_CONSIDER = 4;
|
||||||
|
quint64 considerEntitiesSince = sinceTime - (USECS_PER_SECOND * EXTRA_SECONDS_TO_CONSIDER);
|
||||||
|
|
||||||
// we can probably leverage the ordered nature of QMultiMap to do this quickly...
|
// we can probably leverage the ordered nature of QMultiMap to do this quickly...
|
||||||
bool hasSomethingNewer = false;
|
bool hasSomethingNewer = false;
|
||||||
|
{
|
||||||
|
QReadLocker locker(&_recentlyDeletedEntitiesLock);
|
||||||
|
|
||||||
_recentlyDeletedEntitiesLock.lockForRead();
|
QMultiMap<quint64, QUuid>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
|
||||||
QMultiMap<quint64, QUuid>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
|
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
|
||||||
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
|
if (iterator.key() > considerEntitiesSince) {
|
||||||
if (iterator.key() > sinceTime) {
|
hasSomethingNewer = true;
|
||||||
hasSomethingNewer = true;
|
}
|
||||||
|
++iterator;
|
||||||
}
|
}
|
||||||
++iterator;
|
|
||||||
}
|
}
|
||||||
_recentlyDeletedEntitiesLock.unlock();
|
|
||||||
return hasSomethingNewer;
|
return hasSomethingNewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,6 +827,8 @@ bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) {
|
||||||
std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime,
|
std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime,
|
||||||
bool& hasMore) {
|
bool& hasMore) {
|
||||||
|
|
||||||
|
int EXTRA_SECONDS_TO_CONSIDER = 4;
|
||||||
|
quint64 considerEntitiesSince = sinceTime - (USECS_PER_SECOND * EXTRA_SECONDS_TO_CONSIDER);
|
||||||
auto deletesPacket = NLPacket::create(PacketType::EntityErase);
|
auto deletesPacket = NLPacket::create(PacketType::EntityErase);
|
||||||
|
|
||||||
// pack in flags
|
// pack in flags
|
||||||
|
@ -841,48 +849,46 @@ std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_S
|
||||||
|
|
||||||
// we keep a multi map of entity IDs to timestamps, we only want to include the entity IDs that have been
|
// we keep a multi map of entity IDs to timestamps, we only want to include the entity IDs that have been
|
||||||
// deleted since we last sent to this node
|
// deleted since we last sent to this node
|
||||||
_recentlyDeletedEntitiesLock.lockForRead();
|
{
|
||||||
|
QReadLocker locker(&_recentlyDeletedEntitiesLock);
|
||||||
|
|
||||||
bool hasFilledPacket = false;
|
bool hasFilledPacket = false;
|
||||||
|
|
||||||
auto it = _recentlyDeletedEntityItemIDs.constBegin();
|
auto it = _recentlyDeletedEntityItemIDs.constBegin();
|
||||||
while (it != _recentlyDeletedEntityItemIDs.constEnd()) {
|
while (it != _recentlyDeletedEntityItemIDs.constEnd()) {
|
||||||
QList<QUuid> values = _recentlyDeletedEntityItemIDs.values(it.key());
|
QList<QUuid> values = _recentlyDeletedEntityItemIDs.values(it.key());
|
||||||
for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
|
for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
|
||||||
|
|
||||||
// if the timestamp is more recent then out last sent time, include it
|
// if the timestamp is more recent then out last sent time, include it
|
||||||
if (it.key() > sinceTime) {
|
if (it.key() > considerEntitiesSince) {
|
||||||
QUuid entityID = values.at(valueItem);
|
QUuid entityID = values.at(valueItem);
|
||||||
deletesPacket->write(entityID.toRfc4122());
|
deletesPacket->write(entityID.toRfc4122());
|
||||||
|
++numberOfIDs;
|
||||||
|
|
||||||
++numberOfIDs;
|
// check to make sure we have room for one more ID
|
||||||
|
if (NUM_BYTES_RFC4122_UUID > deletesPacket->bytesAvailableForWrite()) {
|
||||||
// check to make sure we have room for one more ID
|
hasFilledPacket = true;
|
||||||
if (NUM_BYTES_RFC4122_UUID > deletesPacket->bytesAvailableForWrite()) {
|
break;
|
||||||
hasFilledPacket = true;
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check to see if we're about to return
|
||||||
|
if (hasFilledPacket) {
|
||||||
|
// let our caller know how far we got
|
||||||
|
sinceTime = it.key();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if we're about to return
|
// if we got to the end, then we're done sending
|
||||||
if (hasFilledPacket) {
|
if (it == _recentlyDeletedEntityItemIDs.constEnd()) {
|
||||||
// let our caller know how far we got
|
hasMore = false;
|
||||||
sinceTime = it.key();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we got to the end, then we're done sending
|
|
||||||
if (it == _recentlyDeletedEntityItemIDs.constEnd()) {
|
|
||||||
hasMore = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_recentlyDeletedEntitiesLock.unlock();
|
|
||||||
|
|
||||||
// replace the count for the number of included IDs
|
// replace the count for the number of included IDs
|
||||||
deletesPacket->seek(numberOfIDsPos);
|
deletesPacket->seek(numberOfIDsPos);
|
||||||
deletesPacket->writePrimitive(numberOfIDs);
|
deletesPacket->writePrimitive(numberOfIDs);
|
||||||
|
@ -895,23 +901,23 @@ std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_S
|
||||||
void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
||||||
QSet<quint64> keysToRemove;
|
QSet<quint64> keysToRemove;
|
||||||
|
|
||||||
_recentlyDeletedEntitiesLock.lockForWrite();
|
{
|
||||||
QMultiMap<quint64, QUuid>::iterator iterator = _recentlyDeletedEntityItemIDs.begin();
|
QWriteLocker locker(&_recentlyDeletedEntitiesLock);
|
||||||
|
QMultiMap<quint64, QUuid>::iterator iterator = _recentlyDeletedEntityItemIDs.begin();
|
||||||
|
|
||||||
// First find all the keys in the map that are older and need to be deleted
|
// First find all the keys in the map that are older and need to be deleted
|
||||||
while (iterator != _recentlyDeletedEntityItemIDs.end()) {
|
while (iterator != _recentlyDeletedEntityItemIDs.end()) {
|
||||||
if (iterator.key() <= sinceTime) {
|
if (iterator.key() <= sinceTime) {
|
||||||
keysToRemove << iterator.key();
|
keysToRemove << iterator.key();
|
||||||
|
}
|
||||||
|
++iterator;
|
||||||
}
|
}
|
||||||
++iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now run through the keysToRemove and remove them
|
// Now run through the keysToRemove and remove them
|
||||||
foreach (quint64 value, keysToRemove) {
|
foreach (quint64 value, keysToRemove) {
|
||||||
_recentlyDeletedEntityItemIDs.remove(value);
|
_recentlyDeletedEntityItemIDs.remove(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_recentlyDeletedEntitiesLock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue