/// <summary>
        /// 回收一个资源
        /// </summary>
        /// <param name="item"></param>
        /// <param name="destroy"></param>
        protected void DestroyResouceItem(TResouceItem item, bool destroyCache = false)
        {
            if (item == null || item.RefCount > 0)
            {
                return;
            }
            if (!destroyCache)
            {
                mNoRefrenceAssetMapList.InsertToHead(item);
                return;
            }
            if (!mAssetDic.Remove(item.Crc))
            {
                return;
            }

            mNoRefrenceAssetMapList.Remove(item);
            // 释放assetbundle引用
            AssetBundleManager.Instance.ReleaseAsset(item);

            //清空资源对应的对象池
            ObjectManager.Instance.ClearPoolObject(item.Crc);

            if (item.Obj != null)
            {
                item.Obj = null;
#if UNITY_EDITOR
                Resources.UnloadUnusedAssets();
#endif
            }
        }
Example #2
0
        /// <summary>
        /// 根据crc查找ResourceItem
        /// </summary>
        /// <param name="crc"></param>
        /// <returns></returns>
        public TResouceItem FindResouceItem(uint crc)
        {
            TResouceItem item = null;

            mResouceItemDic.TryGetValue(crc, out item);
            return(item);
        }
        /// <summary>
        /// 针对ObjectManager异步加载的接口
        /// </summary>
        /// <param name="path"></param>
        /// <param name="resObj"></param>
        /// <param name="dealfinish"></param>
        /// <param name="priority"></param>
        public void AsyncLoadResouce(string path, TResouceObj resObj, OnAsyncFinish dealfinish, LoadResPriority priority)
        {
            TResouceItem item = GetCacheResouceItem(resObj.Crc);

            if (item != null)
            {
                resObj.ResItem = item;
                dealfinish?.Invoke(path, resObj);
            }
            //判断是否在加载中
            TAsyncLoadResParam para = null;

            if (!mLoadingAssetDic.TryGetValue(resObj.Crc, out para) || para == null)
            {
                para          = mAsyncLoadResParamPool.Allocate();
                para.Crc      = resObj.Crc;
                para.Path     = path;
                para.Priority = priority;
                mLoadingAssetDic.Add(resObj.Crc, para);
                mLoadingAssetList[(int)priority].Add(para);
            }
            //往回调列表里面加回调
            TAsyncCallBack callBack = mAsyncCallBackPool.Allocate();

            callBack.DealFinish = dealfinish;
            callBack.ResObj     = resObj;
            para.CallbackList.Add(callBack);
        }
        /// <summary>
        /// 缓存加载的资源
        /// </summary>
        /// <param name="path"></param>
        /// <param name="item"></param>
        /// <param name="crc"></param>
        /// <param name="obj"></param>
        /// <param name="addrefcount"></param>
        void CacheResouce(string path, ref TResouceItem item, uint crc, Object obj, int addrefcount = 1)
        {
            //缓存太多,清除最早没有使用的资源
            WashOut();

            if (item == null)
            {
                Debug.LogError("ResourceItem is null,path:" + path);
            }
            if (obj == null)
            {
                Debug.LogError("Resource Fail:" + path);
            }
            item.Obj          = obj;
            item.Guid         = obj.GetInstanceID();
            item.LastUserTime = Time.realtimeSinceStartup;
            item.RefCount    += addrefcount;
            TResouceItem oldItem = null;

            if (mAssetDic.TryGetValue(item.Crc, out oldItem))
            {
                mAssetDic[item.Crc] = item;
            }
            else
            {
                mAssetDic.Add(item.Crc, item);
            }
        }
        /// <summary>
        /// 同步资源加载,外部直接调用,仅加载不需要实例化的资源,例如Texture,音频等等
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns></returns>
        public T LoadResouce <T>(string path) where T : UnityEngine.Object
        {
            if (string.IsNullOrEmpty(path))
            {
                return(null);
            }
            uint         crc  = CRC32.GetCRC32(path);
            TResouceItem item = GetCacheResouceItem(crc);

            if (item != null)
            {
                return(item.Obj as T);
            }
            T obj = null;

#if UNITY_EDITOR
            if (!AppConfig.UseAssetBundle)
            {
                item = AssetBundleManager.Instance.FindResouceItem(crc);
                if (item != null && item.AssetBundle != null)
                {
                    if (item.Obj != null)
                    {
                        obj = (T)item.Obj;
                    }
                    else
                    {
                        obj = item.AssetBundle.LoadAsset <T>(item.AssetName);
                    }
                }
                else
                {
                    if (item == null)
                    {
                        item     = new TResouceItem();
                        item.Crc = crc;
                    }
                    obj = LoadAssetByEditor <T>(path);
                }
            }
#endif
            if (obj == null)
            {
                item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc);
                if (item != null && item.AssetBundle != null)
                {
                    if (item.Obj != null)
                    {
                        obj = item.Obj as T;
                    }
                    else
                    {
                        obj = item.AssetBundle.LoadAsset <T>(item.AssetName);
                    }
                }
            }
            CacheResouce(path, ref item, crc, obj);
            return(obj);
        }
        /// <summary>
        /// 同步资源加载,外部直接调用,仅加载不需要实例化的资源,例如Texture,音频等
        /// </summary>
        /// <param name="path"></param>
        /// <param name="resObj"></param>
        /// <returns></returns>
        public TResouceObj LoadResouce(string path, TResouceObj resObj)
        {
            if (resObj == null)
            {
                return(null);
            }
            uint         crc  = resObj.Crc == 0 ? CRC32.GetCRC32(path) : resObj.Crc;
            TResouceItem item = GetCacheResouceItem(crc);

            if (item != null)
            {
                resObj.ResItem = item;
                return(resObj);
            }
            Object obj = null;

#if UNITY_EDITOR
            if (!AppConfig.UseAssetBundle)
            {
                item = AssetBundleManager.Instance.FindResouceItem(crc);
                if (item != null && item.Obj != null)
                {
                    obj = item.Obj as Object;
                }
                else
                {
                    if (item == null)
                    {
                        item     = new TResouceItem();
                        item.Crc = crc;
                    }
                    obj = LoadAssetByEditor <Object>(path);
                }
            }
#endif
            if (obj == null)
            {
                item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc);
                if (item != null && item.AssetBundle != null)
                {
                    if (item.Obj != null)
                    {
                        obj = item.Obj as Object;
                    }
                    else
                    {
                        obj = item.AssetBundle.LoadAsset <Object>(item.AssetName);
                    }
                }
            }
            CacheResouce(path, ref item, crc, obj);
            resObj.ResItem = item;
            item.Clear     = resObj.Clear;


            return(resObj);
        }
        /// <summary>
        /// 预加载资源
        /// </summary>
        /// <param name="path"></param>
        public void PreloadRes(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            uint         crc  = CRC32.GetCRC32(path);
            TResouceItem item = GetCacheResouceItem(crc, 0);

            if (item != null)
            {
                return;
            }
            Object obj = null;

#if UNITY_EDITOR
            if (!AppConfig.UseAssetBundle)
            {
                item = AssetBundleManager.Instance.FindResouceItem(crc);
                if (item != null && item.Obj != null)
                {
                    obj = item.Obj as Object;
                }
                else
                {
                    if (item == null)
                    {
                        item     = new TResouceItem();
                        item.Crc = crc;
                    }
                    obj = LoadAssetByEditor <Object>(path);
                }
            }
#endif
            if (obj == null)
            {
                item = AssetBundleManager.Instance.LoadResouceAssetBundle(crc);
                if (item != null && item.AssetBundle != null)
                {
                    if (item.Obj != null)
                    {
                        obj = item.Obj;
                    }
                    else
                    {
                        obj = item.AssetBundle.LoadAsset <Object>(item.AssetName);
                    }
                }
            }
            CacheResouce(path, ref item, crc, obj);
            //跳场景不清空缓存
            item.Clear = false;
            ReleaseResouce(obj, false);
        }
        /// <summary>
        /// 根据路径减少引用计数
        /// </summary>
        /// <param name="crc"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int DecreaseResouceRef(uint crc = 0, int count = 1)
        {
            TResouceItem item = null;

            if (!mAssetDic.TryGetValue(crc, out item) || item == null)
            {
                return(0);
            }
            item.RefCount -= count;
            return(item.RefCount);
        }
 /// <summary>
 /// 缓存太多,清除最早没有使用的资源
 /// </summary>
 protected void WashOut()
 {
     //当大于缓存个数时,进行一半释放
     while (mNoRefrenceAssetMapList.Size() >= MAXCACHECOUNT)
     {
         for (int i = 0; i < MAXCACHECOUNT / 2; i++)
         {
             TResouceItem item = mNoRefrenceAssetMapList.Back();
             DestroyResouceItem(item, true);
         }
     }
 }
        /// <summary>
        /// 根据path增加引用计数
        /// </summary>
        /// <param name="crc"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public int IncreaseResouceRef(uint crc = 0, int count = 1)
        {
            TResouceItem item = null;

            if (!mAssetDic.TryGetValue(crc, out item) || item == null)
            {
                return(0);
            }
            item.RefCount    += count;
            item.LastUserTime = Time.realtimeSinceStartup;
            return(item.RefCount);
        }
        /// <summary>
        /// 从资源池获取缓存资源
        /// </summary>
        /// <param name="crc"></param>
        /// <param name="addrefcount"></param>
        /// <returns></returns>
        TResouceItem GetCacheResouceItem(uint crc, int addrefcount = 1)
        {
            TResouceItem item = null;

            if (mAssetDic.TryGetValue(crc, out item))
            {
                if (item != null)
                {
                    item.RefCount    += addrefcount;
                    item.LastUserTime = Time.realtimeSinceStartup;
                }
            }
            return(item);
        }
