Lua委托

TestDelegate.cs

  1. using UnityEngine;
  2. using System;
  3. using System.Collections.Generic;
  4. using LuaInterface;
  5. public class TestDelegate: MonoBehaviour
  6. {
  7. private string script =
  8. @"
  9. function DoClick1(go)
  10. print('click1 gameObject is '..go.name)
  11. end
  12. function DoClick2(go)
  13. print('click2 gameObject is '..go.name)
  14. end
  15. function AddClick1(listener)
  16. if listener.onClick then
  17. listener.onClick = listener.onClick + DoClick1
  18. else
  19. listener.onClick = DoClick1
  20. end
  21. end
  22. function AddClick2(listener)
  23. if listener.onClick then
  24. listener.onClick = listener.onClick + DoClick2
  25. else
  26. listener.onClick = DoClick2
  27. end
  28. end
  29. function SetClick1(listener)
  30. if listener.onClick then
  31. listener.onClick:Destroy()
  32. end
  33. listener.onClick = DoClick1
  34. end
  35. function RemoveClick1(listener)
  36. if listener.onClick then
  37. listener.onClick = listener.onClick - DoClick1
  38. else
  39. print('empty delegate')
  40. end
  41. end
  42. function RemoveClick2(listener)
  43. if listener.onClick then
  44. listener.onClick = listener.onClick - DoClick2
  45. else
  46. print('empty delegate')
  47. end
  48. end
  49. --测试重载问题
  50. function TestOverride(listener)
  51. listener:SetOnFinished(TestEventListener.OnClick(DoClick1))
  52. listener:SetOnFinished(TestEventListener.VoidDelegate(DoClick2))
  53. end
  54. function TestEvent()
  55. print('this is a event')
  56. end
  57. function AddEvent(listener)
  58. listener.onClickEvent = listener.onClickEvent + TestEvent
  59. end
  60. function RemoveEvent(listener)
  61. listener.onClickEvent = listener.onClickEvent - TestEvent
  62. end
  63. local t = {name = 'byself'}
  64. function t:TestSelffunc()
  65. print('callback with self: '..self.name)
  66. end
  67. function AddSelfClick(listener)
  68. if listener.onClick then
  69. listener.onClick = listener.onClick + TestEventListener.OnClick(t.TestSelffunc, t)
  70. else
  71. listener.onClick = TestEventListener.OnClick(t.TestSelffunc, t)
  72. end
  73. end
  74. function RemoveSelfClick(listener)
  75. if listener.onClick then
  76. listener.onClick = listener.onClick - TestEventListener.OnClick(t.TestSelffunc, t)
  77. else
  78. print('empty delegate')
  79. end
  80. end
  81. ";
  82. LuaState state = null;
  83. TestEventListener listener = null;
  84. LuaFunction SetClick1 = null;
  85. LuaFunction AddClick1 = null;
  86. LuaFunction AddClick2 = null;
  87. LuaFunction RemoveClick1 = null;
  88. LuaFunction RemoveClick2 = null;
  89. LuaFunction TestOverride = null;
  90. LuaFunction RemoveEvent = null;
  91. LuaFunction AddEvent = null;
  92. LuaFunction AddSelfClick = null;
  93. LuaFunction RemoveSelfClick = null;
  94. //需要删除的转LuaFunction为委托,不需要删除的直接加或者等于即可
  95. void Awake()
  96. {
  97. state = new LuaState();
  98. state.Start();
  99. LuaBinder.Bind(state);
  100. Bind(state);
  101. state.LogGC = true;
  102. state.DoString(script);
  103. GameObject go = new GameObject("TestGo");
  104. listener = (TestEventListener)go.AddComponent(typeof(TestEventListener));
  105. SetClick1 = state.GetFunction("SetClick1");
  106. AddClick1 = state.GetFunction("AddClick1");
  107. AddClick2 = state.GetFunction("AddClick2");
  108. RemoveClick1 = state.GetFunction("RemoveClick1");
  109. RemoveClick2 = state.GetFunction("RemoveClick2");
  110. TestOverride = state.GetFunction("TestOverride");
  111. AddEvent = state.GetFunction("AddEvent");
  112. RemoveEvent = state.GetFunction("RemoveEvent");
  113. AddSelfClick = state.GetFunction("AddSelfClick");
  114. RemoveSelfClick = state.GetFunction("RemoveSelfClick");
  115. }
  116. void Bind(LuaState L)
  117. {
  118. L.BeginModule(null);
  119. TestEventListenerWrap.Register(state);
  120. L.EndModule();
  121. DelegateFactory.dict.Add(typeof(TestEventListener.OnClick), TestEventListener_OnClick);
  122. DelegateFactory.dict.Add(typeof(TestEventListener.VoidDelegate), TestEventListener_VoidDelegate);
  123. }
  124. void CallLuaFunction(LuaFunction func)
  125. {
  126. func.BeginPCall();
  127. func.Push(listener);
  128. func.PCall();
  129. func.EndPCall();
  130. }
  131. //自动生成代码后拷贝过来
  132. class TestEventListener_OnClick_Event : LuaDelegate
  133. {
  134. public TestEventListener_OnClick_Event(LuaFunction func) : base(func) { }
  135. public void Call(UnityEngine.GameObject param0)
  136. {
  137. func.BeginPCall();
  138. func.Push(param0);
  139. func.PCall();
  140. func.EndPCall();
  141. }
  142. }
  143. public static Delegate TestEventListener_OnClick(LuaFunction func, LuaTable self, bool flag)
  144. {
  145. if (func == null)
  146. {
  147. TestEventListener.OnClick fn = delegate { };
  148. return fn;
  149. }
  150. TestEventListener_OnClick_Event target = new TestEventListener_OnClick_Event(func);
  151. TestEventListener.OnClick d = target.Call;
  152. target.method = d.Method;
  153. return d;
  154. }
  155. class TestEventListener_VoidDelegate_Event : LuaDelegate
  156. {
  157. public TestEventListener_VoidDelegate_Event(LuaFunction func) : base(func) { }
  158. public void Call(UnityEngine.GameObject param0)
  159. {
  160. func.BeginPCall();
  161. func.Push(param0);
  162. func.PCall();
  163. func.EndPCall();
  164. }
  165. }
  166. public static Delegate TestEventListener_VoidDelegate(LuaFunction func, LuaTable self, bool flag)
  167. {
  168. if (func == null)
  169. {
  170. TestEventListener.VoidDelegate fn = delegate { };
  171. return fn;
  172. }
  173. TestEventListener_VoidDelegate_Event target = new TestEventListener_VoidDelegate_Event(func);
  174. TestEventListener.VoidDelegate d = target.Call;
  175. target.method = d.Method;
  176. return d;
  177. }
  178. void OnGUI()
  179. {
  180. if (GUI.Button(new Rect(10, 10, 120, 40), " = OnClick1"))
  181. {
  182. CallLuaFunction(SetClick1);
  183. }
  184. else if (GUI.Button(new Rect(10, 60, 120, 40), " + Click1"))
  185. {
  186. CallLuaFunction(AddClick1);
  187. }
  188. else if (GUI.Button(new Rect(10, 110, 120, 40), " + Click2"))
  189. {
  190. CallLuaFunction(AddClick2);
  191. }
  192. else if (GUI.Button(new Rect(10, 160, 120, 40), " - Click1"))
  193. {
  194. CallLuaFunction(RemoveClick1);
  195. }
  196. else if (GUI.Button(new Rect(10, 210, 120, 40), " - Click2"))
  197. {
  198. CallLuaFunction(RemoveClick2);
  199. }
  200. else if (GUI.Button(new Rect(10, 260, 120, 40), "+ Click1 in C#"))
  201. {
  202. LuaFunction func = state.GetFunction("DoClick1");
  203. TestEventListener.OnClick onClick = (TestEventListener.OnClick)DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func);
  204. listener.onClick += onClick;
  205. }
  206. else if (GUI.Button(new Rect(10, 310, 120, 40), " - Click1 in C#"))
  207. {
  208. LuaFunction func = state.GetFunction("DoClick1");
  209. listener.onClick = (TestEventListener.OnClick)DelegateFactory.RemoveDelegate(listener.onClick, func);
  210. func.Dispose();
  211. func = null;
  212. }
  213. else if (GUI.Button(new Rect(10, 360, 120, 40), "OnClick"))
  214. {
  215. if (listener.onClick != null)
  216. {
  217. listener.onClick(gameObject);
  218. }
  219. else
  220. {
  221. Debug.Log("empty delegate!!");
  222. }
  223. }
  224. else if (GUI.Button(new Rect(10, 410, 120, 40), "Override"))
  225. {
  226. CallLuaFunction(TestOverride);
  227. }
  228. else if (GUI.Button(new Rect(10, 460, 120, 40), "Force GC"))
  229. {
  230. //自动gc log: collect lua reference name , id xxx in thread
  231. state.LuaGC(LuaGCOptions.LUA_GCCOLLECT, 0);
  232. GC.Collect();
  233. }
  234. else if (GUI.Button(new Rect(10, 510, 120, 40), "event +"))
  235. {
  236. CallLuaFunction(AddEvent);
  237. }
  238. else if (GUI.Button(new Rect(10, 560, 120, 40), "event -"))
  239. {
  240. CallLuaFunction(RemoveEvent);
  241. }
  242. else if (GUI.Button(new Rect(10, 610, 120, 40), "event call"))
  243. {
  244. listener.OnClickEvent(gameObject);
  245. }
  246. else if (GUI.Button(new Rect(200, 10, 120, 40), "+self call"))
  247. {
  248. CallLuaFunction(AddSelfClick);
  249. }
  250. else if (GUI.Button(new Rect(200, 60, 120, 40), "-self call"))
  251. {
  252. CallLuaFunction(RemoveSelfClick);
  253. }
  254. }
  255. void Update()
  256. {
  257. state.Collect();
  258. state.CheckTop();
  259. }
  260. void SafeRelease(ref LuaFunction luaRef)
  261. {
  262. if (luaRef != null)
  263. {
  264. luaRef.Dispose();
  265. luaRef = null;
  266. }
  267. }
  268. void OnDestroy()
  269. {
  270. SafeRelease(ref AddClick1);
  271. SafeRelease(ref AddClick2);
  272. SafeRelease(ref RemoveClick1);
  273. SafeRelease(ref RemoveClick2);
  274. SafeRelease(ref SetClick1);
  275. SafeRelease(ref TestOverride);
  276. state.Dispose();
  277. state = null;
  278. }
  279. }

