123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using CommonUnity3D.XMUnity.LoadUtil;
- //依赖在外部维护比较好
- //卸载依赖的逻辑需要用计数器
- public class XMUnityAssetBundle {
- public string Name { get; private set; }
- private AssetBundle mAssetBundle = null;
- public AssetBundle AssetBundle { get { return mAssetBundle; } }
- Stack<Object> mCache = new Stack<Object>();
- HashSet<string> mChildAB = new HashSet<string>();
- Dictionary<string, Object> mPrefabs = new Dictionary<string, Object>();
- private Status mBundleStatus = Status.NONE;
- public Status BundleStatus { get { return mBundleStatus; } }
- public int Version { get; private set; }
- private AssetBundleRequest Request = null;
- //System.Diagnostics.Stopwatch sw;
- public delegate void LoadResCallBack(string name, Object o, object userdata, bool isLoadOK);
- public class ABCallBackInfo
- {
- public string Name { get; set; }
- public LoadResCallBack CallBack { get; set; }
- public object UserData { get; set; }
- public ABCallBackInfo(string name, LoadResCallBack callback, object userdata)
- {
- this.Name = name;
- this.CallBack = callback;
- this.UserData = userdata;
- }
- }
- List<ABCallBackInfo> mLoadingAssetTask = new List<ABCallBackInfo>();
- public enum Status
- {
- NONE,
- LoadDep,
- LoadDepDone,
- LoadAssetBundle,
- LoadAssetBundleDone,
- LoadAsset,
- LoadAssetDone,
- Unloaded,
- }
- public enum Type
- {
- MAIN_ASSET,
- DEP_ASSET,
- }
- private Type mType = Type.MAIN_ASSET;
- public Type BundleType { get { return mType; } }
- public XMUnityAssetBundle(string name)
- {
- Name = name;
- }
- public XMUnityAssetBundle(string name, AssetBundle ab, int version)
- {
- Name = name;
- mAssetBundle = ab;
- mBundleStatus = Status.LoadAssetBundleDone;
- Version = version;
- }
- bool AddChild(string name)
- {
- return mChildAB.Add(name);
- }
- bool RemoveChild(string name)
- {
- return mChildAB.Remove(name);
- }
- bool GetFromCache(out Object obj)
- {
- if(mCache.Count > 0)
- {
- obj = mCache.Pop();
- return true;
- }
- else
- {
- obj = null;
- return false;
- }
- }
- void PushCache(Object obj)
- {
- mCache.Push(obj);
- }
- public Object GetAsset(string name)
- {
- Object obj = null;
- mPrefabs.TryGetValue(name, out obj);
- return obj;
- }
- //public void LoadAsset(string asset, bool isAsync)
- //{
- // Object obj = null;
- // //缓存里没有现成的
- // if (!GetFromCache(out obj))
- // {
- // }
- //}
- public void GetAsset(string asset, bool isAsync, LoadResCallBack callback, object userdata, System.Type type = null)
- {
- Object o = null;
- if(mPrefabs.TryGetValue(asset, out o))
- {
- callback(asset, o, userdata, true);
- }
- else
- {
- LoadAsset(asset, isAsync, callback, userdata, type);
- }
- }
- public void LoadAsset(string asset, bool isAsync, LoadResCallBack callback, object userdata, System.Type type = null)
- {
- //TODO 先按照之前的代码只支持一个AB1个物件,以后改成多个
- if (mBundleStatus == Status.LoadAsset || mBundleStatus == Status.LoadAssetDone)
- {
- //Debug.Log("LoadAsset Done");
- AddLoadingAssetTask(asset, callback, userdata);
- return;
- }
- if(type == null)
- {
- type = typeof(Object);
- }
- if(isAsync)
- {
- //sw = System.Diagnostics.Stopwatch.StartNew();
- Request = mAssetBundle.LoadAssetAsync(asset, type);
- mBundleStatus = Status.LoadAsset;
- AddLoadingAssetTask(asset, callback, userdata);
- XMUnityAssetBundleManager.GetInstance().StartCoroutine(CheckRequestAsset(asset));
- }
- else
- {
- //sw = System.Diagnostics.Stopwatch.StartNew();
- if(mAssetBundle == null)
- {
- int i = 0;
- }
- Object o = mAssetBundle.LoadAsset(asset, type);
- if(o != null)
- {
- mPrefabs[asset] = o;
- mBundleStatus = Status.LoadAssetDone;
- callback(asset, o, userdata, true);
- }
- else
- {
- mBundleStatus = Status.LoadAssetDone;
- callback(asset, o, userdata, false);
- }
- }
- mType = Type.MAIN_ASSET;
- }
- void AddLoadingAssetTask(string asset, LoadResCallBack callback, object userdata)
- {
- ABCallBackInfo info = new ABCallBackInfo(asset, callback, userdata);
- mLoadingAssetTask.Add(info);
- }
- void DoLoadAssetCallback(Object asset, bool isLoadOK)
- {
- var iter = mLoadingAssetTask.GetEnumerator();
- while (iter.MoveNext())
- {
- iter.Current.CallBack(iter.Current.Name, asset, iter.Current.UserData, isLoadOK);
- }
- mLoadingAssetTask.Clear();
- }
- public void LoadDeps(bool isAsync, LoadResCallBack callback, object userdata, string childAB)
- {
- //TODO 处理依赖关系
- if(childAB != null)
- {
- mChildAB.Add(childAB);
- }
- if (mBundleStatus == Status.LoadDep)
- {
- AddLoadingAssetTask(null, callback, userdata);
- }
- else if(mBundleStatus == Status.LoadDepDone)
- {
- //Debug.Log("LoadDeps Done");
- callback(null, null, userdata, true);
- }
- else
- {
- //sw = System.Diagnostics.Stopwatch.StartNew();
- if (isAsync)
- {
- Request = mAssetBundle.LoadAllAssetsAsync();
- mBundleStatus = Status.LoadDep;
- AddLoadingAssetTask(null, callback, userdata);
- XMUnityAssetBundleManager.GetInstance().StartCoroutine(CheckRequestDeps());
- }
- else
- {
- mAssetBundle.LoadAllAssets();
- mBundleStatus = Status.LoadDepDone;
- //sw.Stop();
- //Debug.LogError("[zzzzzzzzzzzzzzzz] " + Name.ToString() + " "+sw.ElapsedMilliseconds/1000f);
- callback(null, null, userdata, true);
- }
- }
- mType = Type.DEP_ASSET;
- }
- public void MarkAsDeps(string childAB)
- {
- //TODO 处理依赖关系
- if (childAB != null)
- {
- mChildAB.Add(childAB);
- }
- mBundleStatus = Status.LoadDepDone;
- mType = Type.DEP_ASSET;
- }
- public bool TryUnloadDep(string child, bool isUnloadAll = false, bool force = false)
- {
- if(mChildAB.Remove(child))
- {
- if(mChildAB.Count < 1)
- {
- return Unload(isUnloadAll, force);
- //return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- Debug.LogWarning("[策划测试请无视]XMUnityAssetBundle TryUnloadDep Error! Child not exists: [" + child + "] parent: [" + Name + "]");
- return false;
- }
- }
- public bool Unload(bool all, bool force = false)
- {
- //TODO 被其他包引用的包不能被Unload
- if(mBundleStatus == Status.NONE || mBundleStatus == Status.LoadAssetBundle || mBundleStatus == Status.LoadDep || mBundleStatus == Status.LoadAsset)
- {
- Debug.LogError("[策划测试请无视]XMUnityAssetBundle Unload Error! Status: " + mBundleStatus);
- return false;
- }
- if(force)
- {
- if(mType == Type.DEP_ASSET && mChildAB.Count > 0)
- {
- Debug.LogWarning("[策划测试请无视]XMUnityAssetBundle Force Unload Error! Child Referenced :" + Name + " " + mChildAB.Count);
- }
- }
- else
- {
- if (mType == Type.DEP_ASSET && mChildAB.Count > 0)
- {
- Debug.LogError("[策划测试请无视]XMUnityAssetBundle Unload Error! Child Referenced :" + Name + " " + mChildAB.Count);
- return false;
- }
- }
- //Debug.LogError("[Unload]" + Name + " " + all);
- mBundleStatus = Status.Unloaded;
- mPrefabs.Clear();
- mAssetBundle.Unload(all);
- mAssetBundle = null;
- mChildAB.Clear();
- return true;
- }
- IEnumerator<YieldInstruction> CheckRequestDeps()
- {
- //if (Request != null)
- {
- while (!Request.isDone)
- {
- yield return null;
- }
-
- mBundleStatus = Status.LoadDepDone;
- Request = null;
- //sw.Stop();
- //Debug.LogError("[zzzzzzzzzzzzzzzz] " + Name.ToString() + " "+sw.ElapsedMilliseconds/1000f);
- DoLoadAssetCallback(null, true);
- }
- }
- IEnumerator<YieldInstruction> CheckRequestAsset(string asset)
- {
- //if (Request != null)
- {
- while (!Request.isDone)
- {
- yield return null;
- }
-
- Object o = Request.asset;
- //sw.Stop();
- //Debug.LogError("[zzzzzzzzzzzzzzzz] " + Name.ToString() + " "+sw.ElapsedMilliseconds/1000f);
- if (o != null)
- {
- mPrefabs[asset] = o;
- mBundleStatus = Status.LoadAssetDone;
- Request = null;
- DoLoadAssetCallback(o, true);
- }
- else
- {
- mBundleStatus = Status.LoadAssetDone;
- Request = null;
- DoLoadAssetCallback(null, false);
- }
- }
- }
- }
|