// 加载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住 AssetBundleRequest request = abInfo.AssetBundle.LoadAllAssetsAsync(); await request; UnityEngine.Object[] assets = request.allAssets; 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(); } }
public override void Dispose() { if (this.IsDisposed) { return; } base.Dispose(); this.CoroutineLock.Dispose(); this.CoroutineLock = null; LockInstanceId = 0; }
/// <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); } } }
protected 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 Lock(this LocationComponent self, long key, long instanceId, int time = 0) { CoroutineLock coroutineLock = await CoroutineLockComponent.Instance.Wait(CoroutineLockType.Location, key); LockInfo lockInfo = self.AddChild <LockInfo, long, CoroutineLock>(instanceId, coroutineLock); self.lockInfos.Add(key, lockInfo); Log.Info($"location lock key: {key} instanceId: {instanceId}"); if (time > 0) { long lockInfoInstanceId = lockInfo.InstanceId; await TimerComponent.Instance.WaitAsync(time); if (lockInfo.InstanceId != lockInfoInstanceId) { return; } self.UnLock(key, instanceId, instanceId); } }
// 一帧卸载一个包,避免卡死 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()}"); }
public CoroutineLockTimer(CoroutineLock coroutineLock) { this.CoroutineLock = coroutineLock; this.CoroutineLockInstanceId = coroutineLock.InstanceId; }