internal override void Init()
 {
     CoreLog.DebugFormat("[ResourceCache Reuse] {0}", Path);
     Owner.m_ResourcePathsNotReadyOrFailure.Add(Path);
     Status = ResourceCacheStatus.WaitingForSlot;
     StartTicking();
 }
 internal override void Init()
 {
     InternalLog.DebugFormat("[ResourceCache Reuse] {0}", Path);
     Owner.m_ResourcePathsNotReadyOrFailure.Add(Path);
     Status = ResourceCacheStatus.WaitingForSlot;
     Owner.m_WaitingForSlotResourceCaches.Add(this);
 }
                internal override void OnSlotReady()
                {
                    if (Status != ResourceCacheStatus.WaitingForSlot)
                    {
                        throw new InvalidOperationException($"Oops! '{nameof(OnSlotReady)}' cannot be called on status '{Status}'.");
                    }

                    m_LoadingTask = Owner.RunResourceLoadingTask(Path,
                                                                 ShouldLoadFromReadWritePath ? Owner.ReadWritePath : Owner.InstallerPath);
                    InternalLog.DebugFormat("[ResourceCache Update] {0} start loading", Path);
                    Status = ResourceCacheStatus.Loading;
                    StartTicking();
                }
                internal override void Reset()
                {
                    InternalLog.DebugFormat("[ResourceCache Reset] {0}", Path);

                    m_CopiedResourceObservers.Clear();
                    m_ResourceObservers.Clear();

                    StopTicking();
                    StopAndResetLoadingTask();

                    if (ResourceObject != null)
                    {
                        Owner.ResourceDestroyer.Destroy(ResourceObject);
                    }

                    ResourceObject = null;
                    ShouldLoadFromReadWritePath = false;
                    Status = ResourceCacheStatus.None;
                    Owner.m_ResourcePathsNotReadyOrFailure.Remove(Path);
                    base.Reset();
                }
                private void SucceedAndNotify()
                {
                    Status = ResourceCacheStatus.Ready;
                    Owner.m_ResourcePathsNotReadyOrFailure.Remove(Path);
                    StopAndResetLoadingTask();

                    m_CopiedResourceObservers.Clear();
                    m_CopiedResourceObservers.AddRange(m_ResourceObservers);
                    foreach (var resourceObserver in m_CopiedResourceObservers)
                    {
                        resourceObserver.OnLoadResourceSuccess(Path, ResourceObject);
                    }

                    m_CopiedResourceObservers.Clear();

                    m_ResourceObservers.Clear();

                    if (RetainCount <= 0)
                    {
                        MarkAsUnretained();
                    }
                }
                protected override void Update(TimeStruct timeStruct)
                {
                    switch (Status)
                    {
                    case ResourceCacheStatus.WaitingForSlot:
                        if (Owner.m_RunningResourceLoadingTasks.Count < Owner.m_RunningResourceLoadingTasks.Capacity)
                        {
                            m_LoadingTask = Owner.RunResourceLoadingTask(Path,
                                                                         ShouldLoadFromReadWritePath ? Owner.ReadWritePath : Owner.InstallerPath);
                            CoreLog.DebugFormat("[ResourceCache Update] {0} start loading", Path);
                            Status = ResourceCacheStatus.Loading;
                        }

                        break;

                    case ResourceCacheStatus.Loading:
                        if (!string.IsNullOrEmpty(m_LoadingTask.ErrorMessage))
                        {
                            ErrorMessage = m_LoadingTask.ErrorMessage;

                            CoreLog.DebugFormat("[ResourceCache Update] {0} loading fail", Path);
                            FailAndNotify();
                        }
                        else if (m_LoadingTask.IsDone)
                        {
                            ResourceObject = m_LoadingTask.ResourceObject;

                            CoreLog.DebugFormat("[ResourceCache Update] {0} loading success", Path);
                            SucceedAndNotify();
                        }

                        break;

                    default:
                        break;
                    }
                }
                private void FailAndNotify()
                {
                    Status = ResourceCacheStatus.Failure;
                    Owner.m_ResourcePathsNotReadyOrFailure.Remove(Path);

                    StopTicking();
                    StopAndResetLoadingTask();

                    m_CopiedResourceObservers.Clear();
                    m_CopiedResourceObservers.AddRange(m_ResourceObservers);
                    foreach (var resourceObserver in m_CopiedResourceObservers)
                    {
                        resourceObserver.OnLoadResourceFailure(Path, ErrorMessage);
                    }

                    m_CopiedResourceObservers.Clear();

                    m_ResourceObservers.Clear();

                    if (RetainCount <= 0)
                    {
                        MarkAsUnretained();
                    }
                }