From d7059d8f2de924a953d39ab49823a7547cdc7d92 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 16 Apr 2015 14:46:38 -0700 Subject: [PATCH] add code for uuids in wire protocol. some debugging prints --- examples/dice.js | 2 +- .../entities/src/EntityEditPacketSender.cpp | 9 +++++ libraries/entities/src/EntityItem.cpp | 2 +- libraries/entities/src/EntityItem.h | 6 +-- .../entities/src/EntityItemProperties.cpp | 6 +-- libraries/entities/src/EntityItemProperties.h | 5 ++- .../src/EntityItemPropertiesDefaults.h | 2 +- .../entities/src/EntityItemPropertiesMacros.h | 39 +++++++++++++++++++ .../entities/src/EntityScriptingInterface.cpp | 29 ++++++++------ libraries/entities/src/EntityTree.cpp | 2 +- libraries/entities/src/EntityTreeElement.cpp | 2 +- .../entities/src/SimpleEntitySimulation.cpp | 6 +-- libraries/octree/src/OctreePacketData.cpp | 11 ++++++ libraries/octree/src/OctreePacketData.h | 3 ++ libraries/physics/src/EntityMotionState.cpp | 15 +++---- 15 files changed, 104 insertions(+), 35 deletions(-) diff --git a/examples/dice.js b/examples/dice.js index b118a6b289..2b6d4d478e 100644 --- a/examples/dice.js +++ b/examples/dice.js @@ -13,7 +13,7 @@ // var isDice = false; -var NUMBER_OF_DICE = 2; +var NUMBER_OF_DICE = 1; var dice = []; var DIE_SIZE = 0.20; diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index e94725782d..6f58a5a626 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -36,6 +36,15 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, EntityItemI unsigned char bufferOut[MAX_PACKET_SIZE]; int sizeOut = 0; + + //// XXX + auto nodeList = DependencyManager::get(); + QUuid myNodeID = nodeList->getSessionUUID(); + QString x = properties.getSimulatorID() == myNodeID ? "me" : properties.getSimulatorID().toString(); + qDebug() << "sending update:" << properties.simulatorIDChanged() << properties.getSimulatorID(); + //// XXX + + if (EntityItemProperties::encodeEntityEditPacket(type, modelID, properties, &bufferOut[0], _maxPacketSize, sizeOut)) { #ifdef WANT_DEBUG qCDebug(entities) << "calling queueOctreeEditMessage()..."; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index e8427e0982..94d4d7f8a7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1197,7 +1197,7 @@ void EntityItem::updateLifetime(float value) { } } -void EntityItem::setSimulatorID(const QString& value) { +void EntityItem::setSimulatorID(const QUuid& value) { if (_simulatorID != value) { _simulatorID = value; _simulatorIDChangedTime = usecTimestampNow(); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 124d37d762..634b7e7d3d 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -255,8 +255,8 @@ public: const QString& getUserData() const { return _userData; } void setUserData(const QString& value) { _userData = value; } - QString getSimulatorID() const { return _simulatorID; } - void setSimulatorID(const QString& value); + QUuid getSimulatorID() const { return _simulatorID; } + void setSimulatorID(const QUuid& value); quint64 getSimulatorIDChangedTime() const { return _simulatorIDChangedTime; } const QString& getMarketplaceID() const { return _marketplaceID; } @@ -352,7 +352,7 @@ protected: bool _collisionsWillMove; bool _locked; QString _userData; - QString _simulatorID; // id of Node which is currently responsible for simulating this Entity + QUuid _simulatorID; // id of Node which is currently responsible for simulating this Entity quint64 _simulatorIDChangedTime; // when was _simulatorID last updated? QString _marketplaceID; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8a25d59f26..2ea8e5f578 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -307,7 +307,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons COPY_PROPERTY_TO_QSCRIPTVALUE(animationIsPlaying); COPY_PROPERTY_TO_QSCRIPTVALUE(animationFPS); COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex); - COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(animationSettings,getAnimationSettings()); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(animationSettings, getAnimationSettings()); COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); COPY_PROPERTY_TO_QSCRIPTVALUE(ignoreForCollisions); @@ -319,7 +319,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons COPY_PROPERTY_TO_QSCRIPTVALUE(locked); COPY_PROPERTY_TO_QSCRIPTVALUE(textures); COPY_PROPERTY_TO_QSCRIPTVALUE(userData); - COPY_PROPERTY_TO_QSCRIPTVALUE(simulatorID); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(simulatorID, getSimulatorIDAsString()); COPY_PROPERTY_TO_QSCRIPTVALUE(text); COPY_PROPERTY_TO_QSCRIPTVALUE(lineHeight); COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR_GETTER(textColor, getTextColor()); @@ -403,7 +403,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(locked, setLocked); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(textures, setTextures); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(userData, setUserData); - COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(simulatorID, setSimulatorID); + COPY_PROPERTY_FROM_QSCRIPTVALUE_UUID(simulatorID, setSimulatorID); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(text, setText); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(lineHeight, setLineHeight); COPY_PROPERTY_FROM_QSCRIPTVALUE_COLOR(textColor, setTextColor); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 7de0fc0e8b..3788916807 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -200,7 +200,7 @@ public: DEFINE_PROPERTY_REF(PROP_TEXTURES, Textures, textures, QString); DEFINE_PROPERTY_REF_WITH_SETTER_AND_GETTER(PROP_ANIMATION_SETTINGS, AnimationSettings, animationSettings, QString); DEFINE_PROPERTY_REF(PROP_USER_DATA, UserData, userData, QString); - DEFINE_PROPERTY_REF(PROP_SIMULATOR_ID, SimulatorID, simulatorID, QString); + DEFINE_PROPERTY_REF(PROP_SIMULATOR_ID, SimulatorID, simulatorID, QUuid); DEFINE_PROPERTY_REF(PROP_TEXT, Text, text, QString); DEFINE_PROPERTY(PROP_LINE_HEIGHT, LineHeight, lineHeight, float); DEFINE_PROPERTY_REF(PROP_TEXT_COLOR, TextColor, textColor, xColor); @@ -257,6 +257,7 @@ public: const QStringList& getTextureNames() const { return _textureNames; } void setTextureNames(const QStringList& value) { _textureNames = value; } + QString getSimulatorIDAsString() const { return _simulatorID.toString().mid(1,36).toUpper(); } private: QUuid _id; @@ -330,7 +331,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, Locked, locked, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Textures, textures, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, UserData, userData, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, SimulatorID, simulatorID, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, SimulatorID, simulatorID, QUuid()); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Text, text, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, LineHeight, lineHeight, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, TextColor, textColor, ""); diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index 4b595ae0b8..001f963ecb 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -23,7 +23,7 @@ const glm::vec3 ENTITY_ITEM_ZERO_VEC3(0.0f); const bool ENTITY_ITEM_DEFAULT_LOCKED = false; const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString(""); const QString ENTITY_ITEM_DEFAULT_MARKETPLACE_ID = QString(""); -const QString ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QString(""); +const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid(); const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f; const float ENTITY_ITEM_DEFAULT_GLOW_LEVEL = 0.0f; diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index e3e54f5bc8..8b9d9847bd 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -88,6 +88,22 @@ } \ } +// TODO: this doesn't need a length. See OctreePacketData::appendValue(const QUuid& uuid) +#define READ_ENTITY_PROPERTY_UUID(P,O) \ + if (propertyFlags.getHasProperty(P)) { \ + uint16_t length; \ + memcpy(&length, dataAt, sizeof(length)); \ + dataAt += sizeof(length); \ + bytesRead += sizeof(length); \ + QByteArray ba((const char*)dataAt, length); \ + QUuid value = QUUid::fromRfc4122(ba); \ + dataAt += length; \ + bytesRead += length; \ + if (overwriteLocalData) { \ + O(value); \ + } \ + } + #define READ_ENTITY_PROPERTY_COLOR(P,M) \ if (propertyFlags.getHasProperty(P)) { \ if (overwriteLocalData) { \ @@ -127,6 +143,20 @@ properties.O(value); \ } + +// TODO: make a version of this that does a binary unpacking of the uuid +#define READ_ENTITY_PROPERTY_UUID_TO_PROPERTIES(P,O) \ + if (propertyFlags.getHasProperty(P)) { \ + uint16_t length; \ + memcpy(&length, dataAt, sizeof(length)); \ + dataAt += sizeof(length); \ + processedBytes += sizeof(length); \ + QUuid value((const char*)dataAt); \ + dataAt += length; \ + processedBytes += length; \ + properties.O(value); \ + } + #define READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(P,O) \ if (propertyFlags.getHasProperty(P)) { \ xColor color; \ @@ -207,6 +237,15 @@ } \ } +#define COPY_PROPERTY_FROM_QSCRIPTVALUE_UUID(P, S) \ + QScriptValue P = object.property(#P); \ + if (P.isValid()) { \ + QUuid newValue = P.toVariant().toUuid(); \ + if (_defaultSettings || newValue != _##P) { \ + S(newValue); \ + } \ + } + #define COPY_PROPERTY_FROM_QSCRIPTVALUE_VEC3(P, S) \ QScriptValue P = object.property(#P); \ if (P.isValid()) { \ diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fa142d3abd..57752dff02 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -60,6 +60,19 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { } + +void setSimId(EntityItemProperties& propertiesWithSimID) { + if (propertiesWithSimID.velocityChanged() || + propertiesWithSimID.rotationChanged() || + propertiesWithSimID.containsPositionChange()) { + auto nodeList = DependencyManager::get(); + const QUuid myNodeID = nodeList->getSessionUUID(); + propertiesWithSimID.setSimulatorID(myNodeID); + } +} + + + EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& properties) { // The application will keep track of creatorTokenID @@ -67,11 +80,7 @@ EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& pro // This Node is creating a new object. If it's in motion, set this Node as the simulator. EntityItemProperties propertiesWithSimID = properties; - if (properties.velocityChanged() || properties.rotationChanged()) { - auto nodeList = DependencyManager::get(); - const QString myNodeID = nodeList->getSessionUUID().toString(); - propertiesWithSimID.setSimulatorID(myNodeID); - } + setSimId(propertiesWithSimID); EntityItemID id(NEW_ENTITY, creatorTokenID, false ); @@ -146,14 +155,10 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E } } - // If this node is changing a physics-related property, claim simulation ownership + // if this Node is changing a physics-related property, claim simulation ownership. EntityItemProperties propertiesWithSimID = properties; - if (properties.velocityChanged() || properties.rotationChanged()) { - auto nodeList = DependencyManager::get(); - const QString myNodeID = nodeList->getSessionUUID().toString(); - propertiesWithSimID.setSimulatorID(myNodeID); - } - + setSimId(propertiesWithSimID); + // If we have a local entity tree set, then also update it. We can do this even if we don't know // the actual id, because we can edit out local entities just with creatorTokenID if (_entityTree) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 2227107537..07f61de8b4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -131,7 +131,7 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro } } else { if (properties.simulatorIDChanged() && - !entity->getSimulatorID().isEmpty() && + !entity->getSimulatorID().isNull() && properties.getSimulatorID() != entity->getSimulatorID()) { // A Node is trying to take ownership of the simulation of this entity from another Node. Only allow this // if ownership hasn't recently changed. diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 3dcd2899d3..ad268edc6f 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -719,7 +719,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int if (bytesLeftToRead >= (int)(numberOfEntities * expectedBytesPerEntity)) { // look up the Id of this Node auto nodeList = DependencyManager::get(); - QString myNodeID = nodeList->getSessionUUID().toString(); + QUuid myNodeID = nodeList->getSessionUUID(); for (uint16_t i = 0; i < numberOfEntities; i++) { int bytesForThisEntity = 0; diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 0406aaa443..2c586ae0af 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -38,7 +38,7 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { itemItr = _hasSimulationOwnerEntities.begin(); while (itemItr != _hasSimulationOwnerEntities.end()) { EntityItem* entity = *itemItr; - if (!entity->getSimulatorID().isEmpty() && + if (!entity->getSimulatorID().isNull() && usecTimestampNow() - entity->getLastChangedOnServer() >= AUTO_REMOVE_SIMULATION_OWNER_USEC) { qCDebug(entities) << "auto-removing simulation owner" << entity->getSimulatorID(); entity->setSimulatorID(""); @@ -55,7 +55,7 @@ void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { } else if (entity->getCollisionsWillMove()) { _movableButStoppedEntities.insert(entity); } - if (!entity->getSimulatorID().isEmpty()) { + if (!entity->getSimulatorID().isNull()) { _hasSimulationOwnerEntities.insert(entity); } } @@ -79,7 +79,7 @@ void SimpleEntitySimulation::entityChangedInternal(EntityItem* entity) { _movingEntities.remove(entity); _movableButStoppedEntities.remove(entity); } - if (!entity->getSimulatorID().isEmpty()) { + if (!entity->getSimulatorID().isNull()) { _hasSimulationOwnerEntities.insert(entity); } } diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 674faa11c3..346d2f1a79 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -411,6 +411,17 @@ bool OctreePacketData::appendValue(const QString& string) { return success; } +bool OctreePacketData::appendValue(const QUuid& uuid) { + // TODO: this doesn't need a length + QByteArray bytes = uuid.toRfc4122(); + uint16_t length = bytes.size(); + bool success = appendValue(length); + if (success) { + success = appendRawData((const unsigned char*)bytes.constData(), bytes.size()); + } + return success; +} + bool OctreePacketData::appendValue(const QByteArray& bytes) { bool success = appendRawData((const unsigned char*)bytes.constData(), bytes.size()); return success; diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 1c1576f509..992eca99ae 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -166,6 +166,9 @@ public: /// appends a string value to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QString& string); + /// appends a uuid value to the end of the stream, may fail if new data stream is too long to fit in packet + bool appendValue(const QUuid& uuid); + /// appends a QByteArray value to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QByteArray& bytes); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 655db8fd2f..02d2ed896b 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -188,10 +188,10 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { } auto nodeList = DependencyManager::get(); - QString myNodeID = nodeList->getSessionUUID().toString(); - QString simulatorID = _entity->getSimulatorID(); + QUuid myNodeID = nodeList->getSessionUUID(); + QUuid simulatorID = _entity->getSimulatorID(); - if (!simulatorID.isEmpty() && simulatorID != myNodeID) { + if (!simulatorID.isNull() && simulatorID != myNodeID) { // some other Node is simulating this, so don't broadcast our computations. return false; } @@ -249,13 +249,13 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ auto nodeList = DependencyManager::get(); - QString myNodeID = nodeList->getSessionUUID().toString(); - QString simulatorID = _entity->getSimulatorID(); - if (simulatorID.isEmpty() && !(zeroSpeed && zeroSpin)) { + QUuid myNodeID = nodeList->getSessionUUID(); + QUuid simulatorID = _entity->getSimulatorID(); + if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { // The object is moving and nobody thinks they own the motion. set this Node as the simulator _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); - } else if (simulatorID == myNodeID && _numNonMovingUpdates >= MAX_NUM_NON_MOVING_UPDATES - 1) { + } else if (simulatorID == myNodeID && _numNonMovingUpdates >= MAX_NUM_NON_MOVING_UPDATES - 2) { // we are the simulator and the object has stopped. give up "simulator" status _entity->setSimulatorID(""); properties.setSimulatorID(""); @@ -293,6 +293,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ #ifdef WANT_DEBUG qCDebug(physics) << "EntityMotionState::sendUpdate()... calling queueEditEntityMessage()..."; #endif + entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties); } else { #ifdef WANT_DEBUG