/// <summary> /// 状态机状态翻转 /// </summary> /// <param name="state">指定状态机</param> /// <returns>执行结果</returns> public static async ETTask ChangeState <State, T, U, V>(this FSMComponent self, T t, U u, V v) where State : Entity { CoroutineLock coroutine = null; try { coroutine = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.FSM, self.Id); Entity _tmpState = self.GetState <State>(); //要改变的状态不存在 if (_tmpState == null) { Log.Warning("FSMSystem(容错):该状态【{0}】不存在于状态机中!", typeof(State).Name); } if (self.CurrentState != null) //当前状态不为空 { await FSMEventSystem.Instance.FSMOnExit(self.CurrentState); } self.CurrentState = _tmpState; //缓存为当前状态 await FSMEventSystem.Instance.FSMOnEnter(self.CurrentState, t, u, v); //触发当前状态的OnEnter } finally { coroutine?.Dispose(); } }
// 加载ab包中的all assets private static async ETTask LoadOneBundleAllAssets(this ResourcesComponent self, ABInfo abInfo) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, abInfo.Name.GetHashCode()); if (abInfo.IsDisposed || abInfo.AlreadyLoadAssets) { return; } if (abInfo.AssetBundle != null && !abInfo.AssetBundle.isStreamedSceneAssetBundle) { // 异步load资源到内存cache住 var assets = await AssetBundleHelper.UnityLoadAssetAsync(abInfo.AssetBundle); foreach (UnityEngine.Object asset in assets) { self.AddResource(abInfo.Name, asset.name, asset); } } abInfo.AlreadyLoadAssets = true; } finally { coroutineLock?.Dispose(); } }
public static async ETTask LoadAsync(this ResourcesLoaderComponent self, string ab) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.ResourcesLoader, ab.GetHashCode(), 0); if (self.IsDisposed) { Log.Error($"resourceload already disposed {ab}"); return; } if (self.LoadedResource.Contains(ab)) { return; } self.LoadedResource.Add(ab); await ResourcesComponent.Instance.LoadBundleAsync(ab); } finally { coroutineLock?.Dispose(); } }
static async ETTask <T> __InnerOpenWindow <T, P1, P2, P3, P4>(this UIManagerComponent self, UIWindow target, P1 p1, P2 p2, P3 p3, P4 p4) where T : Entity { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.UIManager, target.GetHashCode()); target.Active = true; T res = target.GetComponent(target.ViewType) as T; var need_load = target.LoadingState == UIWindowLoadingState.NotStart; if (need_load) { target.LoadingState = UIWindowLoadingState.Loading; await Game.EventSystem.PublishAsync(new UIEventType.InnerOpenWindow() { path = target.PrefabPath, window = target }); } Game.EventSystem.Publish(new UIEventType.ResetWindowLayer() { window = target }); await self.__AddWindowToStack(target, p1, p2, p3, p4); return(res); } finally { coroutineLock?.Dispose(); } }
//预加载:可提供初始实例化个数 public static async ETTask PreLoadGameObjectAsync(this GameObjectPoolComponent self, string path, int inst_count, Action callback = null) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, path.GetHashCode()); if (self.CheckHasCached(path)) { callback?.Invoke(); } else { var go = await ResourcesComponent.Instance.LoadAsync <GameObject>(path); if (go != null) { self.CacheAndInstGameObject(path, go as GameObject, inst_count); } callback?.Invoke(); } } finally { coroutineLock?.Dispose(); } }
public static async ETTask <Material> LoadMaterialAsync(this MaterialComponent self, string address, Action <Material> callback = null) { Material res; CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, address.GetHashCode()); if (self.m_cacheMaterial.TryGetValue(address, out res)) { res = await ResourcesComponent.Instance.LoadAsync <Material>(address); if (res != null) { self.m_cacheMaterial[address] = res; } } callback?.Invoke(res); } finally { coroutineLock?.Dispose(); } return(res); }
//异步加载图片 会自动识别图集:回调方式(image 和button已经封装 外部使用时候 谨慎使用) public static async ETTask <Sprite> LoadImageAsync(this ImageLoaderComponent self, string image_path, Action <Sprite> callback = null) { Sprite res = null; CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, image_path.GetHashCode()); self.__GetSpriteLoadInfoByPath(image_path, out int asset_type, out string asset_address, out string subasset_name); if (asset_type == ImageLoaderComponent.SpriteType.Sprite) { res = await self.__LoadSingleImageAsyncInternal(asset_address, callback); } if (asset_type == ImageLoaderComponent.SpriteType.DynSpriteAtlas) { res = await self.__LoadDynSpriteImageAsyncInternal(asset_address, callback); } else { res = await self.__LoadSpriteImageAsyncInternal(asset_address, subasset_name, callback); } } catch (Exception ex) { Log.Error(ex); } finally { coroutineLock?.Dispose(); } return(res); }
public static async ETTask SetSpritePath(this UIImage self, string sprite_path, bool setNativeSize = false) { CoroutineLock coroutine = null; try { coroutine = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.UIImage, self.Id); if (sprite_path == self.sprite_path) { return; } self.ActivatingComponent(); if (self.BgAutoFit != null) { self.BgAutoFit.enabled = false; } self.unity_uiimage.enabled = false; var base_sprite_path = self.sprite_path; self.sprite_path = sprite_path; if (string.IsNullOrEmpty(sprite_path)) { self.unity_uiimage.sprite = null; self.unity_uiimage.enabled = true; } else { var sprite = await ImageLoaderComponent.Instance.LoadImageAsync(sprite_path); self.unity_uiimage.enabled = true; if (sprite == null) { ImageLoaderComponent.Instance.ReleaseImage(sprite_path); return; } self.unity_uiimage.sprite = sprite; if (setNativeSize) { self.SetNativeSize(); } if (self.BgAutoFit != null) { self.BgAutoFit.bgSprite = sprite; self.BgAutoFit.enabled = true; } } if (!string.IsNullOrEmpty(base_sprite_path)) { ImageLoaderComponent.Instance.ReleaseImage(base_sprite_path); } } finally { coroutine?.Dispose(); } }
/// <summary> /// 异步加载assetbundle, 加载ab包分两部分,第一部分是从硬盘加载,第二部分加载all assets。两者不能同时并发 /// </summary> public static async ETTask LoadBundleAsync(this ResourcesComponent self, string assetBundleName) { assetBundleName = assetBundleName.BundleNameToLower(); string[] dependencies = self.GetSortedDependencies(assetBundleName); //Log.Debug($"-----------dep load async start {assetBundleName} dep: {dependencies.ToList().ListToString()}"); using (ListComponent <ABInfo> abInfos = ListComponent <ABInfo> .Create()) { async ETTask LoadDependency(string dependency, List <ABInfo> abInfosList) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, dependency.GetHashCode()); ABInfo abInfo = await self.LoadOneBundleAsync(dependency); if (abInfo == null || abInfo.RefCount > 1) { return; } abInfosList.Add(abInfo); } finally { coroutineLock?.Dispose(); } } // LoadFromFileAsync部分可以并发加载 using (ListComponent <ETTask> tasks = ListComponent <ETTask> .Create()) { foreach (string dependency in dependencies) { tasks.Add(LoadDependency(dependency, abInfos)); } await ETTaskHelper.WaitAll(tasks); // ab包从硬盘加载完成,可以再并发加载all assets tasks.Clear(); foreach (ABInfo abInfo in abInfos) { tasks.Add(self.LoadOneBundleAllAssets(abInfo)); } await ETTaskHelper.WaitAll(tasks); } } }
public override void Destroy(ResourcesLoaderComponent self) { async ETTask UnLoadAsync() { using (ListComponent <string> list = ListComponent <string> .Create()) { list.AddRange(self.LoadedResource); self.LoadedResource = null; if (TimerComponent.Instance == null) { return; } // 延迟5秒卸载包,因为包卸载是引用计数,5秒之内假如重新有逻辑加载了这个包,那么可以避免一次卸载跟加载 await TimerComponent.Instance.WaitAsync(5000); foreach (string abName in list) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.ResourcesLoader, abName.GetHashCode(), 0); { if (ResourcesComponent.Instance == null) { return; } await ResourcesComponent.Instance.UnloadBundleAsync(abName); } } finally { coroutineLock?.Dispose(); } } } } UnLoadAsync().Coroutine(); }
//异步加载图片: 回调方式,按理除了预加载的时候其余时候是不需要关心图集的 public static async ETTask <Sprite> LoadSingleImageAsync(this ImageLoaderComponent self, string atlas_path, Action <Sprite> callback = null) { Sprite res; CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, atlas_path.GetHashCode()); res = await self.__LoadSingleImageAsyncInternal(atlas_path, callback); callback?.Invoke(res); } finally { coroutineLock?.Dispose(); } return(res); }
// 一帧卸载一个包,避免卡死 public static async ETTask UnloadBundleAsync(this ResourcesComponent self, string assetBundleName, bool unload = true) { assetBundleName = assetBundleName.BundleNameToLower(); string[] dependencies = self.GetSortedDependencies(assetBundleName); //Log.Debug($"-----------dep unload start {assetBundleName} dep: {dependencies.ToList().ListToString()}"); foreach (string dependency in dependencies) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Resources, assetBundleName.GetHashCode()); self.UnloadOneBundle(dependency, unload); await TimerComponent.Instance.WaitFrameAsync(); } finally { coroutineLock?.Dispose(); } } //Log.Debug($"-----------dep unload finish {assetBundleName} dep: {dependencies.ToList().ListToString()}"); }
/// <summary> /// 改变格子 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="viewLen"></param> public static async ETTask ChangeGrid(this AOISceneViewComponent self, int x, int y, int viewLen) { CoroutineLock coroutineLock = null; try { coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.AOIView, self.GetHashCode()); while (SceneManagerComponent.Instance.Busing) { await TimerComponent.Instance.WaitAsync(1); } if (self.LastGridX != null) { int count = 0; count += Math.Abs(x - (int)self.LastGridX); count += Math.Abs(y - (int)self.LastGridY); if (count > 4) //太远了走loading { self.ChangeToScene().Coroutine(); } } DictionaryComponent <long, int> temp = DictionaryComponent <long, int> .Create(); for (int i = -viewLen; i <= viewLen; i++) { for (int j = -viewLen; j <= viewLen; j++) { if (self.LastGridY != null) { var oldid = AOIHelper.CreateCellId((int)self.LastGridX + i, (int)self.LastGridY + j); if (!temp.ContainsKey(oldid)) { temp[oldid] = 0; } temp[oldid]--; } var newid = AOIHelper.CreateCellId(x + i, y + j); if (!temp.ContainsKey(newid)) { temp[newid] = 0; } temp[newid]++; } } foreach (var item in temp) { if (item.Value == 0) { continue; } var objs = self.DynamicSceneMap[self.CurMap].GridMapObjects; if (!objs.ContainsKey(item.Key)) { continue; } for (int i = 0; i < objs[item.Key].Count; i++) { var obj = objs[item.Key][i]; if (item.Value > 0) //新增 { if (self.DynamicSceneObjectMapCount.ContainsKey(obj)) { self.DynamicSceneObjectMapCount[obj]++; } else { self.DynamicSceneObjectMapCount[obj] = 1; } //需要显示 if (self.DynamicSceneObjectMapCount[obj] > 0) { AOISceneViewComponent.DynamicSceneViewObj viewObj; //已经有 if (self.DynamicSceneObjectMapObj.ContainsKey(obj)) { viewObj = self.DynamicSceneObjectMapObj[obj]; if (viewObj.Obj == null) //之前有单没加载出来,IsLoading改为true,防止之前已经被改成false了 { viewObj.IsLoading = true; } continue; } Log.Info("AOISceneView Load " + obj.Path); //没有 self.DynamicSceneObjectMapObj[obj] = new AOISceneViewComponent.DynamicSceneViewObj(); viewObj = self.DynamicSceneObjectMapObj[obj]; viewObj.IsLoading = true; GameObjectPoolComponent.Instance.GetGameObjectAsync(obj.Path, (view) => { if (!viewObj.IsLoading) //加载出来后已经不需要的 { GameObjectPoolComponent.Instance.RecycleGameObject(view); self.DynamicSceneObjectMapObj.Remove(obj); } viewObj.Obj = view; viewObj.IsLoading = false; view.transform.position = obj.Position; view.transform.rotation = obj.Rotation; view.transform.localScale = obj.Scale; view.transform.parent = GlobalComponent.Instance.Scene; }).Coroutine(); } } else //移除 { if (self.DynamicSceneObjectMapCount.ContainsKey(obj)) { self.DynamicSceneObjectMapCount[obj]--; } else { self.DynamicSceneObjectMapCount[obj] = -1; } //不需要显示但有 if (self.DynamicSceneObjectMapCount[obj] <= 0 && self.DynamicSceneObjectMapObj.ContainsKey(obj)) { Log.Info("AOISceneView Remove " + obj.Path); var viewObj = self.DynamicSceneObjectMapObj[obj]; if (viewObj.Obj == null) //还在加载 { viewObj.IsLoading = false; } else { viewObj.Obj.SetActive(false); GameObjectPoolComponent.Instance.RecycleGameObject(viewObj.Obj); self.DynamicSceneObjectMapObj.Remove(obj); } } } } } temp.Dispose(); self.LastGridX = x; self.LastGridY = y; } finally { coroutineLock?.Dispose(); } }