TestEventListener.cs

  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using LuaInterface;
  5. public class TestEventListener : MonoBehaviour
  6. {
  7. public delegate void VoidDelegate(GameObject go);
  8. public delegate void OnClick(GameObject go);
  9. public OnClick onClick = delegate { };
  10. public event OnClick onClickEvent = delegate { };
  11. public Func<bool> TestFunc = null;
  12. public void SetOnFinished(OnClick click)
  13. {
  14. Debugger.Log("SetOnFinished OnClick");
  15. }
  16. public void SetOnFinished(VoidDelegate click)
  17. {
  18. Debugger.Log("SetOnFinished VoidDelegate");
  19. }
  20. [NoToLuaAttribute]
  21. public void OnClickEvent(GameObject go)
  22. {
  23. onClickEvent(go);
  24. }
  25. }

TestEventListenerWrap.cs

  1. //this source code was auto-generated by tolua#, do not modify it
  2. using System;
  3. using LuaInterface;
  4. public class TestEventListenerWrap
  5. {
  6. public static void Register(LuaState L)
  7. {
  8. L.BeginClass(typeof(TestEventListener), typeof(UnityEngine.MonoBehaviour));
  9. L.RegFunction("SetOnFinished", SetOnFinished);
  10. L.RegFunction("__eq", op_Equality);
  11. L.RegFunction("__tostring", Lua_ToString);
  12. L.RegVar("onClick", get_onClick, set_onClick);
  13. L.RegVar("onClickEvent", get_onClickEvent, set_onClickEvent);
  14. L.RegFunction("OnClick", TestEventListener_OnClick);
  15. L.RegFunction("VoidDelegate", TestEventListener_VoidDelegate);
  16. L.EndClass();
  17. }
  18. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  19. static int SetOnFinished(IntPtr L)
  20. {
  21. try
  22. {
  23. int count = LuaDLL.lua_gettop(L);
  24. if (count == 2 && TypeChecker.CheckTypes(L, 1, typeof(TestEventListener), typeof(TestEventListener.VoidDelegate)))
  25. {
  26. TestEventListener obj = (TestEventListener)ToLua.ToObject(L, 1);
  27. TestEventListener.VoidDelegate arg0 = null;
  28. LuaTypes funcType2 = LuaDLL.lua_type(L, 2);
  29. if (funcType2 != LuaTypes.LUA_TFUNCTION)
  30. {
  31. arg0 = (TestEventListener.VoidDelegate)ToLua.ToObject(L, 2);
  32. }
  33. else
  34. {
  35. LuaFunction func = ToLua.ToLuaFunction(L, 2);
  36. arg0 = DelegateFactory.CreateDelegate(typeof(TestEventListener.VoidDelegate), func) as TestEventListener.VoidDelegate;
  37. }
  38. obj.SetOnFinished(arg0);
  39. return 0;
  40. }
  41. else if (count == 2 && TypeChecker.CheckTypes(L, 1, typeof(TestEventListener), typeof(TestEventListener.OnClick)))
  42. {
  43. TestEventListener obj = (TestEventListener)ToLua.ToObject(L, 1);
  44. TestEventListener.OnClick arg0 = null;
  45. LuaTypes funcType2 = LuaDLL.lua_type(L, 2);
  46. if (funcType2 != LuaTypes.LUA_TFUNCTION)
  47. {
  48. arg0 = (TestEventListener.OnClick)ToLua.ToObject(L, 2);
  49. }
  50. else
  51. {
  52. LuaFunction func = ToLua.ToLuaFunction(L, 2);
  53. arg0 = DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func) as TestEventListener.OnClick;
  54. }
  55. obj.SetOnFinished(arg0);
  56. return 0;
  57. }
  58. else
  59. {
  60. return LuaDLL.luaL_throw(L, "invalid arguments to method: TestEventListener.SetOnFinished");
  61. }
  62. }
  63. catch(Exception e)
  64. {
  65. return LuaDLL.toluaL_exception(L, e);
  66. }
  67. }
  68. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  69. static int op_Equality(IntPtr L)
  70. {
  71. try
  72. {
  73. ToLua.CheckArgsCount(L, 2);
  74. UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1);
  75. UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2);
  76. bool o = arg0 == arg1;
  77. LuaDLL.lua_pushboolean(L, o);
  78. return 1;
  79. }
  80. catch(Exception e)
  81. {
  82. return LuaDLL.toluaL_exception(L, e);
  83. }
  84. }
  85. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  86. static int Lua_ToString(IntPtr L)
  87. {
  88. object obj = ToLua.ToObject(L, 1);
  89. if (obj != null)
  90. {
  91. LuaDLL.lua_pushstring(L, obj.ToString());
  92. }
  93. else
  94. {
  95. LuaDLL.lua_pushnil(L);
  96. }
  97. return 1;
  98. }
  99. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  100. static int get_onClick(IntPtr L)
  101. {
  102. object o = null;
  103. try
  104. {
  105. o = ToLua.ToObject(L, 1);
  106. TestEventListener obj = (TestEventListener)o;
  107. TestEventListener.OnClick ret = obj.onClick;
  108. ToLua.Push(L, ret);
  109. return 1;
  110. }
  111. catch(Exception e)
  112. {
  113. return LuaDLL.toluaL_exception(L, e, o == null ? "attempt to index onClick on a nil value" : e.Message);
  114. }
  115. }
  116. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  117. static int get_onClickEvent(IntPtr L)
  118. {
  119. ToLua.Push(L, new EventObject("TestEventListener.onClickEvent"));
  120. return 1;
  121. }
  122. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  123. static int set_onClick(IntPtr L)
  124. {
  125. object o = null;
  126. try
  127. {
  128. o = ToLua.ToObject(L, 1);
  129. TestEventListener obj = (TestEventListener)o;
  130. TestEventListener.OnClick arg0 = null;
  131. LuaTypes funcType2 = LuaDLL.lua_type(L, 2);
  132. if (funcType2 != LuaTypes.LUA_TFUNCTION)
  133. {
  134. arg0 = (TestEventListener.OnClick)ToLua.CheckObject(L, 2, typeof(TestEventListener.OnClick));
  135. }
  136. else
  137. {
  138. LuaFunction func = ToLua.ToLuaFunction(L, 2);
  139. arg0 = DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func) as TestEventListener.OnClick;
  140. }
  141. obj.onClick = arg0;
  142. return 0;
  143. }
  144. catch(Exception e)
  145. {
  146. return LuaDLL.toluaL_exception(L, e, o == null ? "attempt to index onClick on a nil value" : e.Message);
  147. }
  148. }
  149. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  150. static int set_onClickEvent(IntPtr L)
  151. {
  152. try
  153. {
  154. TestEventListener obj = (TestEventListener)ToLua.CheckObject(L, 1, typeof(TestEventListener));
  155. EventObject arg0 = null;
  156. if (LuaDLL.lua_isuserdata(L, 2) != 0)
  157. {
  158. arg0 = (EventObject)ToLua.ToObject(L, 2);
  159. }
  160. else
  161. {
  162. return LuaDLL.luaL_throw(L, "The event 'TestEventListener.onClickEvent' can only appear on the left hand side of += or -= when used outside of the type 'TestEventListener'");
  163. }
  164. if (arg0.op == EventOp.Add)
  165. {
  166. TestEventListener.OnClick ev = (TestEventListener.OnClick)DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), arg0.func);
  167. obj.onClickEvent += ev;
  168. }
  169. else if (arg0.op == EventOp.Sub)
  170. {
  171. TestEventListener.OnClick ev = (TestEventListener.OnClick)LuaMisc.GetEventHandler(obj, typeof(TestEventListener), "onClickEvent");
  172. Delegate[] ds = ev.GetInvocationList();
  173. LuaState state = LuaState.Get(L);
  174. for (int i = 0; i < ds.Length; i++)
  175. {
  176. ev = (TestEventListener.OnClick)ds[i];
  177. LuaDelegate ld = ev.Target as LuaDelegate;
  178. if (ld != null && ld.func == arg0.func)
  179. {
  180. obj.onClickEvent -= ev;
  181. state.DelayDispose(ld.func);
  182. break;
  183. }
  184. }
  185. arg0.func.Dispose();
  186. }
  187. return 0;
  188. }
  189. catch(Exception e)
  190. {
  191. return LuaDLL.toluaL_exception(L, e);
  192. }
  193. }
  194. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  195. static int TestEventListener_OnClick(IntPtr L)
  196. {
  197. try
  198. {
  199. LuaFunction func = ToLua.CheckLuaFunction(L, 1);
  200. Delegate arg1 = DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func);
  201. ToLua.Push(L, arg1);
  202. return 1;
  203. }
  204. catch(Exception e)
  205. {
  206. return LuaDLL.toluaL_exception(L, e);
  207. }
  208. }
  209. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  210. static int TestEventListener_VoidDelegate(IntPtr L)
  211. {
  212. try
  213. {
  214. LuaFunction func = ToLua.CheckLuaFunction(L, 1);
  215. Delegate arg1 = DelegateFactory.CreateDelegate(typeof(TestEventListener.VoidDelegate), func);
  216. ToLua.Push(L, arg1);
  217. return 1;
  218. }
  219. catch(Exception e)
  220. {
  221. return LuaDLL.toluaL_exception(L, e);
  222. }
  223. }
  224. }

?