展示了Lua对C#中的委托类型的操作。
「1」代码
操作代码如下:
function DoClick1(go)
print('click1 gameObject is '..go.name)
end
function DoClick2(go)
print('click2 gameObject is '..go.name)
end
function AddClick1(listener)
if listener.onClick then
listener.onClick = listener.onClick + DoClick1
else
listener.onClick = DoClick1
end
end
function AddClick2(listener)
if listener.onClick then
listener.onClick = listener.onClick + DoClick2
else
listener.onClick = DoClick2
end
end
function SetClick1(listener)
if listener.onClick then
listener.onClick:Destroy()
end
listener.onClick = DoClick1
end
function RemoveClick1(listener)
if listener.onClick then
listener.onClick = listener.onClick - DoClick1
else
print('empty delegate')
end
end
function RemoveClick2(listener)
if listener.onClick then
listener.onClick = listener.onClick - DoClick2
else
print('empty delegate')
end
end
--测试重载问题
function TestOverride(listener)
listener:SetOnFinished(TestEventListener.OnClick(DoClick1))
listener:SetOnFinished(TestEventListener.VoidDelegate(DoClick2))
end
function TestEvent()
print('this is a event')
end
function AddEvent(listener)
listener.onClickEvent = listener.onClickEvent + TestEvent
end
function RemoveEvent(listener)
listener.onClickEvent = listener.onClickEvent - TestEvent
end
local t = {name = 'byself'}
function t:TestSelffunc()
print('callback with self: '..self.name)
end
function AddSelfClick(listener)
if listener.onClick then
listener.onClick = listener.onClick + TestEventListener.OnClick(t.TestSelffunc, t)
else
listener.onClick = TestEventListener.OnClick(t.TestSelffunc, t)
end
end
function RemoveSelfClick(listener)
if listener.onClick then
listener.onClick = listener.onClick - TestEventListener.OnClick(t.TestSelffunc, t)
else
print('empty delegate')
end
end
c#代码如下:
public sealed class TestEventListener : MonoBehaviour
{
public delegate void VoidDelegate(GameObject go);
public delegate void OnClick(GameObject go);
public OnClick onClick = delegate { };
public event OnClick onClickEvent = delegate { };
public Func<bool> TestFunc = null;
public void SetOnFinished(OnClick click)
{
Debugger.Log("SetOnFinished OnClick");
}
public void SetOnFinished(VoidDelegate click)
{
Debugger.Log("SetOnFinished VoidDelegate");
}
[NoToLuaAttribute]
public void OnClickEvent(GameObject go)
{
onClickEvent(go);
}
}
new LuaResLoader();
state = new LuaState();
state.Start();
LuaBinder.Bind(state);
Bind(state);
state.LogGC = true;
state.DoString(script);
GameObject go = new GameObject("TestGo");
listener = (TestEventListener)go.AddComponent(typeof(TestEventListener));
SetClick1 = state.GetFunction("SetClick1");
AddClick1 = state.GetFunction("AddClick1");
AddClick2 = state.GetFunction("AddClick2");
RemoveClick1 = state.GetFunction("RemoveClick1");
RemoveClick2 = state.GetFunction("RemoveClick2");
TestOverride = state.GetFunction("TestOverride");
AddEvent = state.GetFunction("AddEvent");
RemoveEvent = state.GetFunction("RemoveEvent");
AddSelfClick = state.GetFunction("AddSelfClick");
RemoveSelfClick = state.GetFunction("RemoveSelfClick");
void CallLuaFunction(LuaFunction func)
{
tips = "";
func.BeginPCall();
func.Push(listener);
func.PCall();
func.EndPCall();
}
void OnGUI()
{
GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);
if (GUI.Button(new Rect(10, 10, 120, 40), " = OnClick1"))
{
CallLuaFunction(SetClick1);
}
else if (GUI.Button(new Rect(10, 60, 120, 40), " + Click1"))
{
CallLuaFunction(AddClick1);
}
else if (GUI.Button(new Rect(10, 110, 120, 40), " + Click2"))
{
CallLuaFunction(AddClick2);
}
else if (GUI.Button(new Rect(10, 160, 120, 40), " - Click1"))
{
CallLuaFunction(RemoveClick1);
}
else if (GUI.Button(new Rect(10, 210, 120, 40), " - Click2"))
{
CallLuaFunction(RemoveClick2);
}
else if (GUI.Button(new Rect(10, 260, 120, 40), "+ Click1 in C#"))
{
tips = "";
LuaFunction func = state.GetFunction("DoClick1");
TestEventListener.OnClick onClick = (TestEventListener.OnClick)DelegateTraits<TestEventListener.OnClick>.Create(func);
listener.onClick += onClick;
}
else if (GUI.Button(new Rect(10, 310, 120, 40), " - Click1 in C#"))
{
tips = "";
LuaFunction func = state.GetFunction("DoClick1");
listener.onClick = (TestEventListener.OnClick)DelegateFactory.RemoveDelegate(listener.onClick, func);
func.Dispose();
func = null;
}
else if (GUI.Button(new Rect(10, 360, 120, 40), "OnClick"))
{
if (listener.onClick != null)
{
listener.onClick(gameObject);
}
else
{
Debug.Log("empty delegate!!");
}
}
else if (GUI.Button(new Rect(10, 410, 120, 40), "Override"))
{
CallLuaFunction(TestOverride);
}
else if (GUI.Button(new Rect(10, 460, 120, 40), "Force GC"))
{
//自动gc log: collect lua reference name , id xxx in thread
state.LuaGC(LuaGCOptions.LUA_GCCOLLECT, 0);
GC.Collect();
}
else if (GUI.Button(new Rect(10, 510, 120, 40), "event +"))
{
CallLuaFunction(AddEvent);
}
else if (GUI.Button(new Rect(10, 560, 120, 40), "event -"))
{
CallLuaFunction(RemoveEvent);
}
else if (GUI.Button(new Rect(10, 610, 120, 40), "event call"))
{
listener.OnClickEvent(gameObject);
}
else if (GUI.Button(new Rect(200, 10, 120, 40), "+self call"))
{
CallLuaFunction(AddSelfClick);
}
else if (GUI.Button(new Rect(200, 60, 120, 40), "-self call"))
{
CallLuaFunction(RemoveSelfClick);
}
}
「2」需要了解的部分
-
这个代码比较长,看的人眼花缭乱,不过没关系,一步一步来就简单了。首先要说明的是
TestEventListener
是一个带有委托变量的类,这里可以认为已经被Lua所认识。在C#代码中,将这个类的实例对象listener传入CallLuaFunction函数中,进入Lua代码。在Lua的函数中对象listener的委托变量进行了加法和减法。 -
" + Click in C# " 和 " - Click in C#" 则是展示了如何在C#中增加和删除绑定的lua方法,其实就是将lua方法取出到C#中,然后转成LuaFunction ,然后直接使用
DelegateFactory.CreateDelegate
和DelegateFactory.RemoveDelegate
。 -
此外重载函数也在Lua中适用,参数为不同类型的委托对象,执行不同的重载函数。
--测试重载问题
function TestOverride(listener)
listener:SetOnFinished(TestEventListener.OnClick(DoClick1))
listener:SetOnFinished(TestEventListener.VoidDelegate(DoClick2))
end
- 这里还可以手动创建委托对象,格式需要记一下:
TestEventListener.Onclick(DoClick1)
网友评论