using System; using System.Collections.Generic; using TMPro; using UnityEngine; namespace LobbyRelaySample.UI { /// /// Handles the list of LobbyButtons and ensures it stays synchronized with the lobby list from the service. /// public class JoinMenuUI : UIPanelBase { [SerializeField] LobbyButtonUI m_LobbyButtonPrefab; [SerializeField] RectTransform m_LobbyButtonParent; [SerializeField] TMP_InputField m_JoinCodeField; public JoinCreateLobbyUI m_JoinCreateLobbyUI; /// /// Key: Lobby ID, Value Lobby UI /// Dictionary m_LobbyButtons = new Dictionary(); Dictionary m_LocalLobby = new Dictionary(); /// Contains some amount of information used to join an existing lobby. LocalLobby m_LocalLobbySelected; public override void Start() { base.Start(); m_JoinCreateLobbyUI.m_OnTabChanged.AddListener(OnTabChanged); Manager.LobbyList.onLobbyListChange += OnLobbyListChanged; } void OnDestroy() { if (Manager == null) return; Manager.LobbyList.onLobbyListChange -= OnLobbyListChanged; } void OnTabChanged(JoinCreateTabs tabState) { if (tabState == JoinCreateTabs.Join) { Show(); } else { Hide(); } } public void LobbyButtonSelected(LocalLobby lobby) { m_LocalLobbySelected = lobby; } public void OnLobbyCodeInputFieldChanged(string newCode) { if (!string.IsNullOrEmpty(newCode)) m_LocalLobbySelected.LobbyCode.Value = newCode.ToUpper(); } public void OnJoinButtonPressed() { Locator.Get.Messenger.OnReceiveMessage(MessageType.JoinLobbyRequest, m_LocalLobbySelected); m_LocalLobbySelected = new LocalLobby(); } public void OnRefresh() { Locator.Get.Messenger.OnReceiveMessage(MessageType.QueryLobbies, null); } void OnLobbyListChanged(Dictionary lobbyList) { ///Check for new entries, We take CurrentLobbies as the source of truth List previousKeys = new List(m_LobbyButtons.Keys); foreach (var codeLobby in lobbyList) { var lobbyCodeKey = codeLobby.Key; var lobbyData = codeLobby.Value; if (!m_LobbyButtons.ContainsKey(lobbyCodeKey)) { if (CanDisplay(lobbyData)) AddNewLobbyButton(lobbyCodeKey, lobbyData); } else { if (CanDisplay(lobbyData)) SetLobbyButton(lobbyCodeKey, lobbyData); else RemoveLobbyButton(lobbyData); } previousKeys.Remove(lobbyCodeKey); } foreach (string key in previousKeys) // Need to remove any lobbies from the list that no longer exist. RemoveLobbyButton(m_LocalLobby[key]); } public void JoinMenuChangedVisibility(bool show) { if (show) { m_JoinCodeField.text = ""; OnRefresh(); } } public void OnQuickJoin() { Locator.Get.Messenger.OnReceiveMessage(MessageType.QuickJoin, null); } bool CanDisplay(LocalLobby lobby) { return lobby.LocalLobbyState.Value == LobbyState.Lobby && !lobby.Private.Value; } /// /// Instantiates UI element and initializes the observer with the LobbyData /// void AddNewLobbyButton(string lobbyCode, LocalLobby lobby) { var lobbyButtonInstance = Instantiate(m_LobbyButtonPrefab, m_LobbyButtonParent); lobbyButtonInstance.GetComponent().BeginObserving(lobby); lobby.onDestroyed += RemoveLobbyButton; // Set up to clean itself lobbyButtonInstance.onLobbyPressed.AddListener(LobbyButtonSelected); m_LobbyButtons.Add(lobbyCode, lobbyButtonInstance); m_LocalLobby.Add(lobbyCode, lobby); } void SetLobbyButton(string lobbyCode, LocalLobby lobby) { m_LobbyButtons[lobbyCode].SetLobby(lobby); } void RemoveLobbyButton(LocalLobby lobby) { var lobbyID = lobby.LobbyID.Value; var lobbyButton = m_LobbyButtons[lobbyID]; lobbyButton.GetComponent().EndObserving(); m_LobbyButtons.Remove(lobbyID); m_LocalLobby.Remove(lobbyID); Destroy(lobbyButton.gameObject); } } }