sim ownership uses expiry, apply priority rules

This commit is contained in:
Andrew Meadows 2015-06-12 07:24:41 -07:00
parent 443c7d9c70
commit 82ba5cd4b6
3 changed files with 33 additions and 17 deletions

View file

@ -27,6 +27,8 @@
#include "EntityTree.h"
#include "EntitySimulation.h"
const quint64 SIMULATOR_CHANGE_LOCKOUT_PERIOD = (quint64)(0.2f * USECS_PER_SECOND);
bool EntityItem::_sendPhysicsUpdates = true;
EntityItem::EntityItem(const EntityItemID& entityItemID) :
@ -66,7 +68,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
_userData(ENTITY_ITEM_DEFAULT_USER_DATA),
_simulatorPriority(0),
_simulatorID(ENTITY_ITEM_DEFAULT_SIMULATOR_ID),
_simulatorIDChangedTime(0),
_simulationOwnershipExpiry(0),
_marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID),
_name(ENTITY_ITEM_DEFAULT_NAME),
_href(""),
@ -594,23 +596,24 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// ownership has changed
auto nodeList = DependencyManager::get<NodeList>();
if (_simulatorID == nodeList->getSessionUUID()) {
// we think we're the owner but entityServer says otherwise we only relenquish
// ownership if the incoming priority is greater than or equal to ours
if (priority >= _simulatorPriority) {
// we think we're the owner but entityServer says otherwise
// we relenquish ownership if the incoming priority is greater than or equal to ours
// AND we don't have max priority
if (priority >= _simulatorPriority && _simulatorPriority != MAX_SIMULATOR_PRIORITY) {
// we're losing simulation ownership
_simulatorID = id;
_simulatorPriority = priority;
_simulatorIDChangedTime = usecTimestampNow();
_simulationOwnershipExpiry = usecTimestampNow() + SIMULATOR_CHANGE_LOCKOUT_PERIOD;
}
} else {
_simulatorID = id;
_simulatorPriority = priority;
_simulatorIDChangedTime = usecTimestampNow();
_simulationOwnershipExpiry = usecTimestampNow() + SIMULATOR_CHANGE_LOCKOUT_PERIOD;
}
} else if (priority != _simulatorPriority) {
// This should be an uncommon event: priority is changing but simulatorID is not.
// We only accept this change if we are NOT the simulator owner, since otherwise
// we would have initiated this change.
// priority is changing but simulatorID is not.
// only accept this change if we are NOT the simulator owner, since otherwise
// we would have initiated this change
auto nodeList = DependencyManager::get<NodeList>();
if (_simulatorID != nodeList->getSessionUUID()) {
_simulatorPriority = priority;
@ -1393,14 +1396,16 @@ void EntityItem::updateCreated(uint64_t value) {
}
void EntityItem::setSimulatorID(const QUuid& value) {
_simulatorID = value;
_simulatorIDChangedTime = usecTimestampNow();
if (_simulatorID != value) {
_simulatorID = value;
_simulationOwnershipExpiry = usecTimestampNow() + SIMULATOR_CHANGE_LOCKOUT_PERIOD;
}
}
void EntityItem::updateSimulatorID(const QUuid& value) {
if (_simulatorID != value) {
_simulatorID = value;
_simulatorIDChangedTime = usecTimestampNow();
_simulationOwnershipExpiry = usecTimestampNow() + SIMULATOR_CHANGE_LOCKOUT_PERIOD;
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
}
}

View file

@ -326,7 +326,7 @@ public:
QUuid getSimulatorID() const { return _simulatorID; }
void setSimulatorID(const QUuid& value);
void updateSimulatorID(const QUuid& value);
quint64 getSimulatorIDChangedTime() const { return _simulatorIDChangedTime; }
const quint64& getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; }
const QString& getMarketplaceID() const { return _marketplaceID; }
void setMarketplaceID(const QString& value) { _marketplaceID = value; }
@ -433,7 +433,7 @@ protected:
QString _userData;
uint8_t _simulatorPriority;
QUuid _simulatorID; // id of Node which is currently responsible for simulating this Entity
quint64 _simulatorIDChangedTime; // when was _simulatorID last updated?
quint64 _simulationOwnershipExpiry; // time in future when ownership is back up for grabs
QString _marketplaceID;
QString _name;
QString _href; //Hyperlink href

View file

@ -157,6 +157,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
if (entity->getSimulatorID() == senderID) {
// We only allow the simulation owner to clear their own simulationID's.
simulationBlocked = false;
properties.setSimulatorPriority(0); // clear priority irregardless of priority sent
}
// else: We assume the sender really did believe it was the simulation owner when it sent
} else if (submittedID == senderID) {
@ -165,9 +166,18 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
simulationBlocked = false;
} else {
// the sender is trying to steal ownership from another simulator
// so we apply the ownership change filter
if (usecTimestampNow() - entity->getSimulatorIDChangedTime() > SIMULATOR_CHANGE_LOCKOUT_PERIOD) {
simulationBlocked = false;
// so we apply the rules for ownership change:
// (1) higher priority wins
// (2) equal priority wins if ownership filter has expired except...
// (3) max priority never loses
uint8_t oldPriority = entity->getSimulatorPriority();
if (oldPriority != MAX_SIMULATOR_PRIORITY) {
uint8_t newPriority = properties.getSimulatorPriority();
if (newPriority > oldPriority ||
(newPriority == oldPriority &&
usecTimestampNow() > entity->getSimulationOwnershipExpiry())) {
simulationBlocked = false;
}
}
}
} else {
@ -177,6 +187,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
}
if (simulationBlocked) {
// squash the physics-related changes.
properties.setSimulatorPriorityChanged(false);
properties.setSimulatorIDChanged(false);
properties.setPositionChanged(false);
properties.setRotationChanged(false);