Add bulk speaker updates. Sped up speaker fetching by disabling list sorting during bulk updates.
This commit is contained in:
@@ -125,6 +125,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
|
||||
mNeedsScroll(false),
|
||||
mCanSelect(true),
|
||||
mColumnsDirty(false),
|
||||
mSortEnabled(true),
|
||||
mMaxItemCount(INT_MAX),
|
||||
mMaxContentWidth(0),
|
||||
mBorderThickness( 2 ),
|
||||
@@ -2301,6 +2302,16 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
|
||||
}
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::setSortEnabled(bool sort)
|
||||
{
|
||||
bool update = sort && !mSortEnabled;
|
||||
mSortEnabled = sort;
|
||||
if (update)
|
||||
{
|
||||
updateSort();
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLScrollListCtrl::getLinesPerPage()
|
||||
{
|
||||
//if mPageLines is NOT provided display all item
|
||||
@@ -2942,7 +2953,7 @@ std::string LLScrollListCtrl::getSortColumnName()
|
||||
|
||||
BOOL LLScrollListCtrl::hasSortOrder() const
|
||||
{
|
||||
return !mSortColumns.empty();
|
||||
return mSortEnabled && !mSortColumns.empty();
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::clearSortOrder()
|
||||
|
||||
@@ -322,6 +322,7 @@ public:
|
||||
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
|
||||
BOOL hasSortOrder() const;
|
||||
void clearSortOrder();
|
||||
void setSortEnabled(bool sort);
|
||||
|
||||
template<typename T> S32 selectMultiple(const std::vector<T>& vec)
|
||||
{
|
||||
@@ -423,6 +424,7 @@ private:
|
||||
bool mDisplayColumnHeaders;
|
||||
bool mColumnsDirty;
|
||||
bool mColumnWidthsDirty;
|
||||
bool mSortEnabled;
|
||||
|
||||
mutable item_list mItemList;
|
||||
|
||||
|
||||
@@ -58,10 +58,13 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
|
||||
mSpeakerClearListener = new SpeakerClearListener(*this);
|
||||
//mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
|
||||
mSpeakerMuteListener = new SpeakerMuteListener(*this);
|
||||
|
||||
mSpeakerBatchBeginListener = new SpeakerBatchBeginListener(*this);
|
||||
mSpeakerBatchEndListener = new SpeakerBatchEndListener(*this);
|
||||
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
|
||||
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
|
||||
mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
|
||||
mSpeakerMgr->addListener(mSpeakerBatchBeginListener, "batch_begin");
|
||||
mSpeakerMgr->addListener(mSpeakerBatchEndListener, "batch_end");
|
||||
//mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
|
||||
}
|
||||
|
||||
@@ -378,6 +381,16 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLParticipantList::onSpeakerBatchBeginEvent()
|
||||
{
|
||||
mAvatarList->setSortEnabled(false);
|
||||
}
|
||||
|
||||
void LLParticipantList::onSpeakerBatchEndEvent()
|
||||
{
|
||||
mAvatarList->setSortEnabled(true);
|
||||
}
|
||||
|
||||
void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
|
||||
{
|
||||
//if (mExcludeAgent && gAgent.getID() == avatar_id) return;
|
||||
@@ -468,6 +481,17 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
|
||||
return mParent.onSpeakerMuteEvent(event, userdata);
|
||||
}
|
||||
|
||||
bool LLParticipantList::SpeakerBatchBeginListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
mParent.onSpeakerBatchBeginEvent();
|
||||
return true;
|
||||
}
|
||||
bool LLParticipantList::SpeakerBatchEndListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
mParent.onSpeakerBatchEndEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Singu Note: The following functions are actually of the LLParticipantListMenu class, but we haven't married lists with menus yet.
|
||||
void LLParticipantList::toggleAllowTextChat(const LLSD& userdata)
|
||||
{
|
||||
|
||||
@@ -76,6 +76,8 @@ protected:
|
||||
bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||
//bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||
bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||
void onSpeakerBatchBeginEvent();
|
||||
void onSpeakerBatchEndEvent();
|
||||
|
||||
/**
|
||||
* List of listeners implementing LLOldEvents::LLSimpleListener.
|
||||
@@ -126,6 +128,20 @@ protected:
|
||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||
};
|
||||
|
||||
class SpeakerBatchBeginListener : public BaseSpeakerListener
|
||||
{
|
||||
public:
|
||||
SpeakerBatchBeginListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||
};
|
||||
|
||||
class SpeakerBatchEndListener : public BaseSpeakerListener
|
||||
{
|
||||
public:
|
||||
SpeakerBatchEndListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||
};
|
||||
|
||||
/**
|
||||
* Menu used in the participant list.
|
||||
class LLParticipantListMenu : public LLListContextMenu
|
||||
@@ -202,6 +218,8 @@ private:
|
||||
LLPointer<SpeakerClearListener> mSpeakerClearListener;
|
||||
//LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener;
|
||||
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
|
||||
LLPointer<SpeakerBatchBeginListener> mSpeakerBatchBeginListener;
|
||||
LLPointer<SpeakerBatchEndListener> mSpeakerBatchEndListener;
|
||||
|
||||
validate_speaker_callback_t mValidateSpeakerCallback;
|
||||
};
|
||||
|
||||
@@ -338,7 +338,20 @@ LLSpeakerMgr::~LLSpeakerMgr()
|
||||
delete mSpeakerDelayRemover;
|
||||
}
|
||||
|
||||
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
|
||||
void LLSpeakerMgr::setSpeakers(const std::vector<LLSpeakerMgr::speaker_entry_t>& speakers)
|
||||
{
|
||||
if (!speakers.empty())
|
||||
{
|
||||
fireEvent(new LLOldEvents::LLEvent(this), "batch_begin");
|
||||
for (auto entry : speakers)
|
||||
{
|
||||
setSpeaker(entry.id, entry.name, entry.status, entry.type, entry.moderator, entry.moderator_muted_text);
|
||||
}
|
||||
fireEvent(new LLOldEvents::LLEvent(this), "batch_end");
|
||||
}
|
||||
}
|
||||
|
||||
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type, bool moderator, bool moderator_muted_text)
|
||||
{
|
||||
LLUUID session_id = getSessionID();
|
||||
if (id.isNull() || (id == session_id))
|
||||
@@ -347,34 +360,37 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
|
||||
}
|
||||
|
||||
LLPointer<LLSpeaker> speakerp;
|
||||
if (mSpeakers.find(id) == mSpeakers.end())
|
||||
auto it = mSpeakers.find(id);
|
||||
if (it == mSpeakers.end() || it->second.isNull())
|
||||
{
|
||||
speakerp = new LLSpeaker(id, name, type);
|
||||
speakerp->mStatus = status;
|
||||
speakerp->mIsModerator = moderator;
|
||||
speakerp->mModeratorMutedText = moderator_muted_text;
|
||||
mSpeakers.insert(std::make_pair(speakerp->mID, speakerp));
|
||||
mSpeakersSorted.push_back(speakerp);
|
||||
LL_DEBUGS("Speakers") << "Added speaker " << id << LL_ENDL;
|
||||
fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "add");
|
||||
}
|
||||
else
|
||||
{
|
||||
speakerp = findSpeaker(id);
|
||||
if (speakerp.notNull())
|
||||
speakerp = it->second;
|
||||
bool update_moderator = (bool)speakerp->mIsModerator != moderator;
|
||||
|
||||
// keep highest priority status (lowest value) instead of overriding current value
|
||||
speakerp->mStatus = llmin(speakerp->mStatus, status);
|
||||
speakerp->mIsModerator = moderator;
|
||||
speakerp->mModeratorMutedText = moderator_muted_text;
|
||||
// RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
|
||||
// we need to override speakers that we think are objects when we find out they are really
|
||||
// residents
|
||||
if (type == LLSpeaker::SPEAKER_AGENT)
|
||||
{
|
||||
// keep highest priority status (lowest value) instead of overriding current value
|
||||
speakerp->mStatus = llmin(speakerp->mStatus, status);
|
||||
// RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
|
||||
// we need to override speakers that we think are objects when we find out they are really
|
||||
// residents
|
||||
if (type == LLSpeaker::SPEAKER_AGENT)
|
||||
{
|
||||
speakerp->mType = LLSpeaker::SPEAKER_AGENT;
|
||||
speakerp->lookupName();
|
||||
}
|
||||
speakerp->mType = LLSpeaker::SPEAKER_AGENT;
|
||||
speakerp->lookupName();
|
||||
}
|
||||
else
|
||||
if (update_moderator)
|
||||
{
|
||||
LL_WARNS("Speakers") << "Speaker " << id << " not found" << LL_ENDL;
|
||||
fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,13 +550,17 @@ void LLSpeakerMgr::updateSpeakerList()
|
||||
std::set<LLUUID> participants;
|
||||
LLVoiceClient::getInstance()->getParticipantList(participants);
|
||||
// If we are, add all voice client participants to our list of known speakers
|
||||
std::vector<speaker_entry_t> speakers;
|
||||
speakers.reserve(participants.size());
|
||||
for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it)
|
||||
{
|
||||
setSpeaker(*participant_it,
|
||||
LLVoiceClient::getInstance()->getDisplayName(*participant_it),
|
||||
LLSpeaker::STATUS_VOICE_ACTIVE,
|
||||
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
|
||||
speakers.emplace_back(speaker_entry_t(
|
||||
*participant_it,
|
||||
LLSpeaker::STATUS_VOICE_ACTIVE,
|
||||
LLVoiceClient::getInstance()->getDisplayName(*participant_it),
|
||||
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL)));
|
||||
}
|
||||
setSpeakers(speakers);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -569,10 +589,11 @@ void LLSpeakerMgr::updateSpeakerList()
|
||||
}
|
||||
else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
|
||||
{
|
||||
std::vector<speaker_entry_t> speakers;
|
||||
speakers.reserve(gdatap->mMembers.size());
|
||||
|
||||
// Add group members when we get the complete list (note: can take a while before we get that list)
|
||||
LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
|
||||
const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers");
|
||||
S32 updated = 0;
|
||||
while (member_it != gdatap->mMembers.end())
|
||||
{
|
||||
LLGroupMemberData* member = member_it->second;
|
||||
@@ -581,16 +602,16 @@ void LLSpeakerMgr::updateSpeakerList()
|
||||
const std::string& localized_online();
|
||||
if ((member->getOnlineStatus() == localized_online()) && (mSpeakers.find(id) == mSpeakers.end()))
|
||||
{
|
||||
LLPointer<LLSpeaker> speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
|
||||
speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
|
||||
updated++;
|
||||
speakers.emplace_back(speaker_entry_t(
|
||||
id,
|
||||
LLSpeaker::STATUS_VOICE_ACTIVE,
|
||||
"",
|
||||
LLSpeaker::SPEAKER_AGENT,
|
||||
(member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR));
|
||||
}
|
||||
++member_it;
|
||||
// Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop
|
||||
// *TODO : solve the perf issue of having several hundreds of widgets in the conversation list
|
||||
if (updated >= load_group_max_members)
|
||||
break;
|
||||
}
|
||||
setSpeakers(speakers);
|
||||
mSpeakerListUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -617,7 +638,7 @@ void LLSpeakerMgr::updateSpeakerList()
|
||||
}
|
||||
}
|
||||
// Always add the current agent (it has to be there...). Will do nothing if already there.
|
||||
setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
|
||||
setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE);
|
||||
}
|
||||
|
||||
void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
|
||||
@@ -737,6 +758,7 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
|
||||
{
|
||||
if ( !speakers.isMap() ) return;
|
||||
|
||||
std::vector<speaker_entry_t> speakerentries;
|
||||
if ( speakers.has("agent_info") && speakers["agent_info"].isMap() )
|
||||
{
|
||||
LLSD::map_const_iterator speaker_it;
|
||||
@@ -744,26 +766,21 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
|
||||
speaker_it != speakers["agent_info"].endMap();
|
||||
++speaker_it)
|
||||
{
|
||||
LLUUID agent_id(speaker_it->first);
|
||||
|
||||
LLPointer<LLSpeaker> speakerp = setSpeaker(
|
||||
agent_id,
|
||||
LLStringUtil::null,
|
||||
LLSpeaker::STATUS_TEXT_ONLY);
|
||||
|
||||
if ( speaker_it->second.isMap() )
|
||||
bool moderator = false;
|
||||
bool moderator_muted = false;
|
||||
if (speaker_it->second.isMap())
|
||||
{
|
||||
BOOL is_moderator = speakerp->mIsModerator;
|
||||
speakerp->mIsModerator = speaker_it->second["is_moderator"];
|
||||
speakerp->mModeratorMutedText =
|
||||
speaker_it->second["mutes"]["text"];
|
||||
// Fire event only if moderator changed
|
||||
if ( is_moderator != speakerp->mIsModerator )
|
||||
{
|
||||
LL_DEBUGS("Speakers") << "Speaker " << agent_id << (is_moderator ? "is now" : "no longer is") << " a moderator" << LL_ENDL;
|
||||
fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
|
||||
}
|
||||
moderator = speaker_it->second["is_moderator"];
|
||||
moderator_muted = speaker_it->second["mutes"]["text"];
|
||||
}
|
||||
speakerentries.emplace_back(
|
||||
LLUUID(speaker_it->first),
|
||||
LLSpeaker::STATUS_TEXT_ONLY,
|
||||
"",
|
||||
LLSpeaker::SPEAKER_AGENT,
|
||||
moderator,
|
||||
moderator_muted
|
||||
);
|
||||
}
|
||||
}
|
||||
else if ( speakers.has("agents" ) && speakers["agents"].isArray() )
|
||||
@@ -775,22 +792,20 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
|
||||
speaker_it != speakers["agents"].endArray();
|
||||
++speaker_it)
|
||||
{
|
||||
const LLUUID agent_id = (*speaker_it).asUUID();
|
||||
|
||||
LLPointer<LLSpeaker> speakerp = setSpeaker(
|
||||
agent_id,
|
||||
LLStringUtil::null,
|
||||
LLSpeaker::STATUS_TEXT_ONLY);
|
||||
speakerentries.emplace_back((*speaker_it).asUUID());
|
||||
}
|
||||
}
|
||||
LLSpeakerMgr::setSpeakers(speakerentries);
|
||||
}
|
||||
|
||||
void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
||||
{
|
||||
if ( !update.isMap() ) return;
|
||||
|
||||
std::vector<speaker_entry_t> speakerentries;
|
||||
if ( update.has("agent_updates") && update["agent_updates"].isMap() )
|
||||
{
|
||||
|
||||
LLSD::map_const_iterator update_it;
|
||||
for(
|
||||
update_it = update["agent_updates"].beginMap();
|
||||
@@ -800,8 +815,11 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
||||
LLUUID agent_id(update_it->first);
|
||||
LLPointer<LLSpeaker> speakerp = findSpeaker(agent_id);
|
||||
|
||||
LLSD agent_data = update_it->second;
|
||||
bool new_speaker = false;
|
||||
bool moderator = false;
|
||||
bool moderator_muted = false;
|
||||
|
||||
LLSD agent_data = update_it->second;
|
||||
if (agent_data.isMap() && agent_data.has("transition"))
|
||||
{
|
||||
if (agent_data["transition"].asString() == "LEAVE" && speakerp.notNull())
|
||||
@@ -811,15 +829,17 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
||||
else if (agent_data["transition"].asString() == "ENTER")
|
||||
{
|
||||
// add or update speaker
|
||||
speakerp = setSpeaker(agent_id);
|
||||
new_speaker = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "bad membership list update from 'agent_updates' for agent " << agent_id << ", transition " << ll_print_sd(agent_data["transition"]) << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (speakerp.isNull()) continue;
|
||||
if (speakerp.isNull() && !new_speaker)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// should have a valid speaker from this point on
|
||||
if (agent_data.isMap() && agent_data.has("info"))
|
||||
@@ -828,21 +848,21 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
||||
|
||||
if (agent_info.has("is_moderator"))
|
||||
{
|
||||
BOOL is_moderator = speakerp->mIsModerator;
|
||||
speakerp->mIsModerator = agent_info["is_moderator"];
|
||||
// Fire event only if moderator changed
|
||||
if ( is_moderator != speakerp->mIsModerator )
|
||||
{
|
||||
LL_DEBUGS("Speakers") << "Speaker " << agent_id << (is_moderator ? "is now" : "no longer is") << " a moderator" << LL_ENDL;
|
||||
fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
|
||||
}
|
||||
moderator = agent_info["is_moderator"];
|
||||
}
|
||||
|
||||
if (agent_info.has("mutes"))
|
||||
{
|
||||
speakerp->mModeratorMutedText = agent_info["mutes"]["text"];
|
||||
moderator_muted = agent_info["mutes"]["text"];
|
||||
}
|
||||
}
|
||||
speakerentries.emplace_back(
|
||||
agent_id,
|
||||
LLSpeaker::STATUS_TEXT_ONLY,
|
||||
"",
|
||||
LLSpeaker::SPEAKER_AGENT,
|
||||
moderator,
|
||||
moderator_muted
|
||||
);
|
||||
}
|
||||
}
|
||||
else if ( update.has("updates") && update["updates"].isMap() )
|
||||
@@ -864,7 +884,9 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
||||
else if ( agent_transition == "ENTER")
|
||||
{
|
||||
// add or update speaker
|
||||
speakerp = setSpeaker(agent_id);
|
||||
speakerentries.emplace_back(
|
||||
agent_id
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -872,6 +894,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
|
||||
}
|
||||
}
|
||||
}
|
||||
LLSpeakerMgr::setSpeakers(speakerentries);
|
||||
}
|
||||
|
||||
void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
|
||||
@@ -1039,10 +1062,13 @@ void LLLocalSpeakerMgr::updateSpeakerList()
|
||||
// pick up non-voice speakers in chat range
|
||||
uuid_vec_t avatar_ids;
|
||||
LLWorld::getInstance()->getAvatars(&avatar_ids, nullptr, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS);
|
||||
std::vector<speaker_entry_t> speakers;
|
||||
speakers.reserve(avatar_ids.size());
|
||||
for (const auto& id : avatar_ids)
|
||||
{
|
||||
setSpeaker(id);
|
||||
speakers.emplace_back(id);
|
||||
}
|
||||
setSpeakers(speakers);
|
||||
|
||||
// check if text only speakers have moved out of chat range
|
||||
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
|
||||
|
||||
@@ -230,10 +230,32 @@ public:
|
||||
void update(BOOL resort_ok);
|
||||
void setSpeakerTyping(const LLUUID& speaker_id, BOOL typing);
|
||||
void speakerChatted(const LLUUID& speaker_id);
|
||||
|
||||
struct speaker_entry_t
|
||||
{
|
||||
speaker_entry_t(const LLUUID& id,
|
||||
LLSpeaker::ESpeakerStatus status = LLSpeaker::STATUS_TEXT_ONLY,
|
||||
const std::string& name = LLStringUtil::null,
|
||||
LLSpeaker::ESpeakerType type = LLSpeaker::SPEAKER_AGENT,
|
||||
const bool moderator = false,
|
||||
const bool moderator_muted_text = false) :
|
||||
id(id), name(name), status(status), type(type), moderator(moderator), moderator_muted_text(moderator_muted_text)
|
||||
{}
|
||||
const LLUUID id;
|
||||
const std::string name;
|
||||
const LLSpeaker::ESpeakerStatus status;
|
||||
const LLSpeaker::ESpeakerType type;
|
||||
const bool moderator;
|
||||
const bool moderator_muted_text;
|
||||
};
|
||||
|
||||
void setSpeakers(const std::vector<speaker_entry_t>& speakers);
|
||||
LLPointer<LLSpeaker> setSpeaker(const LLUUID& id,
|
||||
const std::string& name = LLStringUtil::null,
|
||||
LLSpeaker::ESpeakerStatus status = LLSpeaker::STATUS_TEXT_ONLY,
|
||||
LLSpeaker::ESpeakerType = LLSpeaker::SPEAKER_AGENT);
|
||||
LLSpeaker::ESpeakerType = LLSpeaker::SPEAKER_AGENT,
|
||||
bool moderator = false,
|
||||
bool moderator_muted_text = false);
|
||||
|
||||
BOOL isVoiceActive();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user