possible fix for entities not always updating bug

This commit is contained in:
ZappoMan 2014-11-06 13:17:46 -08:00
parent bcec14b0f4
commit 2b62402a57
8 changed files with 110 additions and 4 deletions

View file

@ -154,6 +154,9 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
quint64 startLock = usecTimestampNow();
_myServer->getOctree()->lockForWrite();
qDebug() << "{" << QThread::currentThread() << "} " << "TREE LOCKED FOR EDIT now:" << usecTimestampNow();
quint64 startProcess = usecTimestampNow();
int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType,
reinterpret_cast<const unsigned char*>(packet.data()),
@ -165,6 +168,7 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
<< "editDataBytesRead=" << editDataBytesRead;
}
qDebug() << "{" << QThread::currentThread() << "} " << "TREE UNLOCKED AFTER EDIT now:" << usecTimestampNow();
_myServer->getOctree()->unlock();
quint64 endProcess = usecTimestampNow();

View file

@ -316,6 +316,7 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
// save that we know the view has been sent.
quint64 now = usecTimestampNow();
setLastTimeBagEmpty(now); // is this what we want? poor names
//qDebug() << "{" << QThread::currentThread() << "} " << " nodeData->setLastTimeBagEmpty() now:" << now;
}

View file

@ -344,6 +344,14 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
// only set our last sent time if we weren't resetting due to frustum change
quint64 now = usecTimestampNow();
nodeData->setLastTimeBagEmpty(now);
//qDebug() << "{" << QThread::currentThread() << "} " << " OctreeSendThread::packetDistributor().... bag is empty so we must have sent our view";
//qDebug() << "{" << QThread::currentThread() << "} " << " _nodeUUID:" << _nodeUUID;
if (_node->getActiveSocket()) {
//qDebug() << "{" << QThread::currentThread() << "} " << " _node active socket:" << *(_node->getActiveSocket());
} else {
//qDebug() << "{" << QThread::currentThread() << "} " << " _node active socket:" << "????";
}
//qDebug() << "{" << QThread::currentThread() << "} " << " nodeData->setLastTimeBagEmpty() now:" << now;
}
// track completed scenes and send out the stats packet accordingly
@ -450,13 +458,22 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
quint64 lockWaitStart = usecTimestampNow();
_myServer->getOctree()->lockForRead();
//qDebug() << "{" << QThread::currentThread() << "} " << "TREE LOCKED FOR READ now:" << usecTimestampNow();
quint64 lockWaitEnd = usecTimestampNow();
lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart);
quint64 encodeStart = usecTimestampNow();
bytesWritten = _myServer->getOctree()->encodeTreeBitstream(subTree, &_packetData, nodeData->elementBag, params);
//qDebug() << "{" << QThread::currentThread() << "} " << " OctreeSendThread::packetDistributor()....";
//qDebug() << "{" << QThread::currentThread() << "} " << " _nodeUUID:" << _nodeUUID;
AACube subTreeCube = subTree->getAACube();
subTreeCube.scale((float)TREE_SCALE);
//qDebug() << "{" << QThread::currentThread() << "} " << " subTree:" << subTreeCube;
//qDebug() << "{" << QThread::currentThread() << "} " << " subTree->getLastChanged():" << subTree->getLastChanged();
bytesWritten = _myServer->getOctree()->encodeTreeBitstream(subTree, &_packetData, nodeData->elementBag, params);
quint64 encodeEnd = usecTimestampNow();
encodeElapsedUsec = (float)(encodeEnd - encodeStart);
@ -465,6 +482,18 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
// the packet and send it
completedScene = nodeData->elementBag.isEmpty();
//qDebug() << "{" << QThread::currentThread() << "} " << " OctreeSendThread::packetDistributor()....";
//qDebug() << "{" << QThread::currentThread() << "} " << " _nodeUUID:" << _nodeUUID;
if (_node->getActiveSocket()) {
//qDebug() << "{" << QThread::currentThread() << "} " << " _node active socket:" << *(_node->getActiveSocket());
} else {
//qDebug() << "{" << QThread::currentThread() << "} " << " _node active socket:" << "????";
}
//qDebug() << "{" << QThread::currentThread() << "} " << " params.lastViewFrustumSent:" << params.lastViewFrustumSent;
//qDebug() << "{" << QThread::currentThread() << "} " << " params.stopReason:" << params.getStopReason();
//qDebug() << "{" << QThread::currentThread() << "} " << " bytesWritten:" << bytesWritten;
//qDebug() << "{" << QThread::currentThread() << "} " << " completedScene:" << completedScene;
// if we're trying to fill a full size packet, then we use this logic to determine if we have a DIDNT_FIT case.
if (_packetData.getTargetSize() == MAX_OCTREE_PACKET_DATA_SIZE) {
if (_packetData.hasContent() && bytesWritten == 0 &&
@ -482,6 +511,7 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
}
nodeData->stats.encodeStopped();
//qDebug() << "{" << QThread::currentThread() << "} " << "TREE UNLOCKED AFTER READ now:" << usecTimestampNow();
_myServer->getOctree()->unlock();
} else {
// If the bag was empty then we didn't even attempt to encode, and so we know the bytesWritten were 0
@ -598,6 +628,7 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
// if after sending packets we've emptied our bag, then we want to remember that we've sent all
// the voxels from the current view frustum
if (nodeData->elementBag.isEmpty()) {
//qDebug() << "{" << QThread::currentThread() << "} " << " nodeData->updateLastKnownViewFrustum()";
nodeData->updateLastKnownViewFrustum();
nodeData->setViewSent(true);
nodeData->map.erase(); // It would be nice if we could save this, and only reset it when the view frustum changes

View file

@ -59,6 +59,7 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
_lastUpdated = 0;
_created = 0; // TODO: when do we actually want to make this "now"
_changedOnServer = 0;
_position = glm::vec3(0,0,0);
_rotation = DEFAULT_ROTATION;
@ -87,6 +88,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) {
_lastEditedFromRemoteInRemoteTime = 0;
_lastUpdated = 0;
_created = 0;
_changedOnServer = 0;
initFromEntityItemID(entityItemID);
}
@ -97,6 +99,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemPropert
_lastEditedFromRemoteInRemoteTime = 0;
_lastUpdated = 0;
_created = properties.getCreated();
_changedOnServer = 0;
initFromEntityItemID(entityItemID);
setProperties(properties, true); // force copy
}
@ -161,7 +164,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
quint64 lastEdited = getLastEdited();
const bool wantDebug = false;
const bool wantDebug = true;
if (wantDebug) {
float editedAgo = getEditedAgo();
QString agoAsString = formatSecondsElapsed(editedAgo);

View file

@ -70,10 +70,14 @@ public:
/// Last edited time of this entity universal usecs
quint64 getLastEdited() const { return _lastEdited; }
void setLastEdited(quint64 lastEdited) { _lastEdited = _lastUpdated = lastEdited; }
void setLastEdited(quint64 lastEdited)
{ _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
void markAsChangedOnServer() { _changedOnServer = usecTimestampNow(); }
quint64 getLastChangedOnServer() const { return _changedOnServer; }
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
@ -268,6 +272,7 @@ protected:
quint64 _lastEditedFromRemote; // this is the last time we received and edit from the server
quint64 _lastEditedFromRemoteInRemoteTime; // time in server time space the last time we received and edit from the server
quint64 _created;
quint64 _changedOnServer;
glm::vec3 _position;
glm::vec3 _dimensions;

View file

@ -496,7 +496,10 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
// if the entityItem exists, then update it
if (existingEntity) {
qDebug() << "Calling updateEntity() properties.getLastEdited(): " << properties.getLastEdited();
updateEntity(entityItemID, properties);
existingEntity->markAsChangedOnServer();
qDebug() << "AFTER updateEntity() now: " << usecTimestampNow();
} else {
qDebug() << "User attempted to edit an unknown entity. ID:" << entityItemID;
}
@ -505,6 +508,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
entityItemID = assignEntityID(entityItemID);
EntityItem* newEntity = addEntity(entityItemID, properties);
if (newEntity) {
newEntity->markAsChangedOnServer();
notifyNewlyCreatedEntity(*newEntity, senderNode);
}
}
@ -551,6 +555,7 @@ void EntityTree::releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncod
EntityTreeElementExtraEncodeData* thisExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>(extraData);
delete thisExtraEncodeData;
}
//qDebug() << "{" << QThread::currentThread() << "} " << "EntityTree::releaseSceneEncodeData()... now:" << usecTimestampNow();
extraEncodeData->clear();
}