Example #12
0
 /// <summary>
 /// 释放资源
 /// </summary>
 /// <param name="item"></param>
 public void ReleaseAsset(TResouceItem item)
 {
     if (item == null)
     {
         return;
     }
     if (item.DependAssetBundle != null && item.DependAssetBundle.Count > 0)
     {
         for (int i = 0; i < item.DependAssetBundle.Count; i++)
         {
             UnLoadAssetBundle(item.DependAssetBundle[i]);
         }
     }
     UnLoadAssetBundle(item.AbName);
 }
 public void Reset()
 {
     Crc            = 0;
     CloneObj       = null;
     Clear          = true;
     Guid           = 0;
     ResItem        = null;
     Already        = false;
     SetSceneParent = false;
     DealFinish     = null;
     Param1         = null;
     Param2         = null;
     Param3         = null;
     OffData        = null;
 }
        /// <summary>
        /// 根据ResouceObj卸载资源
        /// </summary>
        /// <param name="resObj"></param>
        /// <param name="destroyObj">是否将ResouceItem从缓存引用计数的资源列表中移除</param>
        /// <returns></returns>
        public bool ReleaseResouce(TResouceObj resObj, bool destroyObj = false)
        {
            if (resObj == null)
            {
                return(false);
            }
            TResouceItem item = null;

            if (!mAssetDic.TryGetValue(resObj.Crc, out item) || item == null)
            {
                Debug.LogError("AssetDic里不存在该资源:" + resObj.CloneObj.name + " 可能释放了多次");
            }
            GameObject.Destroy(resObj.CloneObj);
            item.RefCount--;
            DestroyResouceItem(item, destroyObj);
            return(true);
        }
        /// <summary>
        /// 不需要实例化的资源卸载,根据路径
        /// </summary>
        /// <param name="path"></param>
        /// <param name="destroyObj"></param>
        /// <returns></returns>
        public bool ReleaseResouce(string path, bool destroyObj = false)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(false);
            }
            uint         crc  = CRC32.GetCRC32(path);
            TResouceItem item = null;

            if (!mAssetDic.TryGetValue(crc, out item) || null == item)
            {
                Debug.LogError("AssetDic里不存在资源" + path + "可能释放了多次");
            }

            item.RefCount--;
            DestroyResouceItem(item, destroyObj);
            return(true);
        }
