Merge pull request #14239 from ElderOrb/FB19219

FB19219 - Make avatarapp to handle wearables update via drag&drop
This commit is contained in:
Brad Hefta-Gaub 2018-12-09 17:20:13 -08:00 committed by GitHub
commit 0425ae1231
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 94 additions and 17 deletions

View file

@ -3277,4 +3277,8 @@ void EntityItem::prepareForSimulationOwnershipBid(EntityItemProperties& properti
properties.setEntityHostType(getEntityHostType());
properties.setOwningAvatarID(getOwningAvatarID());
setLastBroadcast(now); // for debug/physics status icons
}
bool EntityItem::isWearable() const {
return isVisible() && (getParentID() == DependencyManager::get<NodeList>()->getSessionUUID() || getParentID() == AVATAR_SELF_ID);
}

View file

@ -489,7 +489,7 @@ public:
void scriptHasUnloaded();
void setScriptHasFinishedPreload(bool value);
bool isScriptPreloadFinished();
virtual bool isWearable() const;
bool isDomainEntity() const { return _hostType == entity::HostType::DOMAIN; }
bool isAvatarEntity() const { return _hostType == entity::HostType::AVATAR; }
bool isLocalEntity() const { return _hostType == entity::HostType::LOCAL; }

View file

@ -114,6 +114,8 @@ bool EntityScriptingInterface::canReplaceContent() {
void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
if (_entityTree) {
disconnect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity);
disconnect(_entityTree.get(), &EntityTree::deletingEntityPointer, this, &EntityScriptingInterface::onDeletingEntity);
disconnect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
disconnect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
disconnect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
@ -122,6 +124,8 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
_entityTree = elementTree;
if (_entityTree) {
connect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity, Qt::DirectConnection);
connect(_entityTree.get(), &EntityTree::deletingEntityPointer, this, &EntityScriptingInterface::onDeletingEntity, Qt::DirectConnection);
connect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
connect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
connect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
@ -1060,7 +1064,17 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer
}
}
void EntityScriptingInterface::onAddingEntity(EntityItem* entity) {
if (entity->isWearable()) {
emit addingWearable(entity->getEntityItemID());
}
}
void EntityScriptingInterface::onDeletingEntity(EntityItem* entity) {
if (entity->isWearable()) {
emit deletingWearable(entity->getEntityItemID());
}
}
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
PROFILE_RANGE(script_entities, __FUNCTION__);

View file

