diff options
author | Vadim Savchuk <vsavchuk@productengine.com> | 2009-12-25 20:47:42 +0200 |
---|---|---|
committer | Vadim Savchuk <vsavchuk@productengine.com> | 2009-12-25 20:47:42 +0200 |
commit | 614a214870e223ea187bda32169a1859380844d3 (patch) | |
tree | 6b60aa4b128aaf74cdeeba368b166d899506a087 | |
parent | 87aad0fe2177ab863704e5432435a0657277fb92 (diff) | |
parent | 38742b462a222cf97d67b2f2e866d225a4000c1d (diff) |
merge
--HG--
branch : product-engine
-rw-r--r-- | indra/newview/llavatarlist.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llavatarlist.h | 1 | ||||
-rw-r--r-- | indra/newview/llcallfloater.cpp | 74 | ||||
-rw-r--r-- | indra/newview/llcallfloater.h | 16 | ||||
-rw-r--r-- | indra/newview/llparticipantlist.cpp | 28 | ||||
-rw-r--r-- | indra/newview/llparticipantlist.h | 28 |
6 files changed, 108 insertions, 45 deletions
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 5317cf2cd0..b3ef6464f6 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -51,6 +51,12 @@ static const F32 LIT_UPDATE_PERIOD = 5; // Used to limit time spent for avatar list update per frame. static const unsigned ADD_LIMIT = 50; +bool LLAvatarList::contains(const LLUUID& id) +{ + const uuid_vector_t& ids = getIDs(); + return std::find(ids.begin(), ids.end(), id) != ids.end(); +} + void LLAvatarList::toggleIcons() { // Save the new value for new items to use. diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index e913be0f62..0d2ce884ae 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -75,6 +75,7 @@ public: void setNameFilter(const std::string& filter); void setDirty(bool val = true) { mDirty = val; } uuid_vector_t& getIDs() { return mIDs; } + bool contains(const LLUUID& id); void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; } diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 1c65eaba9c..581890c4fd 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -48,6 +48,7 @@ #include "llspeakers.h" #include "lltransientfloatermgr.h" +static void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids); class LLNonAvatarCaller : public LLAvatarListItem { @@ -98,7 +99,7 @@ BOOL LLCallFloater::LLAvatarListItemRemoveTimer::tick() LLCallFloater::LLCallFloater(const LLSD& key) : LLDockableFloater(NULL, false, key) , mSpeakerManager(NULL) -, mPaticipants(NULL) +, mParticipants(NULL) , mAvatarList(NULL) , mNonAvatarCaller(NULL) , mVoiceType(VC_LOCAL_CHAT) @@ -120,8 +121,8 @@ LLCallFloater::~LLCallFloater() { resetVoiceRemoveTimers(); - delete mPaticipants; - mPaticipants = NULL; + delete mParticipants; + mParticipants = NULL; mAvatarListRefreshConnection.disconnect(); @@ -185,8 +186,8 @@ void LLCallFloater::draw() } // Need to resort the participant list if it's in sort by recent speaker order. - if (mPaticipants) - mPaticipants->updateRecentSpeakersOrder(); + if (mParticipants) + mParticipants->updateRecentSpeakersOrder(); LLDockableFloater::draw(); } @@ -194,9 +195,17 @@ void LLCallFloater::draw() // virtual void LLCallFloater::onChange() { - if (NULL == mPaticipants) return; + if (NULL == mParticipants) return; updateParticipantsVoiceState(); + + // Add newly joined participants. + std::vector<LLUUID> speakers_uuids; + get_voice_participants_uuids(speakers_uuids); + for (std::vector<LLUUID>::const_iterator it = speakers_uuids.begin(); it != speakers_uuids.end(); it++) + { + mParticipants->addAvatarIDExceptAgent(*it); + } } @@ -277,7 +286,7 @@ void LLCallFloater::updateSession() bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; childSetVisible("leave_call_btn", !is_local_chat); - refreshPartisipantList(); + refreshParticipantList(); updateAgentModeratorState(); //show floater for voice calls @@ -292,7 +301,7 @@ void LLCallFloater::updateSession() } } -void LLCallFloater::refreshPartisipantList() +void LLCallFloater::refreshParticipantList() { // lets forget states from the previous session // for timers... @@ -301,8 +310,8 @@ void LLCallFloater::refreshPartisipantList() // ...and for speaker state mSpeakerStateMap.clear(); - delete mPaticipants; - mPaticipants = NULL; + delete mParticipants; + mParticipants = NULL; mAvatarList->clear(); bool non_avatar_caller = false; @@ -322,7 +331,8 @@ void LLCallFloater::refreshPartisipantList() if (!non_avatar_caller) { - mPaticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT); + mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT); + mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1)); if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager) { @@ -447,7 +457,7 @@ void LLCallFloater::updateAgentModeratorState() mAgentPanel->childSetValue("user_text", name); } -void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids) +static void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids) { // Get a list of participants from VoiceClient LLVoiceClient::participantMap *voice_map = gVoiceClient->getParticipantList(); @@ -560,13 +570,23 @@ void LLCallFloater::updateParticipantsVoiceState() // HAS LEFT the call. if ((getState(participant_id) == STATE_JOINED)) { - setState(item, STATE_LEFT); - - LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(item->getAvatarId()); - if (speaker.isNull()) - continue; - - speaker->mHasLeftCurrentCall = TRUE; + if (mVoiceType == VC_LOCAL_CHAT) + { + // Don't display avatars that aren't in our nearby chat range anymore as "left". Remove them immediately. + removeVoiceLeftParticipant(participant_id); + } + else + { + setState(item, STATE_LEFT); + + LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(item->getAvatarId()); + if (speaker.isNull()) + { + continue; + } + + speaker->mHasLeftCurrentCall = TRUE; + } } // If an avatarID is not found in a speakers list from VoiceClient and // a panel with this ID has a LEFT status this means that this person @@ -575,9 +595,12 @@ void LLCallFloater::updateParticipantsVoiceState() { setState(item, STATE_INVITED); } + else + { + llwarns << "Unsupported (" << getState(participant_id) << ") state: " << item->getAvatarName() << llendl; + } } } - } void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state) @@ -684,4 +707,15 @@ void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id) } } +bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id) +{ + if (mVoiceType != VC_LOCAL_CHAT) + return true; + + // A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice). + std::vector<LLUUID> speakers; + get_voice_participants_uuids(speakers); + return std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end(); +} + //EOF diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index ee3bc9b9fe..3df9e333c5 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -108,7 +108,7 @@ private: /** * Refreshes participant list according to current Voice Channel */ - void refreshPartisipantList(); + void refreshParticipantList(); /** * Handles event on avatar list is refreshed after it was marked dirty. @@ -127,7 +127,7 @@ private: /** * Sets initial participants voice states in avatar list (Invited, Joined, Has Left). * - * @see refreshPartisipantList() + * @see refreshParticipantList() * @see onAvatarListRefreshed() * @see mInitParticipantsVoiceState */ @@ -182,10 +182,20 @@ private: */ void removeVoiceRemoveTimer(const LLUUID& voice_speaker_id); + /** + * Called by LLParticipantList before adding a speaker to the participant list. + * + * If false is returned, the speaker will not be added to the list. + * + * @param speaker_id Speaker to validate. + * @return true if this is a valid speaker, false otherwise. + */ + bool validateSpeaker(const LLUUID& speaker_id); + private: speaker_state_map_t mSpeakerStateMap; LLSpeakerMgr* mSpeakerManager; - LLParticipantList* mPaticipants; + LLParticipantList* mParticipants; LLAvatarList* mAvatarList; LLNonAvatarCaller* mNonAvatarCaller; EVoiceControls mVoiceType; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 54a837d17d..479c29f656 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -57,6 +57,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av mSortOrder(E_SORT_BY_NAME) , mParticipantListMenu(NULL) , mExcludeAgent(exclude_agent) +, mValidateSpeakerCallback(NULL) { mSpeakerAddListener = new SpeakerAddListener(*this); mSpeakerRemoveListener = new SpeakerRemoveListener(*this); @@ -86,22 +87,19 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* av } //Lets fill avatarList with existing speakers - LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); - LLSpeakerMgr::speaker_list_t speaker_list; mSpeakerMgr->getSpeakerList(&speaker_list, true); for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) { const LLPointer<LLSpeaker>& speakerp = *it; - addAvatarIDExceptAgent(group_members, speakerp->mID); + addAvatarIDExceptAgent(speakerp->mID); if ( speakerp->mIsModerator ) { mModeratorList.insert(speakerp->mID); } } // we need to exclude agent id for non group chat - mAvatarList->setDirty(true); sort(); } @@ -208,6 +206,11 @@ LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder() return mSortOrder; } +void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb) +{ + mValidateSpeakerCallback = cb; +} + void LLParticipantList::updateRecentSpeakersOrder() { if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder()) @@ -221,19 +224,14 @@ void LLParticipantList::updateRecentSpeakersOrder() bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { - LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); LLUUID uu_id = event->getValue().asUUID(); - LLAvatarList::uuid_vector_t::iterator found = std::find(group_members.begin(), group_members.end(), uu_id); - if(found != group_members.end()) + if (mValidateSpeakerCallback && mValidateSpeakerCallback(uu_id)) { - llinfos << "Already got a buddy" << llendl; return true; } - addAvatarIDExceptAgent(group_members, uu_id); - // Mark AvatarList as dirty one - mAvatarList->setDirty(); + addAvatarIDExceptAgent(uu_id); sort(); return true; } @@ -331,11 +329,13 @@ void LLParticipantList::sort() } } -void LLParticipantList::addAvatarIDExceptAgent(std::vector<LLUUID>& existing_list, const LLUUID& avatar_id) +void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) { if (mExcludeAgent && gAgent.getID() == avatar_id) return; + if (mAvatarList->contains(avatar_id)) return; - existing_list.push_back(avatar_id); + mAvatarList->getIDs().push_back(avatar_id); + mAvatarList->setDirty(); adjustParticipant(avatar_id); } @@ -355,7 +355,7 @@ bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::L { /** * We need to filter speaking objects. These objects shouldn't appear in the list - * @c LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy + * @see LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy */ const LLUUID& speaker_id = event->getValue().asUUID(); LLPointer<LLSpeaker> speaker = mParent.mSpeakerMgr->findSpeaker(speaker_id); diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index c4eb180917..d15ec980db 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -44,6 +44,9 @@ class LLParticipantList { LOG_CLASS(LLParticipantList); public: + + typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t; + LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list, bool use_context_menu = true, bool exclude_agent = true); ~LLParticipantList(); void setSpeakingIndicatorsVisible(BOOL visible); @@ -54,6 +57,13 @@ class LLParticipantList } EParticipantSortOrder; /** + * Adds specified avatar ID to the existing list if it is not Agent's ID + * + * @param[in] avatar_id - Avatar UUID to be added into the list + */ + void addAvatarIDExceptAgent(const LLUUID& avatar_id); + + /** * Set and sort Avatarlist by given order */ void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME); @@ -64,6 +74,15 @@ class LLParticipantList */ void updateRecentSpeakersOrder(); + /** + * Set a callback to be called before adding a speaker. Invalid speakers will not be added. + * + * If the callback is unset all speakers are considered as valid. + * + * @see onAddItemEvent() + */ + void setValidateSpeakerCallback(validate_speaker_callback_t cb); + protected: /** * LLSpeakerMgr event handlers @@ -218,14 +237,6 @@ class LLParticipantList void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param); /** - * Adds specified avatar ID to the existing list if it is not Agent's ID - * - * @param[in, out] existing_list - vector with avatars' UUIDs already in the list - * @param[in] avatar_id - Avatar UUID to be added into the list - */ - void addAvatarIDExceptAgent(std::vector<LLUUID>& existing_list, const LLUUID& avatar_id); - - /** * Adjusts passed participant to work properly. * * Adds SpeakerMuteListener to process moderation actions. @@ -260,4 +271,5 @@ class LLParticipantList boost::signals2::connection mAvatarListReturnConnection; LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers; + validate_speaker_callback_t mValidateSpeakerCallback; }; |