Merge branch 'master' of github.com:highfidelity/hifi into quiet-es-sim-spam

This commit is contained in:
Seth Alves 2016-06-13 13:41:32 -07:00
commit 998a5594c0
4 changed files with 65 additions and 39 deletions

View file

@ -239,11 +239,13 @@ void Avatar::updateAvatarEntities() {
} }
AvatarEntityIDs recentlyDettachedAvatarEntities = getAndClearRecentlyDetachedIDs(); AvatarEntityIDs recentlyDettachedAvatarEntities = getAndClearRecentlyDetachedIDs();
foreach (auto entityID, recentlyDettachedAvatarEntities) { _avatarEntitiesLock.withReadLock([&] {
if (!_avatarEntityData.contains(entityID)) { foreach (auto entityID, recentlyDettachedAvatarEntities) {
entityTree->deleteEntity(entityID, true, true); if (!_avatarEntityData.contains(entityID)) {
entityTree->deleteEntity(entityID, true, true);
}
} }
} });
}); });
if (success) { if (success) {

View file

@ -709,12 +709,14 @@ void MyAvatar::saveData() {
settings.beginWriteArray("avatarEntityData"); settings.beginWriteArray("avatarEntityData");
int avatarEntityIndex = 0; int avatarEntityIndex = 0;
for (auto entityID : _avatarEntityData.keys()) { _avatarEntitiesLock.withReadLock([&] {
settings.setArrayIndex(avatarEntityIndex); for (auto entityID : _avatarEntityData.keys()) {
settings.setValue("id", entityID); settings.setArrayIndex(avatarEntityIndex);
settings.setValue("properties", _avatarEntityData.value(entityID)); settings.setValue("id", entityID);
avatarEntityIndex++; settings.setValue("properties", _avatarEntityData.value(entityID));
} avatarEntityIndex++;
}
});
settings.endArray(); settings.endArray();
settings.setValue("displayName", _displayName); settings.setValue("displayName", _displayName);

View file

@ -900,7 +900,11 @@ bool AvatarData::processAvatarIdentity(const Identity& identity) {
hasIdentityChanged = true; hasIdentityChanged = true;
} }
if (identity.avatarEntityData != _avatarEntityData) { bool avatarEntityDataChanged = false;
_avatarEntitiesLock.withReadLock([&] {
avatarEntityDataChanged = (identity.avatarEntityData != _avatarEntityData);
});
if (avatarEntityDataChanged) {
setAvatarEntityData(identity.avatarEntityData); setAvatarEntityData(identity.avatarEntityData);
hasIdentityChanged = true; hasIdentityChanged = true;
} }
@ -914,7 +918,9 @@ QByteArray AvatarData::identityByteArray() {
QUrl emptyURL(""); QUrl emptyURL("");
const QUrl& urlToSend = _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL; const QUrl& urlToSend = _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL;
identityStream << getSessionUUID() << urlToSend << _attachmentData << _displayName << _avatarEntityData; _avatarEntitiesLock.withReadLock([&] {
identityStream << getSessionUUID() << urlToSend << _attachmentData << _displayName << _avatarEntityData;
});
return identityData; return identityData;
} }
@ -1306,16 +1312,18 @@ QJsonObject AvatarData::toJson() const {
root[JSON_AVATAR_ATTACHEMENTS] = attachmentsJson; root[JSON_AVATAR_ATTACHEMENTS] = attachmentsJson;
} }
if (!_avatarEntityData.empty()) { _avatarEntitiesLock.withReadLock([&] {
QJsonArray avatarEntityJson; if (!_avatarEntityData.empty()) {
for (auto entityID : _avatarEntityData.keys()) { QJsonArray avatarEntityJson;
QVariantMap entityData; for (auto entityID : _avatarEntityData.keys()) {
entityData.insert("id", entityID); QVariantMap entityData;
entityData.insert("properties", _avatarEntityData.value(entityID)); entityData.insert("id", entityID);
avatarEntityJson.push_back(QVariant(entityData).toJsonObject()); entityData.insert("properties", _avatarEntityData.value(entityID));
avatarEntityJson.push_back(QVariant(entityData).toJsonObject());
}
root[JSON_AVATAR_ENTITIES] = avatarEntityJson;
} }
root[JSON_AVATAR_ENTITIES] = avatarEntityJson; });
}
auto recordingBasis = getRecordingBasis(); auto recordingBasis = getRecordingBasis();
bool success; bool success;
@ -1604,8 +1612,10 @@ void AvatarData::updateAvatarEntity(const QUuid& entityID, const QByteArray& ent
QMetaObject::invokeMethod(this, "updateAvatarEntity", Q_ARG(const QUuid&, entityID), Q_ARG(QByteArray, entityData)); QMetaObject::invokeMethod(this, "updateAvatarEntity", Q_ARG(const QUuid&, entityID), Q_ARG(QByteArray, entityData));
return; return;
} }
_avatarEntityData.insert(entityID, entityData); _avatarEntitiesLock.withWriteLock([&] {
_avatarEntityDataLocallyEdited = true; _avatarEntityData.insert(entityID, entityData);
_avatarEntityDataLocallyEdited = true;
});
} }
void AvatarData::clearAvatarEntity(const QUuid& entityID) { void AvatarData::clearAvatarEntity(const QUuid& entityID) {
@ -1613,18 +1623,25 @@ void AvatarData::clearAvatarEntity(const QUuid& entityID) {
QMetaObject::invokeMethod(this, "clearAvatarEntity", Q_ARG(const QUuid&, entityID)); QMetaObject::invokeMethod(this, "clearAvatarEntity", Q_ARG(const QUuid&, entityID));
return; return;
} }
_avatarEntityData.remove(entityID);
_avatarEntityDataLocallyEdited = true; _avatarEntitiesLock.withWriteLock([&] {
_avatarEntityData.remove(entityID);
_avatarEntityDataLocallyEdited = true;
});
} }
AvatarEntityMap AvatarData::getAvatarEntityData() const { AvatarEntityMap AvatarData::getAvatarEntityData() const {
AvatarEntityMap result;
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
AvatarEntityMap result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAvatarEntityData", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAvatarEntityData", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(AvatarEntityMap, result)); Q_RETURN_ARG(AvatarEntityMap, result));
return result; return result;
} }
return _avatarEntityData;
_avatarEntitiesLock.withReadLock([&] {
result = _avatarEntityData;
});
return result;
} }
void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) { void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
@ -1632,29 +1649,33 @@ void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
QMetaObject::invokeMethod(this, "setAvatarEntityData", Q_ARG(const AvatarEntityMap&, avatarEntityData)); QMetaObject::invokeMethod(this, "setAvatarEntityData", Q_ARG(const AvatarEntityMap&, avatarEntityData));
return; return;
} }
if (_avatarEntityData != avatarEntityData) { _avatarEntitiesLock.withWriteLock([&] {
// keep track of entities that were attached to this avatar but no longer are if (_avatarEntityData != avatarEntityData) {
AvatarEntityIDs previousAvatarEntityIDs = QSet<QUuid>::fromList(_avatarEntityData.keys()); // keep track of entities that were attached to this avatar but no longer are
AvatarEntityIDs previousAvatarEntityIDs = QSet<QUuid>::fromList(_avatarEntityData.keys());
_avatarEntityData = avatarEntityData; _avatarEntityData = avatarEntityData;
setAvatarEntityDataChanged(true); setAvatarEntityDataChanged(true);
foreach (auto entityID, previousAvatarEntityIDs) { foreach (auto entityID, previousAvatarEntityIDs) {
if (!_avatarEntityData.contains(entityID)) { if (!_avatarEntityData.contains(entityID)) {
_avatarEntityDetached.insert(entityID); _avatarEntityDetached.insert(entityID);
}
} }
} }
} });
} }
AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() { AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() {
AvatarEntityIDs result;
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
AvatarEntityIDs result;
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getRecentlyDetachedIDs", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getRecentlyDetachedIDs", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(AvatarEntityIDs, result)); Q_RETURN_ARG(AvatarEntityIDs, result));
return result; return result;
} }
AvatarEntityIDs result = _avatarEntityDetached; _avatarEntitiesLock.withWriteLock([&] {
_avatarEntityDetached.clear(); result = _avatarEntityDetached;
_avatarEntityDetached.clear();
});
return result; return result;
} }

View file

@ -418,6 +418,7 @@ protected:
// updates about one avatar to another. // updates about one avatar to another.
glm::vec3 _globalPosition; glm::vec3 _globalPosition;
mutable ReadWriteLockable _avatarEntitiesLock;
AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar
AvatarEntityMap _avatarEntityData; AvatarEntityMap _avatarEntityData;
bool _avatarEntityDataLocallyEdited { false }; bool _avatarEntityDataLocallyEdited { false };