commit
614a214870
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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;
|
||||
LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(item->getAvatarId());
|
||||
if (speaker.isNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
speaker->mHasLeftCurrentCall = TRUE;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -53,6 +56,13 @@ class LLParticipantList
|
|||
E_SORT_BY_RECENT_SPEAKERS = 1,
|
||||
} 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
|
||||
*/
|
||||
|
|
@ -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
|
||||
|
|
@ -217,14 +236,6 @@ class LLParticipantList
|
|||
void onAvatarListDoubleClicked(LLAvatarList* list);
|
||||
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.
|
||||
*
|
||||
|
|
@ -260,4 +271,5 @@ class LLParticipantList
|
|||
boost::signals2::connection mAvatarListReturnConnection;
|
||||
|
||||
LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
|
||||
validate_speaker_callback_t mValidateSpeakerCallback;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue