예제 #1
0
            void OnInstantComplete(TObject res)
            {
                Validate();
                SetResult(res);
                var go = Result as GameObject;

                if (go != null)
                {
                    if (m_InstParams.Parent != null)
                    {
                        go.transform.SetParent(m_InstParams.Parent);
                    }
                    if (m_InstParams.SetPositionRotation)
                    {
                        if (m_InstParams.InstantiateInWorldPosition)
                        {
                            go.transform.position = m_InstParams.Position;
                            go.transform.rotation = m_InstParams.Rotation;
                        }
                        else
                        {
                            go.transform.SetPositionAndRotation(m_InstParams.Position, m_InstParams.Rotation);
                        }
                    }
                }
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.InstantiateAsyncCompletion, Context, Time.frameCount - m_StartFrame);
                InvokeCompletionEvent();
            }
예제 #2
0
        /// <summary>
        /// Release a completed IAsyncOperation back into the cache.  ResetStatus will be called on the operation before it is used again.
        /// </summary>
        /// <param name="operation">The operation to release.</param>
        public void Release(IAsyncOperation operation)
        {
            if (operation == null)
            {
                throw new ArgumentNullException("operation");
            }
            operation.Validate();

            Stack <IAsyncOperation> operationStack;

            if (!m_Cache.TryGetValue(operation.GetType(), out operationStack))
            {
                m_Cache.Add(operation.GetType(), operationStack = new Stack <IAsyncOperation>(5));
            }
            operationStack.Push(operation);

#if POST_ASYNCOPERATIONCACHE__EVENTS
            Stats stat;
            if (!m_stats.TryGetValue(operation.GetType(), out stat))
            {
                m_stats.Add(operation.GetType(), stat = new Stats()
                {
                    m_name = string.Format("AsyncOperationCache[{0}]", operation.GetType().Name)
                });
            }
            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.AsyncOpCacheCount, stat.m_name, operationStack.Count);
#endif
        }
 void OnSceneUnloaded(AsyncOperation operation)
 {
     Validate();
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.ReleaseSceneAsyncCompletion, Context, 0);
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheEntryLoadPercent, Context, 0);
     SetResult(m_Scene);
     InvokeCompletionEvent();
 }
예제 #4
0
            public T Get <T>() where T : class
            {
                m_LastRefTime = Time.unscaledTime;
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.PoolCount, m_Location, m_Instances.Count - 1);
                var o = m_Instances.Pop() as T;

                (o as GameObject).SetActive(true);
                return(o);
            }
예제 #5
0
 void ReleaseInternal(IResourceProvider provider, IResourceLocation location)
 {
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.Release, location, Time.frameCount);
     provider.Release(location, null);
     for (int i = 0; location.Dependencies != null && i < location.Dependencies.Count; i++)
     {
         ReleaseInternal(ResourceManager.GetResourceProvider <object>(location.Dependencies[i]), location.Dependencies[i]);
     }
 }
 internal void ReleaseAssets(IResourceProvider provider)
 {
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheEntryLoadPercent, location, 0);
     foreach (var e in entries)
     {
         Debug.Assert(e.IsDone);
         provider.Release(location, e.Result);
         e.ReleaseInternalOperation();
     }
 }
        /// <summary>
        /// Provide the requested object.  The cache will be checked first for existing objects.  If not found, the internal IResourceProvider will be used to provide the object.  The reference count for the asset will be incremented.
        /// </summary>
        /// <typeparam name="TObject"></typeparam>
        /// <param name="location"></param>
        /// <param name="loadDependencyOperation"></param>
        /// <returns></returns>
        public IAsyncOperation <TObject> Provide <TObject>(IResourceLocation location, IAsyncOperation <IList <object> > loadDependencyOperation)
            where TObject : class
        {
            if (location == null)
            {
                throw new ArgumentNullException("location");
            }

            CacheList entryList;

            if (!m_Cache.TryGetValue(location.GetHashCode(), out entryList))
            {
                if (m_Lru != null && m_Lru.Count > 0)
                {
                    var node = m_Lru.First;
                    while (node != null)
                    {
                        if (node.Value.location.GetHashCode() == location.GetHashCode())
                        {
                            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheEntryLoadPercent, location, 1);
                            entryList = node.Value;
                            m_Lru.Remove(node);
                            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheLruCount, ProviderId, m_Lru.Count);
                            break;
                        }
                        node = node.Next;
                    }
                }
                if (entryList == null)
                {
                    entryList = new CacheList(location);
                }

                m_Cache.Add(location.GetHashCode(), entryList);
            }

            entryList.Retain();
            var entry = entryList.FindEntry <TObject>(location);

            if (entry != null)
            {
                if (entry.Status == AsyncOperationStatus.Failed)
                {
                    m_InternalProvider.Release(location, entry.Result);
                    entry.ReleaseInternalOperation();
                    entryList.entries.Remove(entry);
                }
                else
                {
                    return(entry);
                }
            }
            return(entryList.CreateEntry(m_InternalProvider.Provide <TObject>(location, loadDependencyOperation)));
        }
 void UpdateLru()
 {
     if (m_Lru != null)
     {
         float time = Time.unscaledTime;
         while (m_Lru.Last != null && (m_Lru.Last.Value.lastAccessTime - time) > maxLruAge && m_Lru.Last.Value.IsDone)
         {
             m_Lru.Last.Value.ReleaseAssets(m_InternalProvider);
             m_Lru.RemoveLast();
         }
         ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheLruCount, ProviderId, m_Lru.Count);
     }
 }
예제 #9
0
        /// <summary>
        /// Asynchronously loads the scene a the given <paramref name="location"/>.
        /// </summary>
        /// <returns>Async operation for the scene.</returns>
        /// <param name="location">location of the scene to load.</param>
        /// <param name="loadMode">Scene Load mode.</param>
        public static IAsyncOperation <Scene> ProvideScene(IResourceLocation location, LoadSceneMode loadMode = LoadSceneMode.Single)
        {
            if (SceneProvider == null)
            {
                throw new NullReferenceException("ResourceManager.SceneProvider is null.  Assign a valid ISceneProvider object before using.");
            }
            if (location == null)
            {
                return(new CompletedOperation <Scene>().Start(null, null, default(Scene), new ArgumentNullException("location")));
            }

            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.LoadSceneAsyncRequest, location, 1);
            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheEntryLoadPercent, location, 0);

            return(SceneProvider.ProvideSceneAsync(location, LoadDependencies(location), loadMode).Retain());
        }
예제 #10
0
            void InternalOp_completed(AsyncOperation obj)
            {
                Validate();
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.LoadAsyncCompletion, Context, Time.frameCount - m_StartFrame);
                TObject result = null;

                if (obj is AssetBundleCreateRequest)
                {
                    result = (obj as AssetBundleCreateRequest).assetBundle as TObject;
                }
                SetResult(result);
                InvokeCompletionEvent();
                m_Data.Close();
                m_Data.Dispose();
                m_Data = null;
            }
 void OnComplete(IAsyncOperation <TObject> operation)
 {
     Validate();
     Debug.Assert(operation != null);
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.InstantiateAsyncCompletion, Context, Time.frameCount - m_StartFrame);
     m_PrefabResult = operation.Result;
     if (m_PrefabResult == null)
     {
         OperationException = new Exception(string.Format("Unable to load asset to instantiate from location {0}", Context));
         SetResult(null);
     }
     else if (Result == null)
     {
         SetResult(m_InstParams.Instantiate(m_PrefabResult));
     }
     InvokeCompletionEvent();
 }
예제 #12
0
        /// <summary>
        /// Releases resources belonging to the prefab instance.
        /// </summary>
        /// <param name="instance">Instance to release.</param>
        /// <param name="location">The location of the instance.</param>
        public static void ReleaseInstance(Object instance, IResourceLocation location)
        {
            if (InstanceProvider == null)
            {
                throw new NullReferenceException("ResourceManager.InstanceProvider is null.  Assign a valid IInstanceProvider object before using.");
            }
            if (location == null)
            {
                return;
            }

            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.ReleaseInstance, location, Time.frameCount);
            if (InstanceProvider.ReleaseInstance(GetResourceProvider <Object>(location), location, instance))
            {
                ReleaseResource <object>(null, location);
            }
        }
