diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llavatarlist.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llavatarlist.h | 1 | ||||
-rw-r--r-- | indra/newview/llcallfloater.cpp | 52 | ||||
-rw-r--r-- | indra/newview/llcallfloater.h | 10 | ||||
-rw-r--r-- | indra/newview/llparticipantlist.cpp | 26 | ||||
-rw-r--r-- | indra/newview/llparticipantlist.h | 28 |
6 files changed, 93 insertions, 30 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 4ca8ebb284..02d13b4807 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 { @@ -200,6 +201,14 @@ void LLCallFloater::onChange() 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); + } } @@ -335,6 +344,7 @@ void LLCallFloater::refreshParticipantList() if (!non_avatar_caller) { 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) { @@ -459,7 +469,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(); @@ -572,13 +582,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 @@ -587,9 +607,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) @@ -709,4 +732,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 e22128e31f..0e942d7f95 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -188,6 +188,16 @@ 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; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 424843d432..ecce25dd18 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()) @@ -219,19 +222,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; } @@ -329,11 +327,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); } 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; }; |