Files
tianrunCRM/Assets/CoolapeFrame/Scripts/assets/CLAssetsPoolBase.cs
2020-07-04 14:41:25 +08:00

489 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
********************************************************************************
*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;
}
}
}
}