Example #16
0
        /// <summary>
        /// 加载Ab配置表
        /// </summary>
        /// <returns></returns>
        public bool LoadAssetBundleConfig()
        {
#if UNITY_EDITOR
            if (!AppConfig.UseAssetBundle)
            {
                return(false);
            }
#endif
            mResouceItemDic.Clear();
            string configPath = ABLoadPath + mAbConfigABName;
            string hotAbPath  = HotPatchManager.Instance.ComputeABPath(mAbConfigABName);
            configPath = string.IsNullOrEmpty(hotAbPath) ? configPath : hotAbPath;
            byte[]      bytes     = AES.AESFileByteDecrypt(configPath, EdgeFrameworkConst.AESKEY);
            AssetBundle configAB  = AssetBundle.LoadFromMemory(bytes);
            TextAsset   textAsset = configAB.LoadAsset <TextAsset>(mAbConfigABName);
            if (textAsset == null)
            {
                Debug.LogError("AssetBundleConfig is no exist!");
                return(false);
            }
            MemoryStream      stream = new MemoryStream(textAsset.bytes);
            BinaryFormatter   bf     = new BinaryFormatter();
            AssetBundleConfig config = (AssetBundleConfig)bf.Deserialize(stream);
            stream.Close();
            for (int i = 0; i < config.AbList.Count; i++)
            {
                ABBase       abBase = config.AbList[i];
                TResouceItem item   = new TResouceItem();
                item.Crc               = abBase.Crc;
                item.AssetName         = abBase.AssetName;
                item.AbName            = abBase.AbName;
                item.DependAssetBundle = abBase.AbDependce;
                if (mResouceItemDic.ContainsKey(item.Crc))
                {
                    Debug.LogError("重复的Crc:" + item.AssetName + "ab包名:" + item.AbName);
                }
                else
                {
                    mResouceItemDic.Add(item.Crc, item);
                }
            }
            return(true);
        }
        /// <summary>
        /// 异步加载资源(仅仅是不需要实例化的资源,例如音频,图片等)
        /// </summary>
        /// <param name="path"></param>
        /// <param name="dealFinish"></param>
        /// <param name="priority"></param>
        /// <param name="param1"></param>
        /// <param name="param2"></param>
        /// <param name="param3"></param>
        /// <param name="crc"></param>
        public void AsyncLoadResouce(string path, OnAsyncObjFinish dealFinish, LoadResPriority priority, bool isSprite = false, object param1 = null, object param2 = null, object param3 = null, uint crc = 0)
        {
            if (crc == 0)
            {
                crc = CRC32.GetCRC32(path);
            }
            TResouceItem item = GetCacheResouceItem(crc);

            if (item != null)
            {
                if (dealFinish != null)
                {
                    dealFinish(path, item.Obj, param1, param2, param3);
                }
                return;
            }
            //判断是否在加载中
            TAsyncLoadResParam para = null;

            if (!mLoadingAssetDic.TryGetValue(crc, out para) || para == null)
            {
                para          = mAsyncLoadResParamPool.Allocate();
                para.Crc      = crc;
                para.Path     = path;
                para.IsSprite = isSprite;
                para.Priority = priority;
                mLoadingAssetDic.Add(crc, para);
                mLoadingAssetList[(int)priority].Add(para);
            }
            //往回调列表里面加回调
            TAsyncCallBack callBack = mAsyncCallBackPool.Allocate();

            callBack.DealObjFinish = dealFinish;

            callBack.Param1 = param1;
            callBack.Param2 = param2;
            callBack.Param3 = param3;
            para.CallbackList.Add(callBack);
        }
