public static IEnumerator ModMenuLoadStart(List <SceneEdit.SMenuItem> menuList, Dictionary <int, List <int> > menuGroupMemberDic) { Dictionary <SceneEdit.SMenuItem, byte[]> modIconLoads = new Dictionary <SceneEdit.SMenuItem, byte[]>(); modFiles.Clear(); Task loaderWorker = Task.Factory.StartNew(new Action(() => { Mutex dicLock = new Mutex(); Task servantWorker = Task.Factory.StartNew(new Action(() => { foreach (string mod in Menu.GetModFiles()) { try { dicLock.WaitOne(); modFiles[mod] = new MemoryStream(File.ReadAllBytes(mod)); dicLock.ReleaseMutex(); } catch { Debug.LogError("Couldn't read .mod file at: " + mod); } } })); while (!servantWorker.IsCompleted || modFiles.Count > 0) { if (modFiles.Count == 0) { Thread.Sleep(1); continue; } string strFileName = modFiles.First().Key; SceneEdit.SMenuItem mi2 = new SceneEdit.SMenuItem(); if (ModMenuLoad.InitModMenuItemScript(mi2, strFileName, out byte[] icon)) { modIconLoads[mi2] = icon; } dicLock.WaitOne(); modFiles.Remove(strFileName); dicLock.ReleaseMutex(); }
private static IEnumerator InitMenuNative() { List <SceneEdit.SMenuItem> menuList = new List <SceneEdit.SMenuItem>(); Dictionary <int, List <int> > menuGroupMemberDic = new Dictionary <int, List <int> >(); @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>(); //We set time so the coroutines to be called can coordinate themselves. time = Time.realtimeSinceStartup; AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(Main.@this, null); Main.logger.LogInfo($"Files began loading at: {WatchOverall.Elapsed}"); //These coroutines hold the loading code for each type of item related file. this2.StartCoroutine(GSModMenuLoad.GSMenuLoadStart(menuList, menuGroupMemberDic)); this2.StartCoroutine(ModMenuLoad.ModMenuLoadStart(menuList, menuGroupMemberDic)); this2.StartCoroutine(VanillaMenuLoad.VanillaMenuLoadStart(menuList, menuGroupMemberDic)); //In a sorta async fashion, while the threads are no complete, the coroutine will pass on processing to someone else. while (ThreadsDone != 3) { yield return(null); } Main.logger.LogInfo($"All loaders finished at: {WatchOverall.Elapsed}."); //Setting threads back to 0 for next loads. ThreadsDone = 0; //Calls the final function to complete setting up menu items. yield return(@this.StartCoroutine(Main.FixedInitMenu(menuList, @this.m_menuRidDic, menuGroupMemberDic))); //Does something... yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "CoLoadWait").Invoke(@this, null) as IEnumerator)); Main.logger.LogInfo($"Loading completely done at: {WatchOverall.Elapsed}."); }