summaryrefslogtreecommitdiff
path: root/indra/newview/llviewermessage.cpp
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2018-06-19 19:02:12 +0300
committerandreykproductengine <andreykproductengine@lindenlab.com>2018-06-19 19:02:12 +0300
commit48f1c0099dd9ba52a0ce9a36a61d3f52d1ab66d5 (patch)
tree5a4a4b85ec534522a2c2ff2ed4042501a7543865 /indra/newview/llviewermessage.cpp
parentd4faf1a50b467e373f827c65273a18b84e165d97 (diff)
MAINT-4743 Save sounds that arrived too early and use on object update
Diffstat (limited to 'indra/newview/llviewermessage.cpp')
-rw-r--r--indra/newview/llviewermessage.cpp150
1 files changed, 134 insertions, 16 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 4180da17c2..6cba7dd70c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3372,6 +3372,110 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
}
+// sounds can arrive before objects, store them for a short time
+// Note: this is a workaround for MAINT-4743, real fix would be to make
+// server send sound along with object update that creates (rezes) the object
+class PostponedSoundData
+{
+public:
+ PostponedSoundData() :
+ mExpirationTime(0)
+ {}
+ PostponedSoundData(const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags);
+ bool hasExpired() { return LLFrameTimer::getTotalSeconds() > mExpirationTime; }
+
+ LLUUID mObjectId;
+ LLUUID mSoundId;
+ LLUUID mOwnerId;
+ F32 mGain;
+ U8 mFlags;
+ static const F64 MAXIMUM_PLAY_DELAY;
+
+private:
+ F64 mExpirationTime; //seconds since epoch
+};
+const F64 PostponedSoundData::MAXIMUM_PLAY_DELAY = 15.0;
+static F64 postponed_sounds_update_expiration = 0.0;
+static std::map<LLUUID, PostponedSoundData> postponed_sounds;
+
+void set_attached_sound(LLViewerObject *objectp, const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags)
+{
+ if (LLMuteList::getInstance()->isMuted(object_id)) return;
+
+ if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
+
+ // Don't play sounds from a region with maturity above current agent maturity
+ LLVector3d pos = objectp->getPositionGlobal();
+ if (!gAgent.canAccessMaturityAtGlobal(pos))
+ {
+ return;
+ }
+
+ objectp->setAttachedSound(sound_id, owner_id, gain, flags);
+}
+
+PostponedSoundData::PostponedSoundData(const LLUUID &object_id, const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const U8 flags)
+ :
+ mObjectId(object_id),
+ mSoundId(sound_id),
+ mOwnerId(owner_id),
+ mGain(gain),
+ mFlags(flags),
+ mExpirationTime(LLFrameTimer::getTotalSeconds() + MAXIMUM_PLAY_DELAY)
+{
+}
+
+// static
+void update_attached_sounds()
+{
+ if (postponed_sounds.empty())
+ {
+ return;
+ }
+
+ std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.begin();
+ std::map<LLUUID, PostponedSoundData>::iterator end = postponed_sounds.end();
+ while (iter != end)
+ {
+ std::map<LLUUID, PostponedSoundData>::iterator cur_iter = iter++;
+ PostponedSoundData* data = &cur_iter->second;
+ if (data->hasExpired())
+ {
+ postponed_sounds.erase(cur_iter);
+ }
+ else
+ {
+ LLViewerObject *objectp = gObjectList.findObject(data->mObjectId);
+ if (objectp)
+ {
+ set_attached_sound(objectp, data->mObjectId, data->mSoundId, data->mOwnerId, data->mGain, data->mFlags);
+ postponed_sounds.erase(cur_iter);
+ }
+ }
+ }
+ postponed_sounds_update_expiration = LLFrameTimer::getTotalSeconds() + 2 * PostponedSoundData::MAXIMUM_PLAY_DELAY;
+}
+
+//static
+void clear_expired_postponed_sounds()
+{
+ if (postponed_sounds_update_expiration > LLFrameTimer::getTotalSeconds())
+ {
+ return;
+ }
+ std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.begin();
+ std::map<LLUUID, PostponedSoundData>::iterator end = postponed_sounds.end();
+ while (iter != end)
+ {
+ std::map<LLUUID, PostponedSoundData>::iterator cur_iter = iter++;
+ PostponedSoundData* data = &cur_iter->second;
+ if (data->hasExpired())
+ {
+ postponed_sounds.erase(cur_iter);
+ }
+ }
+ postponed_sounds_update_expiration = LLFrameTimer::getTotalSeconds() + 2 * PostponedSoundData::MAXIMUM_PLAY_DELAY;
+}
// *TODO: Remove this dependency, or figure out a better way to handle
// this hack.
@@ -3390,7 +3494,12 @@ void process_object_update(LLMessageSystem *mesgsys, void **user_data)
}
// Update the object...
+ S32 old_num_objects = gObjectList.mNumNewObjects;
gObjectList.processObjectUpdate(mesgsys, user_data, OUT_FULL);
+ if (old_num_objects != gObjectList.mNumNewObjects)
+ {
+ update_attached_sounds();
+ }
}
void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
@@ -3406,7 +3515,12 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data
}
// Update the object...
+ S32 old_num_objects = gObjectList.mNumNewObjects;
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_FULL_COMPRESSED);
+ if (old_num_objects != gObjectList.mNumNewObjects)
+ {
+ update_attached_sounds();
+ }
}
void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
@@ -3437,7 +3551,12 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
gObjectData += (U32Bytes)mesgsys->getReceiveSize();
}
+ S32 old_num_objects = gObjectList.mNumNewObjects;
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
+ if (old_num_objects != gObjectList.mNumNewObjects)
+ {
+ update_attached_sounds();
+ }
}
static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Kill Objects");
@@ -3659,28 +3778,27 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
LLViewerObject *objectp = gObjectList.findObject(object_id);
- if (!objectp)
+ if (objectp)
{
- // we don't know about this object, just bail
- return;
+ set_attached_sound(objectp, object_id, sound_id, owner_id, gain, flags);
}
-
- if (LLMuteList::getInstance()->isMuted(object_id)) return;
-
- if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
-
-
- // Don't play sounds from a region with maturity above current agent maturity
- LLVector3d pos = objectp->getPositionGlobal();
- if( !gAgent.canAccessMaturityAtGlobal(pos) )
+ else if (sound_id.notNull())
{
- return;
+ // we don't know about this object yet, probably it has yet to arrive
+ // std::map for dupplicate prevention.
+ postponed_sounds[object_id] = (PostponedSoundData(object_id, sound_id, owner_id, gain, flags));
+ clear_expired_postponed_sounds();
+ }
+ else
+ {
+ std::map<LLUUID, PostponedSoundData>::iterator iter = postponed_sounds.find(object_id);
+ if (iter != postponed_sounds.end())
+ {
+ postponed_sounds.erase(iter);
+ }
}
-
- objectp->setAttachedSound(sound_id, owner_id, gain, flags);
}
-
void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_data)
{
F32 gain = 0;