View file

@ -94,6 +94,7 @@ void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params)
// TODO: some of these inserts might be redundant!!!
extraEncodeData->insert(this, entityTreeElementExtraEncodeData);
//qDebug() << "{" << QThread::currentThread() << "} " << " STORING extraEncodeData->insert(this...) --- STORING EXTRA DATA....";
}
}
@ -238,6 +239,12 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, Oct
OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData* packetData,
EncodeBitstreamParams& params) const {
//qDebug() << "{" << QThread::currentThread() << "} " << " TOP OF appendElementData()";
AACube elementCube = getAACube();
elementCube.scale(TREE_SCALE);
//qDebug() << "{" << QThread::currentThread() << "} " << " elementCube:" << elementCube;
//qDebug() << "{" << QThread::currentThread() << "} " << " getLastChanged():" << getLastChanged();
OctreeElement::AppendState appendElementState = OctreeElement::COMPLETED; // assume the best...
@ -248,7 +255,9 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
if (extraEncodeData && extraEncodeData->contains(this)) {
entityTreeElementExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
hadElementExtraData = true;
//qDebug() << "{" << QThread::currentThread() << "} " << " extraEncodeData->contains(this) --- USING PREVIOUS EXTRA DATA....";
} else {
//qDebug() << "{" << QThread::currentThread() << "} " << " NOT extraEncodeData->contains(this) --- CREATING NEW EXTRA DATA....";
// if there wasn't one already, then create one
entityTreeElementExtraEncodeData = new EntityTreeElementExtraEncodeData();
entityTreeElementExtraEncodeData->elementCompleted = (_entityItems->size() == 0);
@ -282,6 +291,8 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
uint16_t actualNumberOfEntities = 0;
QVector<uint16_t> indexesOfEntitiesToInclude;
//qDebug() << "{" << QThread::currentThread() << "} " << " entityTreeElementExtraEncodeData->elementCompleted:" << entityTreeElementExtraEncodeData->elementCompleted;
// It's possible that our element has been previous completed. In this case we'll simply not include any of our
// entities for encoding. This is needed because we encode the element data at the "parent" level, and so we
// need to handle the case where our sibling elements need encoding but we don't.
@ -289,7 +300,25 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
for (uint16_t i = 0; i < _entityItems->size(); i++) {
EntityItem* entity = (*_entityItems)[i];
bool includeThisEntity = true;
if (!params.forceSendScene && entity->getLastEdited() < params.lastViewFrustumSent) {
bool ignoreFromLastEdit = (entity->getLastEdited() < params.lastViewFrustumSent);
bool ignoreFromChangeOnServer = (entity->getLastChangedOnServer() < params.lastViewFrustumSent);
if (ignoreFromChangeOnServer != ignoreFromLastEdit) {
qDebug() << "{" << QThread::currentThread() << "} " << "IGNORE MISMATCH!!";
qDebug() << "{" << QThread::currentThread() << "} " << "IGNORE based on getLastEdited():" << ignoreFromLastEdit;
qDebug() << "{" << QThread::currentThread() << "} " << "IGNORE based on getLastChangedOnServer():" << ignoreFromChangeOnServer;
qDebug() << "{" << QThread::currentThread() << "} " << "getLastEdited():" << entity->getLastEdited();
qDebug() << "{" << QThread::currentThread() << "} " << "getLastChangedOnServer():" << entity->getLastChangedOnServer();
qDebug() << "{" << QThread::currentThread() << "} " << "params.lastViewFrustumSent:" << params.lastViewFrustumSent;
} else {
qDebug() << "{" << QThread::currentThread() << "} " << "IGNORE MATCH!! - " << ignoreFromLastEdit;
}
if (!params.forceSendScene && entity->getLastChangedOnServer() < params.lastViewFrustumSent) {
qDebug() << "{" << QThread::currentThread() << "} " << " ignore this entity cause it hasn't changed i:" << i;
//qDebug() << "{" << QThread::currentThread() << "} " << " entity->getLastEdited():" << entity->getLastEdited();
//qDebug() << "{" << QThread::currentThread() << "} " << " params.lastViewFrustumSent:" << params.lastViewFrustumSent;
includeThisEntity = false;
}
@ -314,6 +343,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
if (includeThisEntity) {
indexesOfEntitiesToInclude << i;
numberOfEntities++;
//qDebug() << "{" << QThread::currentThread() << "} " << " indexesOfEntitiesToInclude << i:" << i;
}
}
}
@ -321,11 +351,18 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
int numberOfEntitiesOffset = packetData->getUncompressedByteOffset();
bool successAppendEntityCount = packetData->appendValue(numberOfEntities);
//qDebug() << "{" << QThread::currentThread() << "} " << " numberOfEntities:" << numberOfEntities;
//qDebug() << "{" << QThread::currentThread() << "} " << " successAppendEntityCount:" << successAppendEntityCount;
if (successAppendEntityCount) {
foreach (uint16_t i, indexesOfEntitiesToInclude) {
EntityItem* entity = (*_entityItems)[i];
LevelDetails entityLevel = packetData->startLevel();
//qDebug() << "{" << QThread::currentThread() << "} " << "CALLING entity->appendEntityData()...";
//qDebug() << "{" << QThread::currentThread() << "} " << " entity->getEntityItemID():" << entity->getEntityItemID();
//qDebug() << "{" << QThread::currentThread() << "} " << " entity->getLastEdited():" << entity->getLastEdited();
OctreeElement::AppendState appendEntityState = entity->appendEntityData(packetData,
params, entityTreeElementExtraEncodeData);
@ -375,6 +412,9 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
} else {
// TODO: some of these inserts might be redundant!!!
extraEncodeData->insert(this, entityTreeElementExtraEncodeData);
//qDebug() << "{" << QThread::currentThread() << "} " << " STORING extraEncodeData->insert(this...) --- STORING EXTRA DATA....";
}
} else {
@ -383,11 +423,13 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
// If all of our items have been encoded, then we are complete as an element.
if (entityTreeElementExtraEncodeData->entities.size() == 0) {
entityTreeElementExtraEncodeData->elementCompleted = true;
//qDebug() << "{" << QThread::currentThread() << "} " << " MARKING ENTITY AS DONE .... entityTreeElementExtraEncodeData->elementCompleted = true.... now:" << usecTimestampNow();
}
}
// TODO: some of these inserts might be redundant!!!
extraEncodeData->insert(this, entityTreeElementExtraEncodeData);
//qDebug() << "{" << QThread::currentThread() << "} " << " STORING extraEncodeData->insert(this...) --- STORING EXTRA DATA....";
}
}

