489 lines
13 KiB
C#
489 lines
13 KiB
C#
|
|
/*
|
|||
|
|
********************************************************************************
|
|||
|
|
*Copyright(C),coolae.net
|
|||
|
|
*Author: chenbin
|
|||
|
|
*Version: 2.0
|
|||
|
|
*Date: 2017-01-09
|
|||
|
|
*Description: 资源对象池基类
|
|||
|
|
*Others:
|
|||
|
|
*History:
|
|||
|
|
*********************************************************************************
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
using UnityEngine;
|
|||
|
|
using System.Collections;
|
|||
|
|
using XLua;
|
|||
|
|
|
|||
|
|
namespace Coolape
|
|||
|
|
{
|
|||
|
|
[LuaCallCSharp]
|
|||
|
|
public abstract class CLAssetsPoolBase<T> where T: UnityEngine.Object
|
|||
|
|
{
|
|||
|
|
public CLDelegate OnSetPrefabCallbacks4Borrow = new CLDelegate ();
|
|||
|
|
public CLDelegate OnSetPrefabCallbacks = new CLDelegate ();
|
|||
|
|
// public static ListPool listPool = new ListPool ();
|
|||
|
|
public bool isFinishInitPool = false;
|
|||
|
|
public Hashtable poolMap = new Hashtable ();
|
|||
|
|
public Hashtable prefabMap = new Hashtable ();
|
|||
|
|
public Hashtable isSettingPrefabMap = new Hashtable ();
|
|||
|
|
|
|||
|
|
|
|||
|
|
public void _clean ()
|
|||
|
|
{
|
|||
|
|
isFinishInitPool = false;
|
|||
|
|
poolMap.Clear ();
|
|||
|
|
prefabMap.Clear ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void initPool ()
|
|||
|
|
{
|
|||
|
|
if (isFinishInitPool)
|
|||
|
|
return;
|
|||
|
|
isFinishInitPool = true;
|
|||
|
|
//TODO:
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Wraps the path. 包装路径,以便支持 dir1/dir2/test.unity3d
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>The path.</returns>
|
|||
|
|
/// <param name="basePath">Base path.</param>
|
|||
|
|
/// <param name="thingName">Thing name.</param>
|
|||
|
|
public static string wrapPath (string basePath, string thingName)
|
|||
|
|
{
|
|||
|
|
string tmpStr = thingName.Replace (".", "/");
|
|||
|
|
string[] strs = tmpStr.Split ('/');
|
|||
|
|
string path = basePath;
|
|||
|
|
int len = strs.Length;
|
|||
|
|
for (int i = 0; i < len - 1; i++) {
|
|||
|
|
path = PStr.begin (path).a ("/").a (strs [i]).end ();
|
|||
|
|
}
|
|||
|
|
path = PStr.begin (path).a ("/").a (CLPathCfg.self.platform).a ("/").a (strs [len - 1]).a (".unity3d").end ();
|
|||
|
|
return path;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region 设置预设
|
|||
|
|
|
|||
|
|
//设置预设===========
|
|||
|
|
public bool _havePrefab (string name)
|
|||
|
|
{
|
|||
|
|
return prefabMap.Contains (name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
public virtual bool isAutoReleaseAssetBundle
|
|||
|
|
{
|
|||
|
|
get {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Gets the asset path.需要在扩展类中,实在该方法,调用时会用到doSetPrefab
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>The asset path.</returns>
|
|||
|
|
/// <param name="name">Name.</param>
|
|||
|
|
public abstract string getAssetPath (string name);
|
|||
|
|
|
|||
|
|
public virtual void _setPrefab (string name, object finishCallback, object orgs, object progressCB)
|
|||
|
|
{
|
|||
|
|
string path = getAssetPath (name);
|
|||
|
|
OnSetPrefabCallbacks.add (name, finishCallback, orgs);
|
|||
|
|
doSetPrefab (path, name, (Callback)onFinishSetPrefab, name, progressCB);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void onFinishSetPrefab (object[] paras)
|
|||
|
|
{
|
|||
|
|
if (paras != null && paras.Length > 1) {
|
|||
|
|
T unit = paras [0] as T;
|
|||
|
|
string name = paras [1].ToString ();
|
|||
|
|
ArrayList list = OnSetPrefabCallbacks.getDelegates (name);
|
|||
|
|
int count = list.Count;
|
|||
|
|
ArrayList cell = null;
|
|||
|
|
object cb = null;
|
|||
|
|
object orgs = null;
|
|||
|
|
for (int i = 0; i < count; i++) {
|
|||
|
|
cell = list [i] as ArrayList;
|
|||
|
|
if (cell != null && cell.Count > 1) {
|
|||
|
|
cb = cell [0];
|
|||
|
|
orgs = cell [1];
|
|||
|
|
if (cb != null) {
|
|||
|
|
Utl.doCallback (cb, unit, orgs);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
list.Clear ();
|
|||
|
|
OnSetPrefabCallbacks.removeDelegates (name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
public void doSetPrefab (string path, string name, object finishCallback, object args, object progressCB)
|
|||
|
|
{
|
|||
|
|
if (name == null)
|
|||
|
|
return;
|
|||
|
|
if (MapEx.getBool (isSettingPrefabMap, name)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (_havePrefab (name)) {
|
|||
|
|
if (finishCallback != null) {
|
|||
|
|
Utl.doCallback (finishCallback, prefabMap [name], args);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
isSettingPrefabMap [name] = true;
|
|||
|
|
Callback cb = onGetAssetsBundle;
|
|||
|
|
CLVerManager.self.getNewestRes (path,
|
|||
|
|
CLAssetType.assetBundle,
|
|||
|
|
cb, isAutoReleaseAssetBundle, finishCallback, name, args, progressCB);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void finishSetPrefab (T unit)
|
|||
|
|
{
|
|||
|
|
if (unit != null)
|
|||
|
|
{
|
|||
|
|
prefabMap[unit.name] = unit;
|
|||
|
|
}
|
|||
|
|
isSettingPrefabMap.Remove (unit.name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void onGetAssetsBundle (params object[] paras)
|
|||
|
|
{
|
|||
|
|
string name = "";
|
|||
|
|
string path = "";
|
|||
|
|
try {
|
|||
|
|
if (paras != null) {
|
|||
|
|
path = (paras [0]).ToString ();
|
|||
|
|
AssetBundle asset = (paras [1]) as AssetBundle;
|
|||
|
|
object[] org = (object[])(paras [2]);
|
|||
|
|
object cb = org [0];
|
|||
|
|
name = (org [1]).ToString ();
|
|||
|
|
object args = org [2];
|
|||
|
|
object progressCB = org [3];
|
|||
|
|
|
|||
|
|
if (asset == null) {
|
|||
|
|
Debug.LogError("get asset is null. path =" + path);
|
|||
|
|
finishSetPrefab(null);
|
|||
|
|
Utl.doCallback (cb, null, args);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
GameObject go = null;
|
|||
|
|
T unit = null;
|
|||
|
|
if (typeof(T) == typeof(AssetBundle)) {
|
|||
|
|
unit = asset as T;
|
|||
|
|
unit.name = name;
|
|||
|
|
} else {
|
|||
|
|
if (typeof(T) == typeof(GameObject)) {
|
|||
|
|
// Debug.Log ("11111name====" + name);
|
|||
|
|
unit = asset.mainAsset as T;
|
|||
|
|
unit.name = name;
|
|||
|
|
} else {
|
|||
|
|
// Debug.Log ("22222name====" + name);
|
|||
|
|
go = asset.mainAsset as GameObject;
|
|||
|
|
if (go != null) {
|
|||
|
|
go.name = name;
|
|||
|
|
unit = go.GetComponent<T> ();
|
|||
|
|
} else {
|
|||
|
|
// Debug.Log ("33333name====" + name);
|
|||
|
|
unit = asset.mainAsset as T;
|
|||
|
|
unit.name = name;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
CLAssetsManager.self.addAsset (getAssetPath (name), name, asset, realseAsset);
|
|||
|
|
sepcProc4Assets (unit, cb, args, progressCB);
|
|||
|
|
} else {
|
|||
|
|
Debug.LogError ("Get assetsbundle failed!");
|
|||
|
|
}
|
|||
|
|
} catch (System.Exception e) {
|
|||
|
|
Debug.LogError ("path==" + path + "," + e + name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Sepcs the proc4 assets.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="unit">Unit.</param>
|
|||
|
|
/// <param name="cb">Cb.</param>
|
|||
|
|
/// <param name="args">Arguments.</param>
|
|||
|
|
public virtual void sepcProc4Assets (T unit, object cb, object args, object progressCB)
|
|||
|
|
{
|
|||
|
|
GameObject go = null;
|
|||
|
|
if (typeof(T) == typeof(GameObject)) {
|
|||
|
|
go = unit as GameObject;
|
|||
|
|
} else if (unit is MonoBehaviour) {
|
|||
|
|
go = (unit as MonoBehaviour).gameObject;
|
|||
|
|
}
|
|||
|
|
if (go != null) {
|
|||
|
|
CLSharedAssets sharedAsset = go.GetComponent<CLSharedAssets> ();
|
|||
|
|
if (sharedAsset != null) {
|
|||
|
|
NewList param = ObjPool.listPool.borrowObject ();
|
|||
|
|
param.Add (cb);
|
|||
|
|
param.Add (unit);
|
|||
|
|
param.Add (args);
|
|||
|
|
sharedAsset.init ((Callback)onGetSharedAssets, param, progressCB);
|
|||
|
|
} else {
|
|||
|
|
finishSetPrefab (unit);
|
|||
|
|
Utl.doCallback (cb, unit, args);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
finishSetPrefab (unit);
|
|||
|
|
Utl.doCallback (cb, unit, args);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void onGetSharedAssets (params object[] param)
|
|||
|
|
{
|
|||
|
|
if (param == null) {
|
|||
|
|
Debug.LogWarning ("param == null");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
NewList list = (NewList)(param [0]);
|
|||
|
|
if (list.Count >= 3) {
|
|||
|
|
object cb = list [0];
|
|||
|
|
T obj = list [1] as T;
|
|||
|
|
object orgs = list [2];
|
|||
|
|
finishSetPrefab (obj);
|
|||
|
|
if (cb != null) {
|
|||
|
|
Utl.doCallback (cb, obj, orgs);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
Debug.LogWarning ("list.Count ====0");
|
|||
|
|
}
|
|||
|
|
ObjPool.listPool.returnObject (list);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//释放资源
|
|||
|
|
public virtual void realseAsset (params object[] paras)
|
|||
|
|
{
|
|||
|
|
string name = "";
|
|||
|
|
try {
|
|||
|
|
name = paras [0].ToString ();
|
|||
|
|
object obj = poolMap [name];
|
|||
|
|
ObjsPubPool pool = null;
|
|||
|
|
T unit = null;
|
|||
|
|
MonoBehaviour unitObj = null;
|
|||
|
|
|
|||
|
|
if (obj != null) {
|
|||
|
|
pool = obj as ObjsPubPool;
|
|||
|
|
}
|
|||
|
|
if (pool != null) {
|
|||
|
|
while (pool.queue.Count > 0) {
|
|||
|
|
unit = pool.queue.Dequeue ();
|
|||
|
|
if (unit != null) {
|
|||
|
|
if (unit is MonoBehaviour) {
|
|||
|
|
unitObj = unit as MonoBehaviour;
|
|||
|
|
GameObject.DestroyImmediate (unitObj.gameObject, true);
|
|||
|
|
} else if (unit is GameObject) {
|
|||
|
|
GameObject.DestroyImmediate ((unit as GameObject), true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
unit = null;
|
|||
|
|
}
|
|||
|
|
pool.queue.Clear ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
unit = (T)(prefabMap [name]);
|
|||
|
|
prefabMap.Remove (name);
|
|||
|
|
if (unit != null) {
|
|||
|
|
if (unit is AssetBundle) {
|
|||
|
|
//do nothing, CLAssetsManager will unload assetbundle
|
|||
|
|
} else {
|
|||
|
|
if (unit is MonoBehaviour) {
|
|||
|
|
unitObj = unit as MonoBehaviour;
|
|||
|
|
CLSharedAssets sharedAsset = unitObj.GetComponent<CLSharedAssets> ();
|
|||
|
|
if (sharedAsset != null) {
|
|||
|
|
sharedAsset.returnAssets ();
|
|||
|
|
}
|
|||
|
|
GameObject.DestroyImmediate (unitObj.gameObject, true);
|
|||
|
|
} else if (unit is GameObject) {
|
|||
|
|
CLSharedAssets sharedAsset = (unit as GameObject).GetComponent<CLSharedAssets> ();
|
|||
|
|
if (sharedAsset != null) {
|
|||
|
|
sharedAsset.returnAssets ();
|
|||
|
|
}
|
|||
|
|
GameObject.DestroyImmediate ((unit as GameObject), true);
|
|||
|
|
} else {
|
|||
|
|
//UnityEngine.Resources.UnloadAsset ((Object)unit);
|
|||
|
|
GameObject.DestroyImmediate (unit, true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
unit = null;
|
|||
|
|
} catch (System.Exception e) {
|
|||
|
|
Debug.LogError ("name==" + name + ":" + e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
public ObjsPubPool getObjPool (string name)
|
|||
|
|
{
|
|||
|
|
object obj = poolMap [name];
|
|||
|
|
ObjsPubPool pool = null;
|
|||
|
|
if (obj == null) {
|
|||
|
|
pool = new ObjsPubPool (prefabMap);
|
|||
|
|
poolMap [name] = pool;
|
|||
|
|
} else {
|
|||
|
|
pool = (ObjsPubPool)obj;
|
|||
|
|
}
|
|||
|
|
return pool;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual T _borrowObj (string name)
|
|||
|
|
{
|
|||
|
|
return _borrowObj (name, false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual T _borrowObj (string name, bool isSharedResource)
|
|||
|
|
{
|
|||
|
|
T r = null;
|
|||
|
|
if (isSharedResource) {
|
|||
|
|
r = (T)(prefabMap [name]);
|
|||
|
|
} else {
|
|||
|
|
object obj = poolMap [name];
|
|||
|
|
ObjsPubPool pool = getObjPool (name);
|
|||
|
|
r = pool.borrowObject (name);
|
|||
|
|
poolMap [name] = pool;
|
|||
|
|
}
|
|||
|
|
if (_havePrefab (name)) {
|
|||
|
|
CLAssetsManager.self.useAsset (getAssetPath (name));
|
|||
|
|
}
|
|||
|
|
return r;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Borrows the texture asyn.
|
|||
|
|
/// 异步取得texture
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>The texture asyn.</returns>
|
|||
|
|
/// <param name="path">Path.</param>
|
|||
|
|
/// <param name="onGetTexture">On get texture.</param>
|
|||
|
|
/// 回调函数
|
|||
|
|
/// <param name="org">Org.</param>
|
|||
|
|
/// 透传参数
|
|||
|
|
public virtual void _borrowObjAsyn (string name, object onGetCallbak)
|
|||
|
|
{
|
|||
|
|
_borrowObjAsyn (name, onGetCallbak, null, null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void _borrowObjAsyn (string name, object onGetCallbak, object orgs)
|
|||
|
|
{
|
|||
|
|
_borrowObjAsyn (name, onGetCallbak, orgs, null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void _borrowObjAsyn (string name, object onGetCallbak, object orgs, object progressCB)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrEmpty (name)) {
|
|||
|
|
Debug.LogWarning ("The name is null");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (_havePrefab (name)) {
|
|||
|
|
CLMainBase.self.StartCoroutine(_doBorrowObj(name, onGetCallbak, orgs));
|
|||
|
|
} else {
|
|||
|
|
OnSetPrefabCallbacks4Borrow.add (name, onGetCallbak, orgs);
|
|||
|
|
_setPrefab (name, (Callback)onFinishSetPrefab4Borrow, name, progressCB);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator _doBorrowObj(string name, object onGetCallbak, object orgs)
|
|||
|
|
{
|
|||
|
|
yield return null;
|
|||
|
|
T unit = _borrowObj(name);
|
|||
|
|
Utl.doCallback(onGetCallbak, name, unit, orgs);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public virtual void onFinishSetPrefab4Borrow (object[] paras)
|
|||
|
|
{
|
|||
|
|
if (paras != null && paras.Length > 1) {
|
|||
|
|
T unit = paras [0] as T;
|
|||
|
|
string name = paras [1].ToString ();
|
|||
|
|
ArrayList list = OnSetPrefabCallbacks4Borrow.getDelegates (name);
|
|||
|
|
int count = list.Count;
|
|||
|
|
ArrayList cell = null;
|
|||
|
|
object cb = null;
|
|||
|
|
object orgs = null;
|
|||
|
|
for (int i = 0; i < count; i++) {
|
|||
|
|
cell = list [i] as ArrayList;
|
|||
|
|
if (cell != null && cell.Count > 1) {
|
|||
|
|
cb = cell [0];
|
|||
|
|
orgs = cell [1];
|
|||
|
|
if (cb != null) {
|
|||
|
|
unit = _borrowObj (name);
|
|||
|
|
Utl.doCallback (cb, name, unit, orgs);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
list.Clear ();
|
|||
|
|
OnSetPrefabCallbacks4Borrow.removeDelegates (name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Returns the object. 当参数unit是null时,说明是共享资源
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="name">Name.</param>
|
|||
|
|
/// <param name="unit">Unit.</param>
|
|||
|
|
public virtual void _returnObj (string name, T unit, bool inActive = true, bool setParent = true)
|
|||
|
|
{
|
|||
|
|
if (unit != null) {
|
|||
|
|
object obj = poolMap [name];
|
|||
|
|
ObjsPubPool pool = getObjPool (name);
|
|||
|
|
pool.returnObject (unit);
|
|||
|
|
poolMap [name] = pool;
|
|||
|
|
if (unit is MonoBehaviour) {
|
|||
|
|
MonoBehaviour unitObj = unit as MonoBehaviour;
|
|||
|
|
if (inActive) {
|
|||
|
|
unitObj.gameObject.SetActive (false);
|
|||
|
|
}
|
|||
|
|
if (setParent) {
|
|||
|
|
unitObj.transform.parent = null;
|
|||
|
|
}
|
|||
|
|
} else if (unit is GameObject) {
|
|||
|
|
GameObject unitObj = unit as GameObject;
|
|||
|
|
if (inActive) {
|
|||
|
|
unitObj.SetActive (false);
|
|||
|
|
}
|
|||
|
|
if (setParent) {
|
|||
|
|
unitObj.transform.parent = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
CLAssetsManager.self.unUseAsset (getAssetPath (name));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ObjsPubPool : AbstractObjectPool<T>
|
|||
|
|
{
|
|||
|
|
Hashtable prefabMap = null;
|
|||
|
|
|
|||
|
|
public ObjsPubPool (Hashtable prefabMap)
|
|||
|
|
{
|
|||
|
|
this.prefabMap = prefabMap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override T createObject (string key)
|
|||
|
|
{
|
|||
|
|
T unit = (prefabMap [key]) as T;
|
|||
|
|
if (unit != null) {
|
|||
|
|
Object go = GameObject.Instantiate (unit) as Object;
|
|||
|
|
go.name = key;
|
|||
|
|
|
|||
|
|
T ret = null;
|
|||
|
|
if (go is T) {
|
|||
|
|
ret = go as T;
|
|||
|
|
} else {
|
|||
|
|
ret = ((GameObject)go).GetComponent<T> ();
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override T resetObject (T t)
|
|||
|
|
{
|
|||
|
|
return t;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|