using Cysharp.Threading.Tasks; using System; using System.Linq; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; using System.Threading.Tasks; public class SearchCtrl : SingletonMonoBehaviour { [SerializeField] GameObject opsion; [SerializeField] Image searchMenuButtonImage; [SerializeField] Sprite[] searchMenuButton; [SerializeField] TMP_Text searchMenuButtonText; [SerializeField] TMP_InputField name; [SerializeField] TMP_Dropdown suitStyle; [SerializeField] TMP_Dropdown suitType; [SerializeField] TMP_Dropdown region; [SerializeField] TMP_Dropdown animalTypes; [SerializeField] Toggle[] colors; [SerializeField] Sprite[] isOnSprite; [SerializeField] ItemPrefab item; [SerializeField] Transform results; [SerializeField] GameObject listTop; [SerializeField] GameObject bar; [SerializeField] RectTransform content; [SerializeField] Animator searchUI; [SerializeField] ModalCtrl model; private SearchRequest request; private List librarys = new(); private Queue searchResults = new Queue(); private bool hasMore; #if UNITY_EDITOR [SerializeField] #endif private List itemPrefabs; private UnityEngine.Pool.ObjectPool itemPrefabPool; protected override void OnAwake() { Application.targetFrameRate = 30; QualitySettings.vSyncCount = 0; itemPrefabPool = new UnityEngine.Pool.ObjectPool(itemPrefabs_OnCreate,itemPrefabs_OnGet, itemPrefabs_OnRelease,null,true, 100); itemPrefabs = new List(); } #region ObjectPool private ItemPrefab itemPrefabs_OnCreate() { return Instantiate(item, results); } private void itemPrefabs_OnGet(ItemPrefab itemPrefab) { itemPrefabs.Add(itemPrefab); itemPrefab.gameObject.SetActive(true); } private void itemPrefabs_OnRelease(ItemPrefab itemPrefab) { itemPrefab.gameObject.SetActive(false); itemPrefabs.Remove(itemPrefab); } #endregion private void OnEnable() { hasMore = false; model.gameObject.SetActive(false); searchUI.SetTrigger("reset"); ResetButton(); ObjectClear(); } private void ObjectClear() { //TODO ��Ȱ�� �� �� �ְ� ����� results.gameObject.SetActive(false); listTop.SetActive(false); bar.SetActive(false); librarys.Clear(); while(itemPrefabPool.CountActive > 0) { var item = itemPrefabs[itemPrefabs.Count-1]; itemPrefabPool.Release(item); } } public void OpsionButton() { //�ɼ�â�� ������ �ʾ����� 250,100 //�ɼ�â�� �������� 60 ,290 bool isSelf = !opsion.activeSelf; searchMenuButtonImage.sprite = searchMenuButton[(isSelf ? 1 : 0)]; searchMenuButtonImage.pixelsPerUnitMultiplier = (isSelf ? 3.5f : 1.75f); searchMenuButtonText.color = (isSelf ? Color.white : Color.black); searchUI.SetBool("isSelf", isSelf); ResetButton(); } public void SearchButton() { ObjectClear(); request = new SearchRequest(); request.fursuitName = name.text; if (suitStyle.value != 0) request.suitStyle = GameManager.Instance.suitStyle[suitStyle.value - 1].code_id; if (suitType.value != 0) request.suitType = GameManager.Instance.suitType[suitType.value - 1].code_id; if (region.value != 0) request.suitRegion = GameManager.Instance.region[region.value - 1].code_id; if (animalTypes.value != 0) request.suitAnimalType = GameManager.Instance.animalTypes[animalTypes.value - 1].code_id; _ = SearchSuiters(); results.gameObject.SetActive(true); listTop.SetActive(true); bar.SetActive(true); //NetworkManager.Instance.CreateRequest("library/select/suiters", request, (data) => //{ // librarys = data.data; // results.gameObject.SetActive(true); // listTop.SetActive(true); // bar.SetActive(true); // ItemPrefab[] items = new ItemPrefab[data.data.Count]; // for (int n = 0; n < data.data.Count; n++) // { // var prefab = Instantiate(item, results); // itemPrefabs.Add(prefab); // items[n] = prefab; // } // for (int n = 0; n < data.data.Count; n++) // { // items[n].Set(data.data[n]); // } // hasMore = data.hasMore; // //LayoutRebuilder.ForceRebuildLayoutImmediate(content); //}); } private bool isSearching = false; public async UniTask SearchSuiters() { if (isSearching) return; isSearching = true; var tcs = new TaskCompletionSource(); var searchRequest = NetworkManager.Instance.CreateRequest( "library/select/suiters", request, (data) => { for (int n = 0; n < data.data.Count; n++) { searchResults.Enqueue(data.data[n]); } hasMore = data.hasMore; tcs.SetResult(true); // 응답 완료 신호 } ); await searchRequest.Send(); await tcs.Task; // 응답이 완료될 때까지 대기 await RefreshScroll(); isSearching = false; } bool isRefreshing = false; public async UniTask RefreshScroll() { if (isRefreshing) return; isRefreshing = true; if (searchResults.Count > 0) { while (searchResults.TryDequeue(out var result)) { librarys.Add(result); } // librarys.Sort((a,b) => a.owner_id.CompareTo(b.owner_id)); } int n = 0; for (; n < itemPrefabs.Count; n++) { var item = itemPrefabs[n]; item.Set(librarys[n]); await UniTask.Yield(); } for(; n < librarys.Count; n++) { var item = itemPrefabPool.Get(); item.Set(librarys[n]); await UniTask.Yield(); } for(; n > librarys.Count; n--) { var item = itemPrefabs.Last(); itemPrefabPool.Release(item); await UniTask.Yield(); } await ApplayImages(); // LayoutRebuilder.ForceRebuildLayoutImmediate(content); isRefreshing = false; } private async UniTask ApplayImages() { for (int i = 0; itemPrefabs.Count > i; i++) { await GetImage(itemPrefabs[i].Library); itemPrefabs[i].ImageSet(); } } public void NextSearch() { if (isSearching == false) { hasMore = false; request.page++; _ = SearchSuiters(); } } public async UniTask GetImage(Library library) { if (library._suit_image != null) { return library._suit_image; } var tcs = new TaskCompletionSource(); var request = NetworkManager.Instance.CreateImageRequest( library.imageBase64.Substring(1), new object(), (data) => { library._suit_image = data; tcs.SetResult(data); }, (fail) => { tcs.SetResult(null); }, BestHTTP.HTTPMethods.Get ); await request.Send(); await tcs.Task; return library._suit_image; } public void ResetButton() { suitStyle.value = 0; suitType.value = 0; region.value = 0; animalTypes.value = 0; for(int n = 0; n < colors.Length; n++) { colors[n].isOn = false; colors[n].image.sprite = isOnSprite[0]; } } public void OnToggle(int velue) { colors[velue].image.sprite = isOnSprite[(colors[velue].isOn ? 1 : 0)]; } public void ModelSet(Library library) { model.Set(library); } public void ScrollValue(RectTransform Content) { if(Content.anchoredPosition.y < 0.0f) { Content.anchoredPosition = Vector2.zero; } else if(hasMore && Content.sizeDelta.y != Screen.height && Content.sizeDelta.y - Screen.height < Content.anchoredPosition.y) { NextSearch(); } } } public class SearchRequest { public int xid; public string fursuitName = ""; /*����,��Ʈ �̸�*/ public string suitMaker; /*������*/ public string suitRegion = ""; /*Ȱ�� ����*/ public string suitStyle = ""; /*��Ʈ ��Ÿ��*/ public string suitAnimalType = ""; /*��Ʈ ���� ��*/ public string suitType = ""; /*��Ʈ ����*/ public List colorList = new List(); /*��Ʈ ����*/ public int page = 1; public int size = 5; public int offset = 0; } public class SearchResponse { public List data; public bool hasMore; } public class ImageResponse { public byte[] imageBytes; } public class Library : IEquatable { public string imageBase64; public string suit_name; public string owner_id; public string owner_name; public string production_date; public string suit_image;//������ public Texture2D _suit_image = null; public string maker; public string region; public string animal_type; public string suit_style; public string suit_type; public List suit_color; public bool Equals(Library other) { return this.imageBase64 == other.imageBase64 && this.owner_id == other.owner_id && this.maker == other.maker && this.region == other.region && this.animal_type == other.animal_type && this.suit_type == other.suit_type && this.suit_style == other.suit_style; } }