예제 #13
0
            void OnLoadComplete(IAsyncOperation <TObject> operation)
            {
                Validate();
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.InstantiateAsyncCompletion, Context, Time.frameCount - m_StartFrame);
                m_PrefabResult = operation.Result;

                if (m_PrefabResult == null)
                {
                    Debug.LogWarning("NULL prefab on instantiate: " + Context);
                }
                else if (Result == null)
                {
                    SetResult(m_InstParams.Instantiate(m_PrefabResult));
                }

                InvokeCompletionEvent();
            }
            public IAsyncOperation <Scene> Start(IResourceLocation location, Scene scene)
            {
                Validate();
                m_Scene = scene;
                Context = location;
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.ReleaseSceneAsyncRequest, Context, 0);
                var unloadOp = SceneManager.UnloadSceneAsync(scene);

                if (unloadOp.isDone)
                {
                    DelayedActionManager.AddAction((Action <AsyncOperation>)OnSceneUnloaded, 0, unloadOp);
                }
                else
                {
                    unloadOp.completed += OnSceneUnloaded;
                }
                return(this);
            }
예제 #15
0
 internal bool Update(float releaseTime)
 {
     if (m_Instances.Count > 0)
     {
         if ((m_Instances.Count > 1 && Time.unscaledTime - m_LastReleaseTime > releaseTime) || Time.unscaledTime - m_LastRefTime > (1f / m_Instances.Count) * releaseTime)  //the last item will take releaseTime seconds to drop...
         {
             m_LastReleaseTime = m_LastRefTime = Time.unscaledTime;
             var inst = m_Instances.Pop();
             ReleaseInternal(m_LoadProvider, m_Location);
             Object.Destroy(inst);
             ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.PoolCount, m_Location, m_Instances.Count);
             if (m_Instances.Count == 0 && holdCount == 0)
             {
                 return(false);
             }
         }
     }
     return(true);
 }
        bool ReleaseCache(CacheList entryList)
        {
            if (entryList.Release())
            {
                if (!entryList.IsDone)
                {
                    if (m_RetryReleaseEntryAction == null)
                    {
                        m_RetryReleaseEntryAction = RetryEntryRelease;
                    }
                    entryList.Retain(); //hold on since this will be retried...
                    DelayedActionManager.AddAction(m_RetryReleaseEntryAction, .2f, entryList);
                    return(false);
                }

                if (m_Lru != null)
                {
                    m_Lru.AddFirst(entryList);
                    while (m_Lru.Count > maxLruCount && m_Lru.Last.Value.IsDone)
                    {
                        m_Lru.Last.Value.ReleaseAssets(m_InternalProvider);
                        m_Lru.RemoveLast();
                    }
                    ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheLruCount, ProviderId + " LRU", m_Lru.Count);
                }
                else
                {
                    entryList.ReleaseAssets(m_InternalProvider);
                }

                if (!m_Cache.Remove(entryList.GetHashCode()))
                {
                    Debug.LogWarningFormat("Unable to find entryList {0} in cache.", entryList.location);
                }
                return(true);
            }
            return(false);
        }
예제 #17
0
        /// <summary>
        /// Acquire an IAsyncOperation.
        /// </summary>
        /// <typeparam name="TAsyncOperation">The type of IAsyncOperation to be returned.</typeparam>
        /// <returns>An IAsyncOperation of type TAsyncOperation.</returns>
        public TAsyncOperation Acquire <TAsyncOperation>()
            where TAsyncOperation : IAsyncOperation, new()
        {
            Debug.Assert(m_Cache != null, "AsyncOperationCache.Acquire - m_cache == null.");

            Stack <IAsyncOperation> operationStack;

#if POST_ASYNCOPERATIONCACHE__EVENTS
            Stats stat;
            if (!m_stats.TryGetValue(typeof(TAsyncOperation), out stat))
            {
                m_stats.Add(typeof(TAsyncOperation), stat = new Stats()
                {
                    m_name = string.Format("AsyncOperationCache[{0}]", typeof(TAsyncOperation).Name)
                });
            }
#endif
            if (m_Cache.TryGetValue(typeof(TAsyncOperation), out operationStack) && operationStack.Count > 0)
            {
                var op = (TAsyncOperation)operationStack.Pop();
                op.IsValid = true;
                op.ResetStatus();
#if POST_ASYNCOPERATIONCACHE__EVENTS
                stat.m_hits++;
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.AsyncOpCacheHitRatio, stat.m_name, stat.Value);
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.AsyncOpCacheCount, stat.m_name, operationStack.Count);
#endif
                return(op);
            }
#if POST_ASYNCOPERATIONCACHE__EVENTS
            stat.m_misses++;
            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.AsyncOpCacheHitRatio, stat.m_name, stat.Value);
#endif
            var op2 = new TAsyncOperation();
            op2.IsValid = true;
            op2.ResetStatus();
            return(op2);
        }
예제 #18
0
        /// <summary>
        /// Release resources belonging to the <paramref name="asset"/> at the specified <paramref name="location"/>.
        /// </summary>
        /// <param name="asset">Object to release.</param>
        /// <param name="location">The location of the resource to release.</param>
        /// <typeparam name="TObject">Object type.</typeparam>
        public static void ReleaseResource <TObject>(TObject asset, IResourceLocation location)
            where TObject : class
        {
            if (location == null)
            {
                return;
            }
            var provider = GetResourceProvider <TObject>(location);

            if (provider == null)
            {
                return;
            }
            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.Release, location, Time.frameCount);
            provider.Release(location, asset);
            if (location.HasDependencies)
            {
                foreach (var dep in location.Dependencies)
                {
                    ReleaseResource <object>(null, dep);
                }
            }
        }
예제 #19
0
        /// <summary>
        /// Asynchronouslly instantiate a prefab (GameObject) at the specified <paramref name="location"/>.
        /// </summary>
        /// <returns>Async operation that will complete when the prefab is instantiated.</returns>
        /// <param name="location">location of the prefab.</param>
        /// <param name="instantiateParameters">A struct containing the parameters to pass the the Instantiation call.</param>
        /// <typeparam name="TObject">Instantiated object type.</typeparam>
        public static IAsyncOperation <TObject> ProvideInstance <TObject>(IResourceLocation location, InstantiationParameters instantiateParameters)
            where TObject : Object
        {
            if (InstanceProvider == null)
            {
                throw new NullReferenceException("ResourceManager.InstanceProvider is null.  Assign a valid IInstanceProvider object before using.");
            }

            if (location == null)
            {
                return(new CompletedOperation <TObject>().Start(null, null, default(TObject), new ArgumentNullException("location")));
            }
            var provider = GetResourceProvider <TObject>(location);

            if (provider == null)
            {
                return(new CompletedOperation <TObject>().Start(location, location, default(TObject), new UnknownResourceProviderException(location)));
            }

            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.InstantiateAsyncRequest, location, Time.frameCount);
            ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.LoadAsyncRequest, location, Time.frameCount);

            return(InstanceProvider.ProvideInstanceAsync <TObject>(provider, location, LoadDependencies(location), instantiateParameters).Retain());
        }
        internal bool InitInternal(IResourceProvider provider, string providerId, int maxCacheItemCount, float maxCacheItemAge)
        {
            if (provider == null || string.IsNullOrEmpty(providerId))
            {
                return(false);
            }

            m_InternalProvider = provider;
            m_ProviderId       = providerId;
            maxLruCount        = maxCacheItemCount;
            if (maxLruCount > 0)
            {
                m_Lru     = new LinkedList <CacheList>();
                maxLruAge = maxCacheItemAge;
                if (maxCacheItemAge > 0)
                {
                    var go = new GameObject("CachedProviderUpdater", typeof(CachedProviderUpdater));
                    go.GetComponent <CachedProviderUpdater>().Init(this);
                    go.hideFlags = HideFlags.HideAndDontSave;
                }
                ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheLruCount, ProviderId, m_Lru.Count);
            }
            return(true);
        }
예제 #21
0
 protected virtual void OnComplete()
 {
     Validate();
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.LoadAsyncCompletion, Context, Time.frameCount - m_StartFrame);
     InvokeCompletionEvent();
 }
 internal bool Release()
 {
     refCount--;
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheEntryRefCount, location, refCount);
     return(refCount == 0);
 }
 internal void Retain()
 {
     lastAccessTime = Time.unscaledTime;
     refCount++;
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.CacheEntryRefCount, location, refCount);
 }
예제 #24
0
 public void Put(Object gameObject)
 {
     (gameObject as GameObject).SetActive(false);
     m_Instances.Push(gameObject);
     ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.PoolCount, m_Location, m_Instances.Count);
 }