mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #15285 from danteruiz/avatar-fading
Case 21415: Avatars stay behind after they disconnect
This commit is contained in:
commit
cf7eeb7355
13 changed files with 106 additions and 92 deletions
|
@ -85,7 +85,6 @@ AvatarManager::AvatarManager(QObject* parent) :
|
|||
|
||||
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
AvatarSharedPointer avatar = AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer);
|
||||
|
||||
const auto otherAvatar = std::static_pointer_cast<OtherAvatar>(avatar);
|
||||
if (otherAvatar && _space) {
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
|
@ -211,7 +210,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
{
|
||||
// lock the hash for read to check the size
|
||||
QReadLocker lock(&_hashLock);
|
||||
if (_avatarHash.size() < 2 && _avatarsToFadeOut.isEmpty()) {
|
||||
if (_avatarHash.size() < 2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -376,19 +375,12 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
qApp->getMain3DScene()->enqueueTransaction(renderTransaction);
|
||||
}
|
||||
|
||||
if (!_spaceProxiesToDelete.empty() && _space) {
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
workloadTransaction.remove(_spaceProxiesToDelete);
|
||||
_spaceProxiesToDelete.clear();
|
||||
}
|
||||
_space->enqueueTransaction(workloadTransaction);
|
||||
|
||||
_numAvatarsUpdated = numAvatarsUpdated;
|
||||
_numAvatarsNotUpdated = numAvatarsNotUpdated;
|
||||
_numHeroAvatarsUpdated = numHerosUpdated;
|
||||
|
||||
simulateAvatarFades(deltaTime);
|
||||
|
||||
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
|
||||
}
|
||||
|
||||
|
@ -401,31 +393,6 @@ void AvatarManager::postUpdate(float deltaTime, const render::ScenePointer& scen
|
|||
}
|
||||
}
|
||||
|
||||
void AvatarManager::simulateAvatarFades(float deltaTime) {
|
||||
if (_avatarsToFadeOut.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QReadLocker locker(&_hashLock);
|
||||
QVector<AvatarSharedPointer>::iterator avatarItr = _avatarsToFadeOut.begin();
|
||||
const render::ScenePointer& scene = qApp->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
while (avatarItr != _avatarsToFadeOut.end()) {
|
||||
auto avatar = std::static_pointer_cast<Avatar>(*avatarItr);
|
||||
avatar->updateFadingStatus();
|
||||
if (!avatar->isFading()) {
|
||||
// fading to zero is such a rare event we push a unique transaction for each
|
||||
if (avatar->isInScene()) {
|
||||
avatar->removeFromScene(*avatarItr, scene, transaction);
|
||||
}
|
||||
avatarItr = _avatarsToFadeOut.erase(avatarItr);
|
||||
} else {
|
||||
++avatarItr;
|
||||
}
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
AvatarSharedPointer AvatarManager::newSharedAvatar(const QUuid& sessionUUID) {
|
||||
auto otherAvatar = new OtherAvatar(qApp->thread());
|
||||
otherAvatar->setSessionUUID(sessionUUID);
|
||||
|
@ -453,7 +420,6 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
|
|||
transaction.objectsToRemove.push_back(mState);
|
||||
}
|
||||
avatar->resetDetailedMotionStates();
|
||||
|
||||
} else {
|
||||
if (avatar->getDetailedMotionStates().size() == 0) {
|
||||
avatar->createDetailedMotionStates(avatar);
|
||||
|
@ -521,10 +487,6 @@ void AvatarManager::removeDeadAvatarEntities(const SetOfEntities& deadEntities)
|
|||
|
||||
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
||||
auto avatar = std::static_pointer_cast<OtherAvatar>(removedAvatar);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
_spaceProxiesToDelete.push_back(avatar->getSpaceIndex());
|
||||
}
|
||||
AvatarHashMap::handleRemovedAvatar(avatar, removalReason);
|
||||
avatar->tearDownGrabs();
|
||||
|
||||
|
@ -535,17 +497,39 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
|
|||
// it might not fire until after we create a new instance for the same remote avatar, which creates a race
|
||||
// on the creation of entities for that avatar instance and the deletion of entities for this instance
|
||||
avatar->removeAvatarEntitiesFromTree();
|
||||
|
||||
if (removalReason == KillAvatarReason::TheirAvatarEnteredYourBubble) {
|
||||
emit AvatarInputs::getInstance()->avatarEnteredIgnoreRadius(avatar->getSessionUUID());
|
||||
emit DependencyManager::get<UsersScriptingInterface>()->enteredIgnoreRadius();
|
||||
|
||||
workload::Transaction workloadTransaction;
|
||||
workloadTransaction.remove(avatar->getSpaceIndex());
|
||||
_space->enqueueTransaction(workloadTransaction);
|
||||
|
||||
const render::ScenePointer& scene = qApp->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
avatar->removeFromScene(avatar, scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else if (removalReason == KillAvatarReason::AvatarDisconnected) {
|
||||
// remove from node sets, if present
|
||||
DependencyManager::get<NodeList>()->removeFromIgnoreMuteSets(avatar->getSessionUUID());
|
||||
DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID());
|
||||
avatar->fadeOut(qApp->getMain3DScene(), removalReason);
|
||||
render::Transaction transaction;
|
||||
auto scene = qApp->getMain3DScene();
|
||||
avatar->fadeOut(transaction, removalReason);
|
||||
|
||||
workload::SpacePointer space = _space;
|
||||
transaction.transitionFinishedOperator(avatar->getRenderItemID(), [space, avatar]() {
|
||||
const render::ScenePointer& scene = qApp->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
avatar->removeFromScene(avatar, scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
|
||||
workload::Transaction workloadTransaction;
|
||||
workloadTransaction.remove(avatar->getSpaceIndex());
|
||||
space->enqueueTransaction(workloadTransaction);
|
||||
});
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
_avatarsToFadeOut.push_back(removedAvatar);
|
||||
}
|
||||
|
||||
void AvatarManager::clearOtherAvatars() {
|
||||
|
|
|
@ -220,8 +220,6 @@ private:
|
|||
explicit AvatarManager(QObject* parent = 0);
|
||||
explicit AvatarManager(const AvatarManager& other);
|
||||
|
||||
void simulateAvatarFades(float deltaTime);
|
||||
|
||||
AvatarSharedPointer newSharedAvatar(const QUuid& sessionUUID) override;
|
||||
|
||||
// called only from the AvatarHashMap thread - cannot be called while this thread holds the
|
||||
|
@ -231,8 +229,6 @@ private:
|
|||
KillAvatarReason removalReason = KillAvatarReason::NoReason) override;
|
||||
void handleTransitAnimations(AvatarTransit::Status status);
|
||||
|
||||
QVector<AvatarSharedPointer> _avatarsToFadeOut;
|
||||
|
||||
using SetOfOtherAvatars = std::set<OtherAvatarPointer>;
|
||||
SetOfOtherAvatars _avatarsToChangeInPhysics;
|
||||
|
||||
|
@ -252,7 +248,6 @@ private:
|
|||
|
||||
mutable std::mutex _spaceLock;
|
||||
workload::SpacePointer _space;
|
||||
std::vector<int32_t> _spaceProxiesToDelete;
|
||||
|
||||
AvatarTransit::TransitConfig _transitConfig;
|
||||
};
|
||||
|
|
|
@ -942,8 +942,6 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
|
|||
}
|
||||
|
||||
handleChangedAvatarEntityData();
|
||||
|
||||
updateFadingStatus();
|
||||
}
|
||||
|
||||
// As far as I know no HMD system supports a play area of a kilometer in radius.
|
||||
|
|
|
@ -356,7 +356,6 @@ void OtherAvatar::simulate(float deltaTime, bool inView) {
|
|||
PROFILE_RANGE(simulation, "grabs");
|
||||
applyGrabChanges();
|
||||
}
|
||||
updateFadingStatus();
|
||||
}
|
||||
|
||||
void OtherAvatar::handleChangedAvatarEntityData() {
|
||||
|
|
|
@ -652,9 +652,8 @@ void Avatar::fadeIn(render::ScenePointer scene) {
|
|||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
void Avatar::fadeOut(render::ScenePointer scene, KillAvatarReason reason) {
|
||||
void Avatar::fadeOut(render::Transaction& transaction, KillAvatarReason reason) {
|
||||
render::Transition::Type transitionType = render::Transition::USER_LEAVE_DOMAIN;
|
||||
render::Transaction transaction;
|
||||
|
||||
if (reason == KillAvatarReason::YourAvatarEnteredTheirBubble) {
|
||||
transitionType = render::Transition::BUBBLE_ISECT_TRESPASSER;
|
||||
|
@ -662,7 +661,6 @@ void Avatar::fadeOut(render::ScenePointer scene, KillAvatarReason reason) {
|
|||
transitionType = render::Transition::BUBBLE_ISECT_OWNER;
|
||||
}
|
||||
fade(transaction, transitionType);
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
void Avatar::fade(render::Transaction& transaction, render::Transition::Type type) {
|
||||
|
@ -672,19 +670,6 @@ void Avatar::fade(render::Transaction& transaction, render::Transition::Type typ
|
|||
transaction.addTransitionToItem(itemId, type, _renderItemID);
|
||||
}
|
||||
}
|
||||
_isFading = true;
|
||||
}
|
||||
|
||||
void Avatar::updateFadingStatus() {
|
||||
if (_isFading) {
|
||||
render::Transaction transaction;
|
||||
transaction.queryTransitionOnItem(_renderItemID, [this](render::ItemID id, const render::Transition* transition) {
|
||||
if (!transition || transition->isFinished) {
|
||||
_isFading = false;
|
||||
}
|
||||
});
|
||||
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::removeFromScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
|
|
|
@ -520,9 +520,7 @@ public:
|
|||
bool isMoving() const { return _moving; }
|
||||
|
||||
void fadeIn(render::ScenePointer scene);
|
||||
void fadeOut(render::ScenePointer scene, KillAvatarReason reason);
|
||||
bool isFading() const { return _isFading; }
|
||||
void updateFadingStatus();
|
||||
void fadeOut(render::Transaction& transaction, KillAvatarReason reason);
|
||||
|
||||
// JSDoc is in AvatarData.h.
|
||||
Q_INVOKABLE virtual float getEyeHeight() const override;
|
||||
|
@ -727,7 +725,6 @@ protected:
|
|||
bool _initialized { false };
|
||||
bool _isAnimatingScale { false };
|
||||
bool _mustFadeIn { false };
|
||||
bool _isFading { false };
|
||||
bool _reconstructSoftEntitiesJointMap { false };
|
||||
float _modelScale { 1.0f };
|
||||
|
||||
|
|
|
@ -439,7 +439,6 @@ void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason remo
|
|||
}
|
||||
|
||||
auto removedAvatar = _avatarHash.take(sessionUUID);
|
||||
|
||||
if (removedAvatar) {
|
||||
removedAvatars.push_back(removedAvatar);
|
||||
}
|
||||
|
|
|
@ -221,17 +221,15 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
|
|||
// remove all entities from the scene
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (scene) {
|
||||
render::Transaction transaction;
|
||||
for (const auto& entry : _entitiesInScene) {
|
||||
const auto& renderer = entry.second;
|
||||
const EntityItemPointer& entityItem = renderer->getEntity();
|
||||
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
|
||||
renderer->removeFromScene(scene, transaction);
|
||||
fadeOutRenderable(renderer);
|
||||
} else {
|
||||
savedEntities[entry.first] = entry.second;
|
||||
}
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
_renderablesToUpdate = savedEntities;
|
||||
|
@ -258,12 +256,10 @@ void EntityTreeRenderer::clear() {
|
|||
// remove all entities from the scene
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (scene) {
|
||||
render::Transaction transaction;
|
||||
for (const auto& entry : _entitiesInScene) {
|
||||
const auto& renderer = entry.second;
|
||||
renderer->removeFromScene(scene, transaction);
|
||||
fadeOutRenderable(renderer);
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else {
|
||||
qCWarning(entitiesrenderer) << "EntitityTreeRenderer::clear(), Unexpected null scene, possibly during application shutdown";
|
||||
}
|
||||
|
@ -1016,10 +1012,7 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
|
|||
|
||||
forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities
|
||||
|
||||
// here's where we remove the entity payload from the scene
|
||||
render::Transaction transaction;
|
||||
renderable->removeFromScene(scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
fadeOutRenderable(renderable);
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
|
||||
|
@ -1057,13 +1050,26 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::fadeOutRenderable(const EntityRendererPointer& renderable) {
|
||||
render::Transaction transaction;
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
|
||||
transaction.transitionFinishedOperator(renderable->getRenderItemID(), [scene, renderable]() {
|
||||
render::Transaction transaction;
|
||||
renderable->removeFromScene(scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
});
|
||||
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision) {
|
||||
assert((bool)entity);
|
||||
auto renderable = renderableForEntity(entity);
|
||||
if (!renderable) {
|
||||
return;
|
||||
if (!renderable) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SharedSoundPointer collisionSound = renderable->getCollisionSound();
|
||||
if (!collisionSound) {
|
||||
return;
|
||||
|
|
|
@ -93,6 +93,8 @@ public:
|
|||
/// reloads the entity scripts, calling unload and preload
|
||||
void reloadEntityScripts();
|
||||
|
||||
void fadeOutRenderable(const EntityRendererPointer& renderable);
|
||||
|
||||
// event handles which may generate entity related events
|
||||
QUuid mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
@ -255,6 +257,7 @@ private:
|
|||
std::unordered_map<EntityItemID, EntityRendererPointer> _renderablesToUpdate;
|
||||
std::unordered_map<EntityItemID, EntityRendererPointer> _entitiesInScene;
|
||||
std::unordered_map<EntityItemID, EntityItemWeakPointer> _entitiesToAdd;
|
||||
|
||||
// For Scene.shouldRenderEntities
|
||||
QList<EntityItemID> _entityIDsLastInScene;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ EntityRenderer::EntityRenderer(const EntityItemPointer& entity) : _created(entit
|
|||
});
|
||||
}
|
||||
|
||||
EntityRenderer::~EntityRenderer() { }
|
||||
EntityRenderer::~EntityRenderer() {}
|
||||
|
||||
//
|
||||
// Smart payload proxy members, implementing the payload interface
|
||||
|
@ -421,6 +421,7 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
|
|||
if (fading) {
|
||||
_isFading = Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f;
|
||||
}
|
||||
|
||||
_prevIsTransparent = transparent;
|
||||
|
||||
updateModelTransformAndBound();
|
||||
|
@ -493,4 +494,4 @@ glm::vec4 EntityRenderer::calculatePulseColor(const glm::vec4& color, const Puls
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,10 @@ void Transaction::queryTransitionOnItem(ItemID id, TransitionQueryFunc func) {
|
|||
_queriedTransitions.emplace_back(id, func);
|
||||
}
|
||||
|
||||
void Transaction::transitionFinishedOperator(ItemID id, TransitionFinishedFunc func) {
|
||||
_transitionFinishedOperators.emplace_back(id, func);
|
||||
}
|
||||
|
||||
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) {
|
||||
_updatedItems.emplace_back(id, functor);
|
||||
}
|
||||
|
@ -75,6 +79,7 @@ void Transaction::reserve(const std::vector<Transaction>& transactionContainer)
|
|||
size_t addedTransitionsCount = 0;
|
||||
size_t queriedTransitionsCount = 0;
|
||||
size_t reAppliedTransitionsCount = 0;
|
||||
size_t transitionFinishedOperatorsCount = 0;
|
||||
size_t highlightResetsCount = 0;
|
||||
size_t highlightRemovesCount = 0;
|
||||
size_t highlightQueriesCount = 0;
|
||||
|
@ -85,6 +90,7 @@ void Transaction::reserve(const std::vector<Transaction>& transactionContainer)
|
|||
updatedItemsCount += transaction._updatedItems.size();
|
||||
resetSelectionsCount += transaction._resetSelections.size();
|
||||
addedTransitionsCount += transaction._addedTransitions.size();
|
||||
transitionFinishedOperatorsCount += transaction._transitionFinishedOperators.size();
|
||||
queriedTransitionsCount += transaction._queriedTransitions.size();
|
||||
reAppliedTransitionsCount += transaction._reAppliedTransitions.size();
|
||||
highlightResetsCount += transaction._highlightResets.size();
|
||||
|
@ -99,6 +105,7 @@ void Transaction::reserve(const std::vector<Transaction>& transactionContainer)
|
|||
_addedTransitions.reserve(addedTransitionsCount);
|
||||
_queriedTransitions.reserve(queriedTransitionsCount);
|
||||
_reAppliedTransitions.reserve(reAppliedTransitionsCount);
|
||||
_transitionFinishedOperators.reserve(transitionFinishedOperatorsCount);
|
||||
_highlightResets.reserve(highlightResetsCount);
|
||||
_highlightRemoves.reserve(highlightRemovesCount);
|
||||
_highlightQueries.reserve(highlightQueriesCount);
|
||||
|
@ -142,6 +149,7 @@ void Transaction::merge(Transaction&& transaction) {
|
|||
moveElements(_resetSelections, transaction._resetSelections);
|
||||
moveElements(_addedTransitions, transaction._addedTransitions);
|
||||
moveElements(_queriedTransitions, transaction._queriedTransitions);
|
||||
moveElements(_transitionFinishedOperators, transaction._transitionFinishedOperators);
|
||||
moveElements(_reAppliedTransitions, transaction._reAppliedTransitions);
|
||||
moveElements(_highlightResets, transaction._highlightResets);
|
||||
moveElements(_highlightRemoves, transaction._highlightRemoves);
|
||||
|
@ -156,6 +164,7 @@ void Transaction::merge(const Transaction& transaction) {
|
|||
copyElements(_addedTransitions, transaction._addedTransitions);
|
||||
copyElements(_queriedTransitions, transaction._queriedTransitions);
|
||||
copyElements(_reAppliedTransitions, transaction._reAppliedTransitions);
|
||||
copyElements(_transitionFinishedOperators, transaction._transitionFinishedOperators);
|
||||
copyElements(_highlightResets, transaction._highlightResets);
|
||||
copyElements(_highlightRemoves, transaction._highlightRemoves);
|
||||
copyElements(_highlightQueries, transaction._highlightQueries);
|
||||
|
@ -168,6 +177,7 @@ void Transaction::clear() {
|
|||
_resetSelections.clear();
|
||||
_addedTransitions.clear();
|
||||
_queriedTransitions.clear();
|
||||
_transitionFinishedOperators.clear();
|
||||
_reAppliedTransitions.clear();
|
||||
_highlightResets.clear();
|
||||
_highlightRemoves.clear();
|
||||
|
@ -271,6 +281,7 @@ void Scene::processTransactionFrame(const Transaction& transaction) {
|
|||
transitionItems(transaction._addedTransitions);
|
||||
reApplyTransitions(transaction._reAppliedTransitions);
|
||||
queryTransitionItems(transaction._queriedTransitions);
|
||||
resetTransitionFinishedOperator(transaction._transitionFinishedOperators);
|
||||
|
||||
// Update the numItemsAtomic counter AFTER the pending changes went through
|
||||
_numAllocatedItems.exchange(maxID);
|
||||
|
@ -394,7 +405,7 @@ void Scene::transitionItems(const Transaction::TransitionAdds& transactions) {
|
|||
// Only remove if:
|
||||
// transitioning to something other than none or we're transitioning to none from ELEMENT_LEAVE_DOMAIN or USER_LEAVE_DOMAIN
|
||||
const auto& oldTransitionType = transitionStage->getTransition(transitionId).eventType;
|
||||
if (transitionType != Transition::NONE || !(oldTransitionType == Transition::ELEMENT_LEAVE_DOMAIN || oldTransitionType == Transition::USER_LEAVE_DOMAIN)) {
|
||||
if (transitionType != oldTransitionType) {
|
||||
resetItemTransition(itemId);
|
||||
}
|
||||
}
|
||||
|
@ -440,6 +451,23 @@ void Scene::queryTransitionItems(const Transaction::TransitionQueries& transacti
|
|||
}
|
||||
}
|
||||
|
||||
void Scene::resetTransitionFinishedOperator(const Transaction::TransitionFinishedOperators& operators) {
|
||||
for (auto& finishedOperator : operators) {
|
||||
auto itemId = std::get<0>(finishedOperator);
|
||||
const auto& item = _items[itemId];
|
||||
auto func = std::get<1>(finishedOperator);
|
||||
|
||||
if (item.exist() && func != nullptr) {
|
||||
TransitionStage::Index transitionId = item.getTransitionId();
|
||||
if (!TransitionStage::isIndexInvalid(transitionId)) {
|
||||
_transitionFinishedOperatorMap[transitionId].emplace_back(func);
|
||||
} else if (func) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::resetHighlights(const Transaction::HighlightResets& transactions) {
|
||||
auto outlineStage = getStage<HighlightStage>(HighlightStage::getName());
|
||||
if (outlineStage) {
|
||||
|
@ -526,9 +554,18 @@ void Scene::setItemTransition(ItemID itemId, Index transitionId) {
|
|||
|
||||
void Scene::resetItemTransition(ItemID itemId) {
|
||||
auto& item = _items[itemId];
|
||||
if (!render::TransitionStage::isIndexInvalid(item.getTransitionId())) {
|
||||
TransitionStage::Index transitionId = item.getTransitionId();
|
||||
if (!render::TransitionStage::isIndexInvalid(transitionId)) {
|
||||
auto transitionStage = getStage<TransitionStage>(TransitionStage::getName());
|
||||
transitionStage->removeTransition(item.getTransitionId());
|
||||
|
||||
auto finishedOperators = _transitionFinishedOperatorMap[transitionId];
|
||||
for (auto finishedOperator : finishedOperators) {
|
||||
if (finishedOperator) {
|
||||
finishedOperator();
|
||||
}
|
||||
}
|
||||
_transitionFinishedOperatorMap.erase(transitionId);
|
||||
transitionStage->removeTransition(transitionId);
|
||||
setItemTransition(itemId, render::TransitionStage::INVALID_INDEX);
|
||||
}
|
||||
}
|
||||
|
@ -587,4 +624,4 @@ void Scene::resetStage(const Stage::Name& name, const StagePointer& stage) {
|
|||
} else {
|
||||
(*found).second = stage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,15 @@ class Scene;
|
|||
// These changes must be expressed through the corresponding command from the Transaction
|
||||
// THe Transaction is then queued on the Scene so all the pending transactions can be consolidated and processed at the time
|
||||
// of updating the scene before it s rendered.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
class Transaction {
|
||||
friend class Scene;
|
||||
public:
|
||||
|
||||
typedef std::function<void(ItemID, const Transition*)> TransitionQueryFunc;
|
||||
typedef std::function<void()> TransitionFinishedFunc;
|
||||
typedef std::function<void(HighlightStyle const*)> SelectionHighlightQueryFunc;
|
||||
|
||||
Transaction() {}
|
||||
|
@ -52,6 +55,7 @@ public:
|
|||
void removeTransitionFromItem(ItemID id);
|
||||
void reApplyTransitionToItem(ItemID id);
|
||||
void queryTransitionOnItem(ItemID id, TransitionQueryFunc func);
|
||||
void transitionFinishedOperator(ItemID id, TransitionFinishedFunc func);
|
||||
|
||||
template <class T> void updateItem(ItemID id, std::function<void(T&)> func) {
|
||||
updateItem(id, std::make_shared<UpdateFunctor<T>>(func));
|
||||
|
@ -84,6 +88,7 @@ protected:
|
|||
using Update = std::tuple<ItemID, UpdateFunctorPointer>;
|
||||
using TransitionAdd = std::tuple<ItemID, Transition::Type, ItemID>;
|
||||
using TransitionQuery = std::tuple<ItemID, TransitionQueryFunc>;
|
||||
using TransitionFinishedOperator = std::tuple<ItemID, TransitionFinishedFunc>;
|
||||
using TransitionReApply = ItemID;
|
||||
using SelectionReset = Selection;
|
||||
using HighlightReset = std::tuple<std::string, HighlightStyle>;
|
||||
|
@ -95,6 +100,7 @@ protected:
|
|||
using Updates = std::vector<Update>;
|
||||
using TransitionAdds = std::vector<TransitionAdd>;
|
||||
using TransitionQueries = std::vector<TransitionQuery>;
|
||||
using TransitionFinishedOperators = std::vector<TransitionFinishedOperator>;
|
||||
using TransitionReApplies = std::vector<TransitionReApply>;
|
||||
using SelectionResets = std::vector<SelectionReset>;
|
||||
using HighlightResets = std::vector<HighlightReset>;
|
||||
|
@ -107,6 +113,7 @@ protected:
|
|||
TransitionAdds _addedTransitions;
|
||||
TransitionQueries _queriedTransitions;
|
||||
TransitionReApplies _reAppliedTransitions;
|
||||
TransitionFinishedOperators _transitionFinishedOperators;
|
||||
SelectionResets _resetSelections;
|
||||
HighlightResets _highlightResets;
|
||||
HighlightRemoves _highlightRemoves;
|
||||
|
@ -208,6 +215,7 @@ protected:
|
|||
ItemIDSet _masterNonspatialSet;
|
||||
|
||||
void resetItems(const Transaction::Resets& transactions);
|
||||
void resetTransitionFinishedOperator(const Transaction::TransitionFinishedOperators& transactions);
|
||||
void removeItems(const Transaction::Removes& transactions);
|
||||
void updateItems(const Transaction::Updates& transactions);
|
||||
void transitionItems(const Transaction::TransitionAdds& transactions);
|
||||
|
@ -223,6 +231,8 @@ protected:
|
|||
mutable std::mutex _selectionsMutex; // mutable so it can be used in the thread safe getSelection const method
|
||||
SelectionMap _selections;
|
||||
|
||||
std::unordered_map<int32_t, std::vector<Transaction::TransitionFinishedFunc>> _transitionFinishedOperatorMap;
|
||||
|
||||
void resetSelections(const Transaction::SelectionResets& transactions);
|
||||
// More actions coming to selections soon:
|
||||
// void removeFromSelection(const Selection& selection);
|
||||
|
|
|
@ -50,4 +50,4 @@ namespace render {
|
|||
typedef std::vector<Transition::Type> TransitionTypes;
|
||||
}
|
||||
|
||||
#endif // hifi_render_Transition_h
|
||||
#endif // hifi_render_Transition_h
|
||||
|
|
Loading…
Reference in a new issue