From c6e24e53a1041ab12b74469e335281f416af5b75 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Tue, 22 Dec 2009 14:45:49 +0200 Subject: Work on normal bug EXT-3434 There is no difference between invited and left participants in a Group call (Voice Controls) -- implemented removing of participant who has left voice chat from the list (after hardcoded 10 seconds) -- added struct params to be set from the xml --HG-- branch : product-engine --- indra/newview/llcallfloater.cpp | 109 ++++++++++++++++++++++++++++++++-------- indra/newview/llcallfloater.h | 63 +++++++++++++++++++++++ 2 files changed, 152 insertions(+), 20 deletions(-) diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 683cde7bee..33253c2781 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -79,6 +79,28 @@ static void* create_non_avatar_caller(void*) return new LLNonAvatarCaller; } +LLCallFloater::LLAvatarListItemRemoveTimer::LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id) +: LLEventTimer(period) +, mRemoveCallback(remove_cb) +, mSpeakerId(speaker_id) +{ +} + +BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick() +{ + if (mRemoveCallback) + { + mRemoveCallback(mSpeakerId); + } + return TRUE; +} + + +LLCallFloater::Params::Params() +: voice_left_remove_delay("voice_left_remove_delay", 10) +{ +} + LLCallFloater::LLCallFloater(const LLSD& key) : LLDockableFloater(NULL, false, key) , mSpeakerManager(NULL) @@ -90,6 +112,7 @@ LLCallFloater::LLCallFloater(const LLSD& key) , mSpeakingIndicator(NULL) , mIsModeratorMutedVoice(false) , mInitParticipantsVoiceState(false) +, mVoiceLeftRemoveDelay(10) // TODO: mantipov: make xml driven { mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); LLVoiceClient::getInstance()->addObserver(this); @@ -98,6 +121,8 @@ LLCallFloater::LLCallFloater(const LLSD& key) LLCallFloater::~LLCallFloater() { + resetVoiceRemoveTimers(); + delete mPaticipants; mPaticipants = NULL; @@ -268,6 +293,8 @@ void LLCallFloater::updateSession() void LLCallFloater::refreshPartisipantList() { + resetVoiceRemoveTimers(); + delete mPaticipants; mPaticipants = NULL; mAvatarList->clear(); @@ -542,26 +569,6 @@ void LLCallFloater::updateParticipantsVoiceState() { setState(item, STATE_INVITED); } - -/* - // If there is already a started timer for the current panel don't do anything. - bool no_timer_for_current_panel = true; - if (mTimersMap.size() > 0) - { - timers_map::iterator found_it = mTimersMap.find(participant_id); - if (found_it != mTimersMap.end()) - { - no_timer_for_current_panel = false; - } - } - - if (no_timer_for_current_panel) - { - // Starting a timer to remove an avatar row panel after timeout - // *TODO Make the timeout period adjustable - mTimersMap.insert(timer_pair(participant_id, new LLAvatarRowRemoveTimer(this->getHandle(), 10, participant_id))); - } -*/ } } @@ -580,10 +587,12 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state) new_desc.setStyle(LLFontGL::NORMAL); break; case STATE_JOINED: + removeVoiceRemoveTimer(item->getAvatarId()); new_desc.setStyle(LLFontGL::NORMAL); break; case STATE_LEFT: { + setVoiceRemoveTimer(item->getAvatarId()); new_desc.setStyle(LLFontGL::ITALIC); } break; @@ -603,4 +612,64 @@ void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state) } } +void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id) +{ + + // If there is already a started timer for the current panel don't do anything. + bool no_timer_for_current_panel = true; + if (mVoiceLeftTimersMap.size() > 0) + { + timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id); + if (found_it != mVoiceLeftTimersMap.end()) + { + no_timer_for_current_panel = false; + } + } + + if (no_timer_for_current_panel) + { + // Starting a timer to remove an avatar row panel after timeout + mVoiceLeftTimersMap.insert(timer_pair(voice_speaker_id, + new LLAvatarListItemRemoveTimer(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), mVoiceLeftRemoveDelay, voice_speaker_id))); + } +} + +void LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id) +{ + if (mVoiceLeftTimersMap.size() > 0) + { + mVoiceLeftTimersMap.erase(mVoiceLeftTimersMap.find(voice_speaker_id)); + } + + mAvatarList->removeItemByUUID(voice_speaker_id); +} + + +void LLCallFloater::resetVoiceRemoveTimers() +{ + if (mVoiceLeftTimersMap.size() > 0) + { + for (timers_map::iterator iter = mVoiceLeftTimersMap.begin(); + iter != mVoiceLeftTimersMap.end(); ++iter) + { + delete iter->second; + } + } + mVoiceLeftTimersMap.clear(); +} + +void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id) +{ + // Remove the timer if it has been already started + if (mVoiceLeftTimersMap.size() > 0) + { + timers_map::iterator found_it = mVoiceLeftTimersMap.find(voice_speaker_id); + if (found_it != mVoiceLeftTimersMap.end()) + { + delete found_it->second; + mVoiceLeftTimersMap.erase(found_it); + } + } +} + //EOF diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 1e64066647..537c57f671 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -57,6 +57,15 @@ class LLSpeakerMgr; class LLCallFloater : public LLDockableFloater, LLVoiceClientParticipantObserver { public: + struct Params : public LLInitParam::Block + { + Optional voice_left_remove_delay; + + Params(); + }; + + LOG_CLASS(LLCallFloater); + LLCallFloater(const LLSD& key); ~LLCallFloater(); @@ -151,6 +160,34 @@ private: return mSpeakerStateMap[speaker_id]; } + + /** + * Instantiates new LLAvatarListItemRemoveTimer and adds it into the map if it is not already created. + * + * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list when timer expires. + */ + void setVoiceRemoveTimer(const LLUUID& voice_speaker_id); + + /** + * Removes specified by UUID Avatar List item. + * + * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list. + */ + void removeVoiceLeftParticipant(const LLUUID& voice_speaker_id); + + /** + * Deletes all timers from the list to prevent started timers from ticking after destruction + * and after switching on another voice channel. + */ + void resetVoiceRemoveTimers(); + + /** + * Removes specified by UUID timer from the map. + * + * @param voice_speaker_id LLUUID of Avatar List item whose timer should be removed from the map. + */ + void removeVoiceRemoveTimer(const LLUUID& voice_speaker_id); + private: speaker_state_map_t mSpeakerStateMap; LLSpeakerMgr* mSpeakerManager; @@ -175,6 +212,32 @@ private: boost::signals2::connection mAvatarListRefreshConnection; + /** + * class LLAvatarListItemRemoveTimer + * + * Implements a timer that removes avatar list item of a participant + * who has left the call. + */ + class LLAvatarListItemRemoveTimer : public LLEventTimer + { + public: + typedef boost::function callback_t; + + LLAvatarListItemRemoveTimer(callback_t remove_cb, F32 period, const LLUUID& speaker_id); + virtual ~LLAvatarListItemRemoveTimer() {}; + + virtual BOOL tick(); + + private: + callback_t mRemoveCallback; + LLUUID mSpeakerId; + }; + + typedef std::pair timer_pair; + typedef std::map timers_map; + + timers_map mVoiceLeftTimersMap; + S32 mVoiceLeftRemoveDelay; }; -- cgit v1.2.3