more correct creation and edit times for entities

This commit is contained in:
Andrew Meadows 2014-12-17 12:19:34 -08:00
parent 61ec1bdd6a
commit e36ee2a961
4 changed files with 55 additions and 37 deletions

View file

@ -53,14 +53,13 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
_creatorTokenID = entityItemID.creatorTokenID;
// init values with defaults before calling setProperties
//uint64_t now = usecTimestampNow();
_lastEdited = 0;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = 0; // TODO: when do we actually want to make this "now"
_created = usecTimestampNow();
_changedOnServer = 0;
_position = glm::vec3(0,0,0);
@ -99,16 +98,20 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) {
EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) {
_type = EntityTypes::Unknown;
_lastEdited = 0;
quint64 now = usecTimestampNow();
_created = properties.getCreated() < now ? properties.getCreated() : now;
_lastEdited = _lastEditedFromRemote = _lastSimulated = _lastUpdated = _lastEditedFromRemoteInRemoteTime = _created;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = properties.getCreated();
_dirtyFlags = 0;
_changedOnServer = 0;
initFromEntityItemID(entityItemID);
setProperties(properties, true); // force copy
if (_lastEdited == 0) {
_lastEdited = _created;
}
}
EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
@ -367,7 +370,12 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bytesRead += sizeof(createdFromBuffer);
createdFromBuffer -= clockSkew;
_created = createdFromBuffer; // TODO: do we ever want to discard this???
if (createdFromBuffer < _created) {
// the server claims that this entity has an older creation time
// so we accept it and clear _lastEdited
_created = createdFromBuffer;
_lastEdited = 0;
}
if (wantDebug) {
quint64 lastEdited = getLastEdited();
@ -416,14 +424,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
if (fromSameServerEdit) {
// If this is from the same sever packet, then check against any local changes since we got
// the most recent packet from this server time
if (_lastEdited > _lastEditedFromRemote) {
if (_lastEdited >= _lastEditedFromRemote) {
ignoreServerPacket = true;
}
} else {
// If this isn't from the same sever packet, then honor our skew adjusted times...
// If we've changed our local tree more recently than the new data from this packet
// then we will not be changing our values, instead we just read and skip the data
if (_lastEdited > lastEditedFromBufferAdjusted) {
if (_lastEdited >= lastEditedFromBufferAdjusted) {
ignoreServerPacket = true;
}
}
@ -439,7 +447,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
qDebug() << "USING NEW data from server!!! ****************";
}
_lastEdited = lastEditedFromBufferAdjusted;
// don't allow _lastEdited to be in the future
_lastEdited = lastEditedFromBufferAdjusted < now ? lastEditedFromBufferAdjusted : now;
_lastEditedFromRemote = now;
_lastEditedFromRemoteInRemoteTime = lastEditedFromBuffer;
@ -451,7 +460,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
ByteCountCoded<quint64> updateDeltaCoder = encodedUpdateDelta;
quint64 updateDelta = updateDeltaCoder;
if (overwriteLocalData) {
_lastSimulated = _lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that for _lastEdited
_lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that for _lastEdited
_lastSimulated = now;
if (wantDebug) {
qDebug() << "_lastUpdated =" << _lastUpdated;
qDebug() << "_lastEdited=" << _lastEdited;
@ -576,7 +586,7 @@ void EntityItem::simulate(const quint64& now) {
float timeElapsed = (float)(now - _lastSimulated) / (float)(USECS_PER_SECOND);
if (wantDebug) {
qDebug() << "********** EntityItem::update()";
qDebug() << "********** EntityItem::simulate()";
qDebug() << " entity ID=" << getEntityItemID();
qDebug() << " now=" << now;
qDebug() << " _lastSimulated=" << _lastSimulated;
@ -612,10 +622,8 @@ void EntityItem::simulate(const quint64& now) {
}
}
_lastSimulated = now;
if (wantDebug) {
qDebug() << " ********** EntityItem::update() .... SETTING _lastSimulated=" << _lastSimulated;
qDebug() << " ********** EntityItem::simulate() .... SETTING _lastSimulated=" << _lastSimulated;
}
if (hasAngularVelocity()) {
@ -645,13 +653,13 @@ void EntityItem::simulate(const quint64& now) {
}
}
if (hasVelocity() || hasGravity()) {
if (hasVelocity()) {
glm::vec3 position = getPosition();
glm::vec3 velocity = getVelocity();
glm::vec3 newPosition = position + (velocity * timeElapsed);
if (wantDebug) {
qDebug() << " EntityItem::update()....";
qDebug() << " EntityItem::simulate()....";
qDebug() << " timeElapsed:" << timeElapsed;
qDebug() << " old AACube:" << getMaximumAACube();
qDebug() << " old position:" << position;
@ -677,15 +685,15 @@ void EntityItem::simulate(const quint64& now) {
}
// handle gravity....
if (hasGravity() && !isRestingOnSurface()) {
velocity += getGravity() * timeElapsed;
}
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
// "ground" plane of the domain, but for now it
if (hasGravity() && isRestingOnSurface()) {
velocity.y = 0.0f;
position.y = getDistanceToBottomOfEntity();
if (hasGravity()) {
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
// "ground" plane of the domain, but for now it what we've got
if (isRestingOnSurface()) {
velocity.y = 0.0f;
position.y = getDistanceToBottomOfEntity();
} else {
velocity += getGravity() * timeElapsed;
}
}
// handle damping for velocity
@ -721,10 +729,12 @@ void EntityItem::simulate(const quint64& now) {
qDebug() << " old getAABox:" << getAABox();
}
}
_lastSimulated = now;
}
bool EntityItem::isMoving() const {
return hasVelocity() || (hasGravity() && !isRestingOnSurface()) || hasAngularVelocity();
return hasVelocity() || hasAngularVelocity();
}
bool EntityItem::lifetimeHasExpired() const {
@ -773,10 +783,13 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
// handle the setting of created timestamps for the basic new entity case
if (forceCopy) {
quint64 now = usecTimestampNow();
if (properties.getCreated() == UNKNOWN_CREATED_TIME) {
_created = usecTimestampNow();
_created = now;
} else if (properties.getCreated() != USE_EXISTING_CREATED_TIME) {
_created = properties.getCreated();
quint64 created = properties.getCreated();
// don't allow _created to be in the future
_created = created < now ? created : now;
}
}
@ -803,13 +816,17 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
if (somethingChanged) {
somethingChangedNotification(); // notify derived classes that something has changed
bool wantDebug = false;
uint64_t now = usecTimestampNow();
if (wantDebug) {
uint64_t now = usecTimestampNow();
int elapsed = now - getLastEdited();
qDebug() << "EntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
"now=" << now << " getLastEdited()=" << getLastEdited();
}
setLastEdited(properties._lastEdited);
// don't allow _lastEdited to be in the future
setLastEdited(properties._lastEdited < now ? properties._lastEdited : now);
if (getDirtyFlags() & EntityItem::DIRTY_POSITION) {
_lastSimulated = usecTimestampNow();
}
}
return somethingChanged;

View file

@ -85,7 +85,7 @@ public:
/// Last edited time of this entity universal usecs
quint64 getLastEdited() const { return _lastEdited; }
void setLastEdited(quint64 lastEdited)
{ _lastEdited = _lastSimulated = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
{ _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; }
@ -120,9 +120,6 @@ public:
static int expectedBytes();
static bool encodeEntityEditMessageDetails(PacketType command, EntityItemID id, const EntityItemProperties& details,
unsigned char* bufferOut, int sizeIn, int& sizeOut);
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, size_t length, int clockSkew);
// perform update

View file

@ -95,8 +95,8 @@ enum EntityPropertyList {
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
const quint64 UNKNOWN_CREATED_TIME = (quint64)(-1);
const quint64 USE_EXISTING_CREATED_TIME = (quint64)(-2);
const quint64 UNKNOWN_CREATED_TIME = 0;
const quint64 USE_EXISTING_CREATED_TIME = 1;
/// A collection of properties of an entity item used in the scripting API. Translates between the actual properties of an

View file

@ -71,7 +71,6 @@ bool EntityTypes::registerEntityType(EntityType entityType, const char* name, En
EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
const EntityItemProperties& properties) {
EntityItem* newEntityItem = NULL;
EntityTypeFactory factory = NULL;
if (entityType >= 0 && entityType <= LAST) {
@ -129,7 +128,12 @@ EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int byte
EntityItemID tempEntityID(actualID);
EntityItemProperties tempProperties;
tempProperties.setCreated(usecTimestampNow()); // this is temporary...
// we set the Creation and Edit times to 'now', but if the server submits an earlier Creation time
// then it will be accepted
quint64 now = usecTimestampNow();
tempProperties.setCreated(now);
tempProperties.setLastEdited(now);
return constructEntityItem(entityType, tempEntityID, tempProperties);
}