View file

@ -19,6 +19,7 @@
#include <fstream> // to load voxels from file
#include <QDebug>
#include <QThread>
#include <QVector>
#include <GeometryUtil.h>
@ -1087,6 +1088,9 @@ int Octree::encodeTreeBitstream(OctreeElement* element,
if (suppressEmptySubtrees() && params.includeColor && childBytesWritten == 2) {
childBytesWritten = 0;
//params.stopReason = EncodeBitstreamParams::UNKNOWN; // possibly should be DIDNT_FIT...
//qDebug() << "{" << QThread::currentThread() << "} " << "EncodeBitstreamParams::UNKNOWN???? line:" << __LINE__;
}
// if we wrote child bytes, then return our result of all bytes written
@ -1096,6 +1100,7 @@ int Octree::encodeTreeBitstream(OctreeElement* element,
// otherwise... if we didn't write any child bytes, then pretend like we also didn't write our octal code
bytesWritten = 0;
//params.stopReason = EncodeBitstreamParams::DIDNT_FIT;
//qDebug() << "{" << QThread::currentThread() << "} " << "EncodeBitstreamParams::UNKNOWN???? line:" << __LINE__;
}
if (bytesWritten == 0) {
@ -1231,6 +1236,9 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
if (params.stats) {
params.stats->skippedNoChange(element);
}
//qDebug() << "{" << QThread::currentThread() << "} " << "params.stopReason = EncodeBitstreamParams::NO_CHANGE ... ";
//qDebug() << "{" << QThread::currentThread() << "} " << " params.lastViewFrustumSent:" << params.lastViewFrustumSent;
//qDebug() << "{" << QThread::currentThread() << "} " << " element->getLastChanged():" << element->getLastChanged();
params.stopReason = EncodeBitstreamParams::NO_CHANGE;
return bytesAtThisLevel;
}
@ -1521,6 +1529,12 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
// to be completed.
LevelDetails childDataLevelKey = packetData->startLevel();
//qDebug() << "{" << QThread::currentThread() << "} " << "appendElementData()";
AACube childElementCube = childElement->getAACube();
childElementCube.scale(TREE_SCALE);
//qDebug() << "{" << QThread::currentThread() << "} " << " childElementCube:" << childElementCube;
//qDebug() << "{" << QThread::currentThread() << "} " << " childElement->getLastChanged():" << childElement->getLastChanged();
OctreeElement::AppendState childAppendState = childElement->appendElementData(packetData, params);
// allow our tree subclass to do any additional bookkeeping it needs to do with encoded data state
@ -1872,6 +1886,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
element->elementEncodeComplete(params, &bag);
}
//qDebug() << "{" << QThread::currentThread() << "} " << "got to bottom... didn't set stopReason...";
return bytesAtThisLevel;
}