Commits

Anonymous committed 7830513

Work on low task EXT-3682 (Dedicated icon is required for AvaLine callers in the VCP)
-- refactored processing of voice participants in the "Voice control panel".
Now list is filled only when voice channel is in CONNECTED state and is cleared otherwise.

Comments (0)

Files changed (3)

indra/newview/llavatarlist.cpp

 {
 	getIDs().clear();
 	setDirty(true);
+	LLFlatListView::clear();
 }
 
 void LLAvatarList::setNameFilter(const std::string& filter)

indra/newview/llcallfloater.cpp

 #include "llparticipantlist.h"
 #include "llspeakers.h"
 #include "lltransientfloatermgr.h"
+#include "llvoicechannel.h"
 
 static void get_voice_participants_uuids(std::vector<LLUUID>& speakers_uuids);
 
 	return TRUE;
 }
 
+LLVoiceChannel* LLCallFloater::sCurrentVoiceCanel = NULL;
+
 LLCallFloater::LLCallFloater(const LLSD& key)
 : LLDockableFloater(NULL, false, key)
 , mSpeakerManager(NULL)
 	mParticipants = NULL;
 
 	mAvatarListRefreshConnection.disconnect();
+	mVoiceChannelStateChangeConnection.disconnect();
 
 	// Don't use LLVoiceClient::getInstance() here 
 	// singleton MAY have already been destroyed.
 	childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this));
 
 	mNonAvatarCaller = getChild<LLNonAvatarCaller>("non_avatar_caller");
+	mNonAvatarCaller->setVisible(FALSE);
 
 	LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_panel");
 
 
 	initAgentData();
 
-	// update list for current session
-	updateSession();
+
+	connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
 
 	return TRUE;
 }
 
 void LLCallFloater::refreshParticipantList()
 {
-	// lets forget states from the previous session
-	// for timers...
-	resetVoiceRemoveTimers();
-
-	// ...and for speaker state
-	mSpeakerStateMap.clear();
-
-	delete mParticipants;
-	mParticipants = NULL;
-	mAvatarList->clear();
-
 	bool non_avatar_caller = false;
 	if (VC_PEER_TO_PEER == mVoiceType)
 	{
 	}
 }
 
+// static
 void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
 {
-	// Don't update participant list if no channel info is available.
-	// Fix for ticket EXT-3427
-	// @see LLParticipantList::~LLParticipantList()
-	if(LLVoiceChannel::getCurrentVoiceChannel() && 
-		LLVoiceChannel::STATE_NO_CHANNEL_INFO == LLVoiceChannel::getCurrentVoiceChannel()->getState())
-	{
-		return;
-	}
+	LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+
+	// *NOTE: if signal was sent for voice channel with LLVoiceChannel::STATE_NO_CHANNEL_INFO
+	// it sill be sent for the same channel again (when state is changed).
+	// So, lets ignore this call.
+	if (channel == sCurrentVoiceCanel) return;
+
 	LLCallFloater* call_floater = LLFloaterReg::getTypedInstance<LLCallFloater>("voice_controls");
 
-	// Forget speaker manager from the previous session to avoid using it after session was destroyed.
-	call_floater->mSpeakerManager = NULL;
-	call_floater->updateSession();
+	call_floater->connectToChannel(channel);
 }
 
 void LLCallFloater::updateTitle()
 	return std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end();
 }
 
+void LLCallFloater::connectToChannel(LLVoiceChannel* channel)
+{
+	mVoiceChannelStateChangeConnection.disconnect();
+
+	sCurrentVoiceCanel = channel;
+
+	mVoiceChannelStateChangeConnection = sCurrentVoiceCanel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2));
+
+	updateState(channel->getState());
+}
+
+void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
+{
+	updateState(new_state);
+}
+
+void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state)
+{
+	LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceCanel->getSessionName() << LL_ENDL;
+	if (LLVoiceChannel::STATE_CONNECTED == new_state)
+	{
+		updateSession();
+	}
+	else
+	{
+		reset();
+	}
+}
+
+void LLCallFloater::reset()
+{
+	// lets forget states from the previous session
+	// for timers...
+	resetVoiceRemoveTimers();
+
+	// ...and for speaker state
+	mSpeakerStateMap.clear();
+
+	delete mParticipants;
+	mParticipants = NULL;
+	mAvatarList->clear();
+
+	mSpeakerManager = NULL;
+}
+
 //EOF

indra/newview/llcallfloater.h

 #define LL_LLCALLFLOATER_H
 
 #include "lldockablefloater.h"
+#include "llvoicechannel.h"
 #include "llvoiceclient.h"
 
 class LLAvatarList;
 	 */
 	bool validateSpeaker(const LLUUID& speaker_id);
 
+	/**
+	 * Connects to passed channel to be updated according to channel's voice states.
+	 */
+	void connectToChannel(LLVoiceChannel* channel);
+
+	/**
+	 * Callback to process changing of voice channel's states.
+	 */
+	void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
+
+	/**
+	 * Updates floater according to passed channel's voice state.
+	 */
+	void updateState(const LLVoiceChannel::EState& new_state);
+
+	/**
+	 * Resets floater to be ready to show voice participants.
+	 *
+	 * Clears all data from the latest voice session.
+	 */
+	void reset();
+
 private:
 	speaker_state_map_t mSpeakerStateMap;
 	LLSpeakerMgr* mSpeakerManager;
 
 	timers_map		mVoiceLeftTimersMap;
 	S32				mVoiceLeftRemoveDelay;
+
+	/**
+	 * Stores reference to current voice channel.
+	 *
+	 * Is used to ignore voice channel changed callback for the same channel.
+	 *
+	 * @see sOnCurrentChannelChanged()
+	 */
+	static LLVoiceChannel* sCurrentVoiceCanel;
+	boost::signals2::connection mVoiceChannelStateChangeConnection;
 };