@ -1908,6 +1908,31 @@ signals:
*/
void addingEntity(const EntityItemID& entityID);
/**jsdoc
* Triggered when an 'wearable' entity is deleted.
* @function Entities.deletingWearable
* @param {Uuid} entityID - The ID of the 'wearable' entity deleted.
* @returns {Signal}
* @example <caption>Report when an 'wearable' entity is deleted.</caption>
* Entities.deletingWearable.connect(function (entityID) {
* print("Deleted wearable: " + entityID);
* });
*/
void deletingWearable(const EntityItemID& entityID);
/**jsdoc
* Triggered when an 'wearable' entity is added to Interface's local in-memory tree of entities it knows about. This may occur when
* 'wearable' entities are added to avatar
* @function Entities.addingWearable
* @param {Uuid} entityID - The ID of the 'wearable' entity added.
* @returns {Signal}
* @example <caption>Report when an 'wearable' entity is added.</caption>
* Entities.addingWearable.connect(function (entityID) {
* print("Added wearable: " + entityID);
* });
*/
void addingWearable(const EntityItemID& entityID);
/**jsdoc
* Triggered when you disconnect from a domain, at which time Interface's local in-memory tree of entities it knows about
* is cleared.
@ -1938,6 +1963,8 @@ protected:
private slots:
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
void onAddingEntity(EntityItem* entity);
void onDeletingEntity(EntityItem* entity);
private:
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);

View file

@ -305,6 +305,7 @@ void EntityTree::postAddEntity(EntityItemPointer entity) {
fixupNeedsParentFixups();
emit addingEntity(entity->getEntityItemID());
emit addingEntityPointer(entity.get());
}
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {

View file

@ -309,6 +309,7 @@ signals:
void deletingEntity(const EntityItemID& entityID);
void deletingEntityPointer(EntityItem* entityID);
void addingEntity(const EntityItemID& entityID);
void addingEntityPointer(EntityItem* entityID);
void editingEntityPointer(const EntityItemPointer& entityID);
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);

View file

@ -519,7 +519,6 @@ QVector<bool> ModelEntityItem::getJointTranslationsSet() const {
return result;
}
bool ModelEntityItem::hasModel() const {
return resultWithReadLock<bool>([&] {
return !_modelURL.isEmpty();

View file

@ -69,12 +69,12 @@ function getMyAvatarSettings() {
}
}
function updateAvatarWearables(avatar, bookmarkAvatarName, callback) {
function updateAvatarWearables(avatar, callback) {
executeLater(function() {
var wearables = getMyAvatarWearables();
avatar[ENTRY_AVATAR_ENTITIES] = wearables;
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables, 'avatarName' : bookmarkAvatarName})
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables})
if(callback)
callback();
@ -188,7 +188,11 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
sendToQml(message)
break;
case 'selectAvatar':
Entities.addingWearable.disconnect(onAddingWearable);
Entities.deletingWearable.disconnect(onDeletingWearable);
AvatarBookmarks.loadBookmark(message.name);
Entities.addingWearable.connect(onAddingWearable);
Entities.deletingWearable.connect(onDeletingWearable);
break;
case 'deleteAvatar':
AvatarBookmarks.removeBookmark(message.name);
@ -223,7 +227,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
// revert changes using snapshot of wearables
if(currentAvatarWearablesBackup !== null) {
AvatarBookmarks.updateAvatarEntities(currentAvatarWearablesBackup);
updateAvatarWearables(currentAvatar, message.avatarName);
updateAvatarWearables(currentAvatar);
}
} else {
sendToQml({'method' : 'updateAvatarInBookmarks'});
@ -256,8 +260,11 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
parentJointIndex: hipsIndex
};
Entities.addingWearable.disconnect(onAddingWearable);
var entityID = Entities.addEntity(properties, true);
updateAvatarWearables(currentAvatar, message.avatarName, function() {
Entities.addingWearable.connect(onAddingWearable);
updateAvatarWearables(currentAvatar, function() {
onSelectedEntity(entityID);
});
break;
@ -265,8 +272,12 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
ensureWearableSelected(message.entityID);
break;
case 'deleteWearable':
Entities.deletingWearable.disconnect(onDeletingWearable);
Entities.deleteEntity(message.entityID);
updateAvatarWearables(currentAvatar, message.avatarName);
Entities.deletingWearable.connect(onDeletingWearable);
updateAvatarWearables(currentAvatar);
break;
case 'changeDisplayName':
if (MyAvatar.displayName !== message.displayName) {
@ -380,6 +391,18 @@ function onSelectedEntity(entityID, pointerEvent) {
}
}
function onAddingWearable(entityID) {
updateAvatarWearables(currentAvatar, function() {
sendToQml({'method' : 'updateAvatarInBookmarks'});
});
}
function onDeletingWearable(entityID) {
updateAvatarWearables(currentAvatar, function() {
sendToQml({'method' : 'updateAvatarInBookmarks'});
});
}
function handleWearableMessages(channel, message, sender) {
if (channel !== 'Hifi-Object-Manipulation') {
return;
@ -485,6 +508,8 @@ function off() {
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
Entities.addingWearable.disconnect(onAddingWearable);
Entities.deletingWearable.disconnect(onDeletingWearable);
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
@ -495,16 +520,23 @@ function off() {
}
function on() {
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
if (!isWired) { // It is not ok to connect these twice, hence guard.
isWired = true;
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
Entities.addingWearable.connect(onAddingWearable);
Entities.deletingWearable.connect(onDeletingWearable);
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
}
}
function onTabletButtonClicked() {
@ -514,7 +546,6 @@ function onTabletButtonClicked() {
} else {
ContextOverlay.enabled = false;
tablet.loadQMLSource(AVATARAPP_QML_SOURCE);
isWired = true;
}
}
var hasEventBridge = false;