public UnityObject LoadAssetSync(string address)
        {
            string    assetPath = assetDetailConfig.GetPathByAddress(address);
            AssetNode assetNode = GetAssetNodeSync(assetPath);

            return(assetNode.GetAsset());
        }
        public UnityObject InstanceAssetSync(string address)
        {
            string    assetPath = assetDetailConfig.GetPathByAddress(address);
            AssetNode assetNode = GetAssetNodeSync(assetPath);

            return(assetNode.CreateInstance());
        }
        protected override void OnCreateAssetNodeAsync(AssetNode assetNode)
        {
            string     bundlePath = assetDetailConfig.GetBundleByPath(assetNode.Path);
            BundleNode bundleNode = GetAsyncBundleNode(bundlePath);

            bundleNode.RetainRef();
        }
        private float GetAsyncAssetProgress(string assetPath)
        {
            AssetNode assetNode = assetNodeDic[assetPath];

            if (assetNode.IsLoaded())
            {
                return(1.0f);
            }
            if (!assetNode.IsLoading())
            {
                return(0.0f);
            }
            string bundlePath    = assetDetailConfig.GetBundleByPath(assetPath);
            float  progress      = GetAsycBundleProgress(bundlePath);
            int    progressCount = 1;

            string[] dependBundlePaths = bundleDetailConfig.GetDependencies(bundlePath);
            if (dependBundlePaths != null && dependBundlePaths.Length > 0)
            {
                progressCount += dependBundlePaths.Length;
                foreach (var dbp in dependBundlePaths)
                {
                    progress += GetAsycBundleProgress(dbp);
                }
            }
            if (assetOperationDic.TryGetValue(assetPath, out var loadAsyncOperation))
            {
                progress += loadAsyncOperation.Progress;
            }
            progressCount += 1;
            return(progress / progressCount);
        }
        protected override void OnCreateAssetNodeSync(AssetNode assetNode)
        {
            string assetPath  = assetNode.Path;
            var    bundlePath = assetDetailConfig.GetBundleByPath(assetPath);
            var    bundleNode = bundleNodeDic[bundlePath];

            bundleNode.RetainRef();
        }
        protected override void OnAsyncRequestUpdate(AsyncRequest request)
        {
            var result = request.result;

            string[] assetPaths = request.paths;
            for (int i = 0; i < assetPaths.Length; i++)
            {
                if (result.IsDoneAt(i))
                {
                    continue;
                }

                string    assetPath = assetPaths[i];
                AssetNode assetNode = assetNodeDic[assetPath];
                if (assetNode.IsLoaded())
                {
                    if (request.isInstance)
                    {
                        request.SetUObject(i, assetNode.CreateInstance());
                    }
                    else
                    {
                        request.SetUObject(i, assetNode.GetAsset());
                    }
                    assetNode.ReleaseRef();
                    continue;
                }
                else
                {
                    string     bundlePath = assetDetailConfig.GetBundleByPath(assetPath);
                    BundleNode bundleNode = bundleNodeDic[bundlePath];
                    if (bundleNode.IsDone && !assetOperationDic.ContainsKey(assetPath))
                    {
                        BundleAssetAsyncOperation assetOperation = assetOperationPool.Get();
                        assetOperation.DoInitilize(assetPath);
                        assetOperation.OnOperationComplete = OnAssetFromBundleCreated;

                        assetOperationDic.Add(assetPath, assetOperation);
                        operationLDic.Add(assetPath, assetOperation);
                    }
                    request.SetProgress(i, GetAsyncAssetProgress(assetPath));
                }
            }
            if (result.IsDone())
            {
                if (request.isInstance)
                {
                    request.state = RequestState.InstanceFinished;
                }
                else
                {
                    request.state = RequestState.LoadFinished;
                }
            }
        }
        protected override void OnAsyncRequestUpdate(AsyncRequest request)
        {
            var result = request.result;

            string[] assetPaths = request.paths;
            for (int i = 0; i < assetPaths.Length; i++)
            {
                if (result.IsDoneAt(i))
                {
                    continue;
                }

                string    assetPath = assetPaths[i];
                AssetNode assetNode = assetNodeDic[assetPath];
                if (assetNode.IsLoaded())
                {
                    if (request.isInstance)
                    {
                        request.SetUObject(i, assetNode.CreateInstance());
                    }
                    else
                    {
                        request.SetUObject(i, assetNode.GetAsset());
                    }
                    assetNode.ReleaseRef();
                    continue;
                }
                else
                {
                    if (!operationLDic.TryGetValue(assetPath, out var assetOperation))
                    {
                        assetOperation = assetOperationPool.Get();
                        assetOperation.DoInitilize(assetPath);
                        assetOperation.OnOperationComplete = OnAssetLoadCompleted;

                        operationLDic.Add(assetPath, assetOperation);
                    }

                    request.SetProgress(i, assetOperation.Progress);
                }
            }
            if (result.IsDone())
            {
                if (request.isInstance)
                {
                    request.state = RequestState.InstanceFinished;
                }
                else
                {
                    request.state = RequestState.LoadFinished;
                }
            }
        }
        public void UnloadUnusedAssets()
        {
            var keys = assetNodeDic.Keys;

            foreach (var key in keys)
            {
                AssetNode node = assetNodeDic[key];
                if (!node.IsInUsing())
                {
                    OnReleaseAssetNode(node);
                    assetNodeDic.Remove(key);
                    assetNodePool.Release(node);
                }
            }
        }
 protected override void OnReleaseAssetNode(AssetNode assetNode)
 {
 }
 protected override void OnCreateAssetNodeSync(AssetNode assetNode)
 {
 }
 protected abstract void OnReleaseAssetNode(AssetNode assetNode);
 protected abstract void OnCreateAssetNodeAsync(AssetNode assetNode);
        public void DoUdpate(float deltaTime, float unscaleDeltaTime)
        {
            if (State == LoaderState.Initializing)
            {
                if (OnInitializeUpdate(deltaTime))
                {
                    if (State == LoaderState.Initialized)
                    {
                        State = LoaderState.Running;
                        initializedCallback?.Invoke(true);
                    }
                    else
                    {
                        initializedCallback?.Invoke(false);
                    }
                }
                return;
            }

            if (State != LoaderState.Running)
            {
                return;
            }

            if (operationLDic.Count > 0 && operationCount < OperationMaxCount)
            {
                int diffCount = OperationMaxCount - operationCount;
                for (int i = 0; i < operationLDic.Count; i++)
                {
                    if (!operationLDic[i].IsRunning)
                    {
                        operationLDic[i].DoStart();
                        diffCount--;
                    }
                    if (diffCount <= 0)
                    {
                        break;
                    }
                }
            }

            for (int i = runningRequestList.Count - 1; i >= 0; --i)
            {
                AsyncRequest request = runningRequestList[i];
                if (request.state == RequestState.Instancing || request.state == RequestState.Loading)
                {
                    OnAsyncRequestUpdate(request);
                }
                if (request.state == RequestState.WaitingForInstance)
                {
                    request.state = RequestState.Instancing;
                }
                else if (request.state == RequestState.LoadFinished && request.isInstance)
                {
                    request.state = RequestState.WaitingForInstance;
                }
                else if ((request.state == RequestState.LoadFinished && !request.isInstance) ||
                         (request.state == RequestState.InstanceFinished && request.isInstance))
                {
                    OnAsyncRequestEnd(request);
                    requestDic.Remove(request.id);
                    runningRequestList.RemoveAt(i);
                    resultDic.Remove(request.id);
                    resultPool.Release(request.result);
                    requestPool.Release(request);
                }
            }

            while (waitingRequestQueue.Count > 0 && (operationCount < OperationMaxCount))
            {
                AsyncRequest request = waitingRequestQueue.Dequeue();
                request.state = RequestState.Loading;

                string[] assetPaths = request.paths;
                for (int i = 0; i < assetPaths.Length; i++)
                {
                    string    assetPath = assetPaths[i];
                    AssetNode assetNode = GetAssetNodeAsync(assetPath);
                    assetNode.RetainRef();
                }

                OnAsyncRequestStart(request);

                runningRequestList.Add(request);
            }

            if (unloadOperation != null)
            {
                if (unloadOperation.isDone)
                {
                    if (OnUnloadAssetsUpdate())
                    {
                        unloadFinishedCallbacks.Clear();
                        unloadOperation = null;
                    }
                }
            }
        }
        protected override void OnReleaseAssetNode(AssetNode assetNode)
        {
            string bundlePath = assetDetailConfig.GetBundleByPath(assetNode.Path);

            TryToReleaseBundleNode(bundlePath);
        }