using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using TinaX.VFSKit; using TinaX; using TinaX.VFSKit.Exceptions; using Cysharp.Threading.Tasks; namespace TinaX.VFSKitInternal { /// /// VFS内部的一个资源 /// #pragma warning disable CA1063 // Implement IDisposable Correctly public class VFSAsset : IAsset, IRefCounter #pragma warning restore CA1063 // Implement IDisposable Correctly { protected UnityEngine.Object _asset; public UnityEngine.Object Asset => _asset; public string AssetPathLower => this.QueryResult.AssetPathLower; public string AssetPath => this.QueryResult.AssetPath; public VFSBundle Bundle { get; internal set; } public VFSGroup Group { get; internal set; } public AssetLoadState LoadState { get; internal set; } = AssetLoadState.Idle; public AssetQueryResult QueryResult { get; internal set; } //public UniTask _loadTask; //public UniTask LoadTask //{ // get // { // return _loadTask; // } // internal set // { // _loadTask = value.Preserve(); // } //} public AsyncLazy LoadTask { get; internal set; } public int AssetHashCode { get; private protected set; } = -1; public VFSAsset(VFSGroup group, AssetQueryResult queryResult) { this.Group = group; this.QueryResult = queryResult; } #region Counter public int RefCount { get; private set; } = 0; public void Release() { RefCount--; if(RefCount <= 0 && LoadState != AssetLoadState.Unloaded) { Unload(); } } public void Retain() { RefCount++; } #endregion public T Get() where T : UnityEngine.Object { return _asset as T; } public UnityEngine.Object Get() => _asset; public void Unload() { if(_asset != null) { if (!(_asset is GameObject)) Resources.UnloadAsset(_asset); _asset = null; } if (this.Bundle != null) { this.Bundle.Release(); this.Bundle.UnRegisterAsset(this); this.Bundle = null; } this.LoadState = AssetLoadState.Unloaded; } public async UniTask LoadAsync() { if (this.Bundle == null) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle is null, asset :" + AssetPathLower); if(this.Bundle.LoadState != AssetLoadState.Loaded) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle not ready, asset :" + AssetPathLower); if (this.LoadState == AssetLoadState.Unloaded) throw new VFSException("[TinaX.VFS] Error: Attempt to load an unloaded asset :" + AssetPathLower); if (this._asset == null || this.LoadState != AssetLoadState.Loaded) { this.LoadState = AssetLoadState.Loading; this._asset = await this.Bundle.AssetBundle.LoadAssetAsync(this.AssetPathLower); } this.LoadState = AssetLoadState.Loaded; this.LoadTask = UniTask.CompletedTask.ToAsyncLazy(); this.AssetHashCode = this._asset.GetHashCode(); RegisterToBundle(); } public async UniTask LoadAsync(Type type) { if (this.Bundle == null) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle is null, asset :" + AssetPathLower); if (this.Bundle.LoadState != AssetLoadState.Loaded) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle not ready, asset :" + AssetPathLower); if (this.LoadState == AssetLoadState.Unloaded) throw new VFSException("[TinaX.VFS] Error: Attempt to load an unloaded asset :" + AssetPathLower); if (this._asset == null || this.LoadState != AssetLoadState.Loaded) { this.LoadState = AssetLoadState.Loading; this._asset = await this.Bundle.AssetBundle.LoadAssetAsync(this.AssetPathLower,type); } this.LoadState = AssetLoadState.Loaded; this.LoadTask = UniTask.CompletedTask.ToAsyncLazy(); this.AssetHashCode = this._asset.GetHashCode(); RegisterToBundle(); } public void Load() where T : UnityEngine.Object { if (this.Bundle == null) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle is null, asset :" + AssetPathLower); if (this.Bundle.LoadState != AssetLoadState.Loaded) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle not ready, asset :" + AssetPathLower); if (this.LoadState == AssetLoadState.Unloaded) throw new VFSException("[TinaX.VFS] Error: Attempt to load an unloaded asset :" + AssetPathLower); if (this._asset == null || this.LoadState != AssetLoadState.Loaded) { this.LoadState = AssetLoadState.Loading; this._asset = this.Bundle.AssetBundle.LoadAsset(this.AssetPathLower); } this.LoadState = AssetLoadState.Loaded; this.LoadTask = UniTask.CompletedTask.ToAsyncLazy(); this.AssetHashCode = this._asset.GetHashCode(); RegisterToBundle(); } public void Load(Type type) { if (this.Bundle == null) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle is null, asset :" + AssetPathLower); if (this.Bundle.LoadState != AssetLoadState.Loaded) throw new VFSException("[TinaX.VFS] Error: Load asset but assetbundle not ready, asset :" + AssetPathLower); if (this.LoadState == AssetLoadState.Unloaded) throw new VFSException("[TinaX.VFS] Error: Attempt to load an unloaded asset :" + AssetPathLower); if (this._asset == null || this.LoadState != AssetLoadState.Loaded) { this.LoadState = AssetLoadState.Loading; this._asset = this.Bundle.AssetBundle.LoadAsset(this.AssetPathLower, type); } this.LoadState = AssetLoadState.Loaded; this.LoadTask = UniTask.CompletedTask.ToAsyncLazy(); this.AssetHashCode = this._asset.GetHashCode(); RegisterToBundle(); } protected void RegisterToBundle() { if(this.Bundle != null) { this.Bundle.RegisterAsset(this); } } #pragma warning disable CA1063 // Implement IDisposable Correctly public void Dispose() #pragma warning restore CA1063 // Implement IDisposable Correctly { this.Release(); } } #if UNITY_EDITOR /// /// 用于从AssetDatabase加载的资源 /// #pragma warning disable CA1063 // Implement IDisposable Correctly public class EditorAsset : IAsset , IRefCounter #pragma warning restore CA1063 // Implement IDisposable Correctly { #region Editor not need counter public int RefCount { get; private set; } = 0; public void Release() { RefCount--; if(RefCount <= 0) { this.Unload(); } } public void Retain() { RefCount++; } #endregion protected UnityEngine.Object _asset; public UnityEngine.Object Asset => _asset; public AssetLoadState LoadState { get; private set; } = AssetLoadState.Loaded; public string AssetPathLower { get; private set; } public int AssetHashCode { get; private set; } public EditorAsset(UnityEngine.Object asset,string lower_path) { _asset = asset; this.AssetPathLower = lower_path; this.AssetHashCode = asset.GetHashCode(); } public EditorAsset(string path_lower) { this.AssetPathLower = path_lower; } public T Get() where T : UnityEngine.Object { return _asset as T; } public UnityEngine.Object Get() { return _asset; } private void Unload() { if (_asset != null) { if (!(_asset is GameObject)) { Resources.UnloadAsset(_asset); } this._asset = null; } this.LoadState = AssetLoadState.Unloaded; } #pragma warning disable CA1063 // Implement IDisposable Correctly public void Dispose() #pragma warning restore CA1063 // Implement IDisposable Correctly { this.Release(); } } #endif }