using System; using System.Collections; using System.Collections.Generic; using Ichni.RhythmGame.Beatmap; using UniRx; using UnityEngine; using UnityEngine.Events; namespace Ichni.RhythmGame { public class BeatmapContainer : IBaseElement { public List gameElementList; [NonSerialized] public List lowPriorityActions; public BaseElement_BM matchedBM { get; set; } public BeatmapContainer() { gameElementList = new List(); lowPriorityActions = new List(); Observable.EveryUpdate().Subscribe(_ => ExecuteLowPriorityActions()); } public void ExecuteLowPriorityActions() { if (lowPriorityActions.Count > 0) { lowPriorityActions.ForEach(low => low.Invoke()); lowPriorityActions.Clear(); } } public void SaveBM() { matchedBM = new BeatmapContainer_BM(gameElementList); } public void SetUpInspector() { throw new System.NotImplementedException(); } public void Refresh() { throw new System.NotImplementedException(); } } namespace Beatmap { public partial class BeatmapContainer_BM : BaseElement_BM { public List elementList; public IntReactiveProperty remainingElementAmount; public int loadAmount = 0; public int loadMaximumAmountPerFrame = 100; public BeatmapContainer_BM() { } public BeatmapContainer_BM(List gameElementList) { elementList = new List(); gameElementList.ForEach(e => { e.SaveBM(); e.submoduleList.RemoveAll(s => s == null); e.submoduleList.ForEach(s => s.SaveBM()); }); foreach (var gameElement in gameElementList) { if (gameElement.matchedBM != null) { elementList.Add(gameElement.matchedBM); } List submodules = gameElement.submoduleList.ConvertAll(s => s.matchedBM); submodules.RemoveAll(s => s == null); elementList.AddRange(submodules); } loadMaximumAmountPerFrame = Mathf.Min(Mathf.Max(1, gameElementList.Count / 60), 500); } public override void ExecuteBM() { GameManager.instance.beatmapContainer = new BeatmapContainer(); GameManager.instance.beatmapContainer.matchedBM = this; remainingElementAmount = new IntReactiveProperty(elementList.Count); GameElement_BM.identifier.Clear(); GameManager.instance.StartCoroutine(ExecuteLoadElements()); } private IEnumerator ExecuteLoadElements() { List lowPriorityElements = new List(); for (int index = 0; index < elementList.Count; index++) { BaseElement_BM element = elementList[index]; if (LowPriorityGameElementTypes.Contains(element.GetType())) { lowPriorityElements.Add(element); continue; } if (element is GameElement_BM gameElement) { GameElement_BM.identifier.Add(gameElement.elementGuid, gameElement); } //Debug.Log(element.attachedElementGuid); element.ExecuteBM(); remainingElementAmount.Value--; float loadPercent = (float)(elementList.Count - remainingElementAmount.Value) / elementList.Count; GameManager.instance.projectLoader.loadPercent = loadPercent; GameManager.instance.gameLoadingCanvas.SetProgress(loadPercent * 100f); loadAmount++; if (loadAmount >= loadMaximumAmountPerFrame) { loadAmount = 0; yield return new WaitForEndOfFrame(); } } foreach (var element in lowPriorityElements) { if (element == null) { Debug.LogError("Null element detected in low-priority elements. Skipping execution."); continue; } element.ExecuteBM(); remainingElementAmount.Value--; float loadPercent = (float)(elementList.Count - remainingElementAmount.Value) / elementList.Count; GameManager.instance.projectLoader.loadPercent = loadPercent; GameManager.instance.gameLoadingCanvas.SetProgress(loadPercent * 100f); loadAmount++; if (loadAmount >= loadMaximumAmountPerFrame) { loadAmount = 0; yield return new WaitForEndOfFrame(); } } GameManager.instance.beatmapContainer.ExecuteLowPriorityActions(); GameManager.instance.beatmapContainer.gameElementList.ForEach(gameElement => { gameElement.AfterInitialize(); gameElement.Refresh(); }); GameManager.instance.noteManager.AllNotesRegistered(); Debug.Log("All elements loaded."); GameManager.instance.gameLoadingCanvas.FadeOut(); GameManager.instance.audioManager.isLoading = false; yield return null; } } public partial class BeatmapContainer_BM : BaseElement_BM { public static readonly List LowPriorityGameElementTypes = new() { //typeof(NoteJudgeSubmodule_BM), }; public static readonly List LowPriorityDataTypes = new() { typeof(EnableControlEffect_BM), }; } } }