Example #18
0
        /// <summary>
        /// 根据路径的crc加载中间类ResouceItem
        /// </summary>
        /// <param name="crc"></param>
        /// <returns></returns>
        public TResouceItem LoadResouceAssetBundle(uint crc)
        {
            TResouceItem item = null;

            if (!mResouceItemDic.TryGetValue(crc, out item) || item == null)
            {
                Debug.LogError(string.Format("LoadResourceAssetBundle Erro:can not find crc {0} in AssetBundleConfig", crc.ToString()));
                return(item);
            }
            //if (item.assetBundle != null)
            //{
            //    item.RefCount++;
            //    return item;
            //}
            item.AssetBundle = LoadAssetBundle(item.AbName);
            if (item.DependAssetBundle != null)
            {
                for (int i = 0; i < item.DependAssetBundle.Count; i++)
                {
                    LoadAssetBundle(item.DependAssetBundle[i]);
                }
            }
            return(item);
        }
        /// <summary>
        /// 不需要实例化的资源卸载,根据对象
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="destroyObj"></param>
        /// <returns></returns>
        public bool ReleaseResouce(Object obj, bool destroyObj = false)
        {
            if (obj == null)
            {
                return(false);
            }
            TResouceItem item = null;

            foreach (TResouceItem res in mAssetDic.Values)
            {
                if (res.Guid == obj.GetInstanceID())
                {
                    item = res;
                }
            }
            if (item == null)
            {
                Debug.LogError("AssetDic里不存在资源" + obj.name + "可能释放了多次");
                return(false);
            }
            item.RefCount--;
            DestroyResouceItem(item, destroyObj);
            return(true);
        }
        /// <summary>
        /// 异步加载
        /// </summary>
        /// <returns></returns>
        IEnumerator AsyncLoadCor()
        {
            List <TAsyncCallBack> callBackList = null;
            //上一次yild的时间
            long lastYildTime = System.DateTime.Now.Ticks;

            while (true)
            {
                bool haveYield = false;
                for (int i = 0; i < (int)LoadResPriority.RES_NUM; i++)
                {
                    if (mLoadingAssetList[(int)LoadResPriority.RES_HIGHT].Count > 0)
                    {
                        i = (int)LoadResPriority.RES_HIGHT;
                    }
                    else if (mLoadingAssetList[(int)LoadResPriority.RES_MIDDLE].Count > 0)
                    {
                        i = (int)LoadResPriority.RES_MIDDLE;
                    }

                    List <TAsyncLoadResParam> loadingList = mLoadingAssetList[i];

                    if (loadingList.Count <= 0)
                    {
                        continue;
                    }
                    TAsyncLoadResParam loadingItem = loadingList[0];
                    loadingList.RemoveAt(0);
                    callBackList = loadingItem.CallbackList;

                    Object       obj  = null;
                    TResouceItem item = null;
#if UNITY_EDITOR
                    if (!AppConfig.UseAssetBundle)
                    {
                        if (loadingItem.IsSprite)
                        {
                            obj = LoadAssetByEditor <Sprite>(loadingItem.Path);
                        }
                        else
                        {
                            obj = LoadAssetByEditor <Object>(loadingItem.Path);
                        }

                        //模拟异步加载
                        yield return(new WaitForSeconds(0.5f));

                        item = AssetBundleManager.Instance.FindResouceItem(loadingItem.Crc);
                        if (item == null)
                        {
                            item     = new TResouceItem();
                            item.Crc = loadingItem.Crc;
                        }
                    }
#endif
                    if (obj == null)
                    {
                        item = AssetBundleManager.Instance.LoadResouceAssetBundle(loadingItem.Crc);
                        if (item != null && item.AssetBundle != null)
                        {
                            AssetBundleRequest abRequest = null;
                            if (loadingItem.IsSprite)
                            {
                                abRequest = item.AssetBundle.LoadAssetAsync <Sprite>(item.AssetName);
                            }
                            else
                            {
                                abRequest = item.AssetBundle.LoadAssetAsync(item.AssetName);
                            }
                            yield return(abRequest);

                            if (abRequest.isDone)
                            {
                                obj = abRequest.asset;
                            }
                            lastYildTime = System.DateTime.Now.Ticks;
                        }
                    }
                    CacheResouce(loadingItem.Path, ref item, loadingItem.Crc, obj, callBackList.Count);
                    for (int j = 0; j < callBackList.Count; j++)
                    {
                        TAsyncCallBack callBack = callBackList[j];
                        if (callBack != null && callBack.DealFinish != null && callBack.ResObj != null)
                        {
                            TResouceObj tempResObj = callBack.ResObj;
                            tempResObj.ResItem = item;
                            callBack.DealFinish(loadingItem.Path, tempResObj, tempResObj.Param1, tempResObj.Param2, tempResObj.Param3);
                            callBack.DealFinish = null;
                            tempResObj          = null;
                        }

                        if (callBack != null && callBack.DealObjFinish != null)
                        {
                            callBack.DealObjFinish(loadingItem.Path, obj, callBack.Param1, callBack.Param2, callBack.Param3);
                            callBack.DealObjFinish = null;
                        }
                        callBack.Reset();
                        mAsyncCallBackPool.Recycle(callBack);
                    }
                    obj = null;
                    callBackList.Clear();
                    mLoadingAssetDic.Remove(loadingItem.Crc);

                    loadingItem.Reset();
                    mAsyncLoadResParamPool.Recycle(loadingItem);

                    if (System.DateTime.Now.Ticks - lastYildTime > MAXLOADRESTIME)
                    {
                        yield return(null);

                        lastYildTime = System.DateTime.Now.Ticks;
                        haveYield    = true;
                    }
                }
                if (!haveYield || System.DateTime.Now.Ticks - lastYildTime > MAXLOADRESTIME)
                {
                    lastYildTime = System.DateTime.Now.Ticks;
                    yield return(null);
                }
                yield return(null);
            }
        }