美文网首页
ToLua的Example示例学习笔记11_Delegate

ToLua的Example示例学习笔记11_Delegate

作者: 凌枫望星月 | 来源:发表于2020-05-12 21:31 被阅读0次

    展示了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.CreateDelegateDelegateFactory.RemoveDelegate

    • 此外重载函数也在Lua中适用,参数为不同类型的委托对象,执行不同的重载函数。

                --测试重载问题
                function TestOverride(listener)
                    listener:SetOnFinished(TestEventListener.OnClick(DoClick1)) 
                    listener:SetOnFinished(TestEventListener.VoidDelegate(DoClick2))
                end
    
    • 这里还可以手动创建委托对象,格式需要记一下:
      TestEventListener.Onclick(DoClick1)

    相关文章

      网友评论

          本文标题:ToLua的Example示例学习笔记11_Delegate

          本文链接:https://www.haomeiwen.com/subject/dwivnhtx.html