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

500 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.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
namespace Coolape
{
public class InvokeEx : MonoBehaviour
{
public bool canFixedUpdate = false;
public bool canUpdate = false;
public static InvokeEx self;
public InvokeEx ()
{
self = this;
}
Hashtable coroutineMap = Hashtable.Synchronized (new Hashtable ());
Hashtable coroutineIndex = Hashtable.Synchronized (new Hashtable ());
/// <summary>
/// Invoke4s the lua.回调lua函数 等待时间
/// </summary>
/// <param name='callbakFunc'> only support Luafunction or Callback
/// Callbak func.
/// </param>
/// <param name='sec'>
/// Sec.
/// </param>
public static UnityEngine.Coroutine invoke (object callbakFunc, float sec)
{
return self.invoke4Lua (callbakFunc, sec);
}
public static UnityEngine.Coroutine invoke (object callbakFunc, object orgs, float sec)
{
return self.invoke4Lua (callbakFunc, orgs, sec);
}
public static UnityEngine.Coroutine invoke (object callbakFunc, object orgs, float sec, bool onlyOneCoroutine)
{
return self.invoke4Lua (callbakFunc, orgs, sec, onlyOneCoroutine);
}
public UnityEngine.Coroutine invoke4Lua (object callbakFunc, float sec)
{
return invoke4Lua (callbakFunc, "", sec);
}
public UnityEngine.Coroutine invoke4Lua (object callbakFunc, object orgs, float sec)
{
return invoke4Lua (callbakFunc, orgs, sec, false);
}
/// <summary>
/// Invoke4s the lua.
/// </summary>
/// <param name="callbakFunc">Callbak func.lua函数</param>
/// <param name="orgs">Orgs.参数</param>
/// <param name="sec">Sec.等待时间</param>
public UnityEngine.Coroutine invoke4Lua (object callbakFunc, object orgs, float sec, bool onlyOneCoroutine)
{
if (!gameObject.activeInHierarchy)
return null;
if (callbakFunc == null) {
Debug.LogError ("callbakFunc is null ......");
return null;
}
try {
UnityEngine.Coroutine ct = null;
if (onlyOneCoroutine) {
cleanCoroutines (callbakFunc);
}
int index = getCoroutineIndex (callbakFunc);
ct = StartCoroutine (doInvoke4Lua (callbakFunc, sec, orgs, index));
setCoroutine (callbakFunc, ct, index);
return ct;
} catch (System.Exception e) {
Debug.LogError (callbakFunc + ":" + e);
return null;
}
}
public int getCoroutineIndex (object callbakFunc)
{
object key = getKey4InvokeMap (callbakFunc, coroutineIndex);
int ret = MapEx.getInt (coroutineIndex, key);
coroutineIndex [key] = ret + 1;
return ret;
}
public void setCoroutineIndex (object callbakFunc, int val)
{
object key = getKey4InvokeMap (callbakFunc, coroutineIndex);
coroutineIndex [key] = val;
}
/// <summary>
/// Gets the key4 invoke map.当直接传luafunction时不能直接用用Equals查找一下key
/// </summary>
/// <returns>The key4 invoke map.</returns>
/// <param name="callbakFunc">Callbak func.</param>
/// <param name="map">Map.</param>
public object getKey4InvokeMap (object callbakFunc, Hashtable map)
{
if (callbakFunc == null || map == null)
return callbakFunc;
object key = callbakFunc;
if (callbakFunc != null) {
NewList keys = ObjPool.listPool.borrowObject ();
keys.AddRange (map.Keys);
for (int i = 0; i < keys.Count; i++) {
if ((callbakFunc).Equals ((keys [i]))) {
key = keys [i];
break;
}
}
ObjPool.listPool.returnObject (keys);
keys = null;
}
return key;
}
public Hashtable getCoroutines (object callbakFunc)
{
object key = getKey4InvokeMap (callbakFunc, coroutineMap);
Hashtable ret = MapEx.getMap(coroutineMap, key);
ret = ret == null ? new Hashtable() : ret;
coroutineMap[key] = ret;
return ret;
}
public void setCoroutine (object callbakFunc, UnityEngine.Coroutine ct, int index)
{
object key = getKey4InvokeMap (callbakFunc, coroutineMap);
Hashtable map = getCoroutines (callbakFunc);
map [index] = ct;
coroutineMap [key] = map;
}
public void cleanCoroutines (object callbakFunc)
{
object key = getKey4InvokeMap (callbakFunc, coroutineMap);
Hashtable list = getCoroutines (callbakFunc);
foreach (DictionaryEntry cell in list) {
StopCoroutine ((UnityEngine.Coroutine)(cell.Value));
}
list.Clear ();
setCoroutineIndex (callbakFunc, 0);
coroutineMap.Remove (key);
}
public void rmCoroutine (object callbakFunc, int index)
{
object key = getKey4InvokeMap (callbakFunc, coroutineMap);
Hashtable list = getCoroutines (callbakFunc);
list.Remove (index);
coroutineMap [key] = list;
}
public static void cancelInvoke ()
{
self.cancelInvoke4Lua ();
}
public static void cancelInvoke (object callbakFunc)
{
self.cancelInvoke4Lua (callbakFunc);
}
public void cancelInvoke4Lua ()
{
cancelInvoke4Lua (null);
}
public void cancelInvoke4Lua (object callbakFunc)
{
if (callbakFunc == null) {
Hashtable list = null;
NewList keys = ObjPool.listPool.borrowObject();
keys.AddRange(coroutineMap.Keys);
object key = null;
for (int i = 0; i < keys.Count; i++) {
key = keys[i];
if (key != null)
{
list = getCoroutines(key);
foreach (DictionaryEntry cell in list)
{
StopCoroutine((UnityEngine.Coroutine)(cell.Value));
}
list.Clear();
}
}
coroutineMap.Clear ();
coroutineIndex.Clear ();
ObjPool.listPool.returnObject(keys);
} else {
cleanCoroutines (callbakFunc);
}
}
Queue invokeFuncs = new Queue ();
IEnumerator doInvoke4Lua (object callbakFunc, float sec, object orgs, int index)
{
yield return new WaitForSeconds (sec);
try {
rmCoroutine (callbakFunc, index);
Utl.doCallback (callbakFunc, orgs);
} catch (System.Exception e) {
string msg = "call err:doInvoke4Lua" + ",callbakFunc=[" + callbakFunc + "]";
Debug.LogError (msg);
Debug.LogError (e);
}
}
//================================================
// Fixed invoke 4 lua
//================================================
long _frameCounter = 0;
object locker=new object();
public long frameCounter {
get {
lock (locker) {
return _frameCounter;
}
}
set {
lock (locker) {
_frameCounter = value;
}
}
}
Hashtable _fixedInvokeMap = new Hashtable ();
public Hashtable fixedInvokeMap {
get {
if (_fixedInvokeMap == null) {
_fixedInvokeMap = Hashtable.Synchronized (new Hashtable ());
}
return _fixedInvokeMap;
}
}
public static void invokeByFixedUpdate (object luaFunc, float waitSec)
{
if (self == null) {
Debug.LogError ("Must attach InvokeEx on some gameObject!");
return;
}
self._fixedInvoke (luaFunc, null, waitSec);
}
public static void invokeByFixedUpdate (object luaFunc, object paras, float waitSec)
{
if (self == null) {
Debug.LogError ("Must attach InvokeEx on some gameObject!");
return;
}
self._fixedInvoke (luaFunc, paras, waitSec);
}
public void fixedInvoke4Lua (object luaFunc, float waitSec)
{
_fixedInvoke (luaFunc, null, waitSec);
}
public void fixedInvoke4Lua (object luaFunc, object paras, float waitSec)
{
_fixedInvoke (luaFunc, paras, waitSec);
}
void _fixedInvoke (object callback, object paras, float waitSec)
{
int waiteFrame = Mathf.CeilToInt (waitSec / Time.fixedDeltaTime);
waiteFrame = waiteFrame <= 0 ? 1 : waiteFrame; //至少有帧
long key = frameCounter + waiteFrame;
object[] content = new object[2];
// print (waiteFrame + "===" + key +"====" + luaFunc);
List<object[]> funcList = (List<object[]>)(fixedInvokeMap [key]);
if (funcList == null) {
funcList = new List<object[]> ();
}
content [0] = callback;
content [1] = paras;
funcList.Add (content);
fixedInvokeMap [key] = funcList;
if(!canFixedUpdate) {
canFixedUpdate = true;
}
}
public static void cancelInvokeByFixedUpdate ()
{
cancelInvokeByFixedUpdate (null);
}
public static void cancelInvokeByFixedUpdate (object func)
{
self.cancelFixedInvoke4Lua (func);
}
public void cancelFixedInvoke4Lua ()
{
cancelFixedInvoke4Lua (null);
}
public void cancelFixedInvoke4Lua (object func)
{
if (func == null) {
if (fixedInvokeMap != null) {
fixedInvokeMap.Clear ();
}
return;
}
List<object[]> list = null;
int count = 0;
object[] content = null;
foreach (DictionaryEntry item in fixedInvokeMap) {
list = (List<object[]>)(item.Value);
count = list.Count;
for (int i = count - 1; i >= 0; i--) {
content = list [i];
if (func.Equals (content [0])) {
list.RemoveAt (i);
}
}
if(list.Count == 0) {
fixedInvokeMap.Remove (item);
}
}
}
void doFixedInvoke (long key)
{
if (fixedInvokeMap == null && fixedInvokeMap.Count <= 0)
return;
if (fixedInvokeMap [key] == null)
return;
object[] content = null;
List<object[]> funcList = (List<object[]>)(fixedInvokeMap [key]);
object callback = null;
if (funcList != null) {
for (int i = 0; i < funcList.Count; i++) {
content = funcList [i];
callback = content [0];
Utl.doCallback (callback, content [1]);
}
funcList.Clear ();
funcList = null;
fixedInvokeMap.Remove (key);
}
}
//================================================
// FixedUpdate
//================================================
//帧统计
public virtual void FixedUpdate ()
{
if (!canFixedUpdate)
return;
frameCounter++;
if (fixedInvokeMap != null && fixedInvokeMap.Count > 0) {
doFixedInvoke (frameCounter);
} else {
canFixedUpdate = false;
frameCounter = 0;
}
}
//================================================
// Update
//================================================
ArrayList _invokeByUpdateList = null;
ArrayList invokeByUpdateList {
get {
if (_invokeByUpdateList == null) {
_invokeByUpdateList = ArrayList.Synchronized (new ArrayList ());
}
return _invokeByUpdateList;
}
}
/// <summary>
/// Invoke4s the lua.
/// </summary>
/// <param name="callbakFunc">Callbak func.lua函数</param>
/// <param name="orgs">Orgs.参数</param>
/// <param name="sec">Sec.等待时间</param>
public static void invokeByUpdate (object callbakFunc, float sec)
{
self.updateInvoke (callbakFunc, sec);
}
public static void invokeByUpdate (object callbakFunc, object orgs, float sec)
{
self.updateInvoke (callbakFunc, orgs, sec);
}
public void updateInvoke (object callbakFunc, float sec)
{
updateInvoke (callbakFunc, null, sec);
}
public void updateInvoke (object callbakFunc, object orgs, float sec)
{
if (callbakFunc == null)
return;
NewList list = ObjPool.listPool.borrowObject ();
list.Add (callbakFunc);
list.Add (orgs);
list.Add (Time.unscaledTime + sec);
invokeByUpdateList.Add (list);
canUpdate = true;
}
public static void cancelInvokeByUpdate ()
{
self.cancelUpdateInvoke ();
}
public static void cancelInvokeByUpdate (object callbakFunc)
{
self.cancelUpdateInvoke (callbakFunc);
}
public void cancelUpdateInvoke ()
{
cancelUpdateInvoke (null);
}
public void cancelUpdateInvoke (object callbakFunc)
{
NewList list = null;
int count = invokeByUpdateList.Count;
if (callbakFunc == null) {
for (int i = 0; i < count; i++) {
list = (NewList)(invokeByUpdateList [i]);
ObjPool.listPool.returnObject (list);
}
list = null;
invokeByUpdateList.Clear ();
return;
}
for (int i = count - 1; i >= 0; i--) {
list = (NewList)(invokeByUpdateList [i]);
if (callbakFunc.Equals (list [0])) {
invokeByUpdateList.RemoveAt (i);
ObjPool.listPool.returnObject (list);
}
}
list = null;
}
void doInvokeByUpdate ()
{
int count = invokeByUpdateList.Count;
NewList list = null;
object callbakFunc;
object orgs;
float sec;
int index = 0;
while (index < invokeByUpdateList.Count) {
list = (NewList)(invokeByUpdateList [index]);
callbakFunc = list [0];
orgs = list [1];
sec = (float)(list [2]);
if (sec <= Time.unscaledTime)
{
invokeByUpdateList.RemoveAt(index);
Utl.doCallback (callbakFunc, orgs);
ObjPool.listPool.returnObject (list);
} else {
index++;
}
}
list = null;
}
public virtual void Update ()
{
if (!canUpdate)
return;
if (invokeByUpdateList.Count > 0) {
doInvokeByUpdate ();
} else {
canUpdate = false;
}
}
}
}