summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalad Dais <SaladDais@users.noreply.github.com>2023-11-09 15:41:08 +0000
committerAndrey Lihatskiy <alihatskiy@productengine.com>2023-11-09 23:10:39 +0200
commitdd694f0add587b8117c824a2bb4d6dc525c27304 (patch)
tree77998e7d5f21581fdc06c54ae67fe342b1f0e43f
parent4d4abdd76971d7b4b128d8e7a3cf6eebe0861d79 (diff)
Fix BUG-225288: Detaching stops unrelated animations
This is to do with misunderstandings related to how .find() works with multimaps. .find() will, in fact, return an iterator to the first iterator it finds, and will iterate through all elements in the multimap when incremented, not just items with the same key. Change code working with animation sources to be aware of this fact, so unrelated animation sources do not have their animations stopped.
-rw-r--r--indra/newview/llviewermessage.cpp6
-rw-r--r--indra/newview/llvoavatarself.cpp6
2 files changed, 11 insertions, 1 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index f3288a5300..7b91e4806f 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4152,6 +4152,12 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
{
+ if (anim_it->first != object_id)
+ {
+ // elements with the same key are always contiguous, bail if we went past the
+ // end of this object's animations
+ break;
+ }
if (anim_it->second == animation_id)
{
anim_found = TRUE;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 8fc1dcd81f..ea9bd248b1 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -834,7 +834,11 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
{
gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
- mAnimationSources.erase(motion_it++);
+ mAnimationSources.erase(motion_it);
+ // Must find() after each erase() to deal with potential iterator invalidation
+ // This also ensures that we don't go past the end of this source's animations
+ // into those of another source.
+ motion_it = mAnimationSources.find(source_id);
}