--HG--
branch : product-engine
meow-7.2.2
Vadim Savchuk 2009-12-25 20:47:42 +02:00
commit 614a214870
6 changed files with 106 additions and 43 deletions

View File

@ -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.

View File

@ -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; }

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
};