xLua的Examples\04_LuaObjectOrented

本文深入探讨了xLua框架中C#与Lua脚本间事件及属性变更通知的绑定机制,详细解释了ICalc接口的this[int index]{get;set;}

xLuaExamples/04_LuaObjectOrented

/*
 * Tencent is pleased to support the open source community by making xLua available.
 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
 * http://opensource.org/licenses/MIT
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/

using System;
using UnityEngine;
using XLua;

public class PropertyChangedEventArgs : EventArgs
{
    public string name;
    public object value;
}

public class InvokeLua : MonoBehaviour
{
    [CSharpCallLua]
    public interface ICalc
    {
        event EventHandler<PropertyChangedEventArgs> PropertyChanged;

        int Add(int a, int b);
        int Mult { get; set; }

        object this[int index] { get; set; }
    }

    [CSharpCallLua]
    public delegate ICalc CalcNew(int mult, params string[] args);

    private string script = @"
                local calc_mt = {
                    __index = {
                        Add = function(self, a, b)
                            return (a + b) * self.Mult
                        end,
                        
                        get_Item = function(self, index)
                            return self.list[index + 1]
                        end,

                        set_Item = function(self, index, value)
                            self.list[index + 1] = value
                            self:notify({name = index, value = value})
                        end,
                        
                        add_PropertyChanged = function(self, delegate)
	                        if self.notifylist == nil then
		                        self.notifylist = {}
	                        end
	                        table.insert(self.notifylist, delegate)
                            print('add',delegate)
                        end,
                                                
                        remove_PropertyChanged = function(self, delegate)
                            for i=1, #self.notifylist do
		                        if CS.System.Object.Equals(self.notifylist[i], delegate) then
			                        table.remove(self.notifylist, i)
			                        break
		                        end
	                        end
                            print('remove', delegate)
                        end,

                        notify = function(self, evt)
	                        if self.notifylist ~= nil then
		                        for i=1, #self.notifylist do
			                        self.notifylist[i](self, evt)
		                        end
	                        end	
                        end,
                    }
                }

                Calc = {
	                New = function (mult, ...)
                        print(...)
                        return setmetatable({Mult = mult, list = {'aaaa','bbbb','cccc'}}, calc_mt)
                    end
                }
	        ";
    // Use this for initialization
    void Start()
    {
        LuaEnv luaenv = new LuaEnv();
        Test(luaenv);//调用了带可变参数的delegate,函数结束都不会释放delegate,即使置空并调用GC
        luaenv.Dispose();
    }

    void Test(LuaEnv luaenv)
    {
        luaenv.DoString(script);
        CalcNew calc_new = luaenv.Global.GetInPath<CalcNew>("Calc.New");
        ICalc calc = calc_new(10, "hi", "john"); //constructor
        Debug.Log("sum(*10) =" + calc.Add(1, 2));
        calc.Mult = 100;
        Debug.Log("sum(*100)=" + calc.Add(1, 2));

        Debug.Log("list[0]=" + calc[0]);
        Debug.Log("list[1]=" + calc[1]);
        
        calc.PropertyChanged += Notify;
        calc[1] = "dddd";
        Debug.Log("list[1]=" + calc[1]);

        calc.PropertyChanged -= Notify;

        calc[1] = "eeee";
        Debug.Log("list[1]=" + calc[1]);
    }

    void Notify(object sender, PropertyChangedEventArgs e)
    {
        Debug.Log(string.Format("{0} has property changed {1}={2}", sender, e.name, e.value));
    }

    // Update is called once per frame
    void Update()
    {

    }
}

从代码比较容易读,但仔细阅读,还是发现有两点疑问
1.ICalc的object this[int index] { get; set; }如何和calc_mt的get_Item和set_Item联系上了的?
  实际上是xLua的规则,如果你定义了 this[int index] { get; set; }那么对应的lua就是get_Item和set_Item

2.ICalc的PropertyChanged如何和calc_mt的add_PropertyChanged和remove_PropertyChanged联系上了的

实际上联系上lua函数的饼不是PropertyChanged而是其+=和--=,这也是xLua的规则。如果定义了委托,那么对于的+=和-=

就是add_委托的名称和remove_委托的名称

 

 

 热更新框架设计系列课程总体介绍:        本系列课程由《热更新框架设计之Xlua基础》、《热更新框架设计之热更流程与热补丁技术》、《热更新框架设计之游戏客户端框架》三套课程组成。 三套课程是一个不可分割有机的整体,笔者带领大家由浅入深逐级深入 ,在领悟热更精髓的基础之上,通过高端架构设计,设计出“低耦合”、“低侵入”、“高复用”性的游戏(VR/AR)客户端热更框架。                           温馨提示:            本套课程需要具备一定的框架理解与驾驭能力,为了更好的理解本作,强烈推荐广大学员首先学完必要的前导课程:“UI客户端框架设计”、“AssetBundle 框架设计”、“lua基础与中级篇”。《热更新框架设计之Xlua基础》课程介绍:       本课程为系列课程的xlua基础部分,本课程主要就xlua的优势、特点、环境搭建、以及lua文件加载、C#调用lua的各种方式、lua调用C#的各种技巧展开讨论与讲解,学后基本掌握xlua中常用的技术基础,为后续课程打下坚实的基础。 热更新系列(技术含量:中高级):A:《lua热更新技术中级篇》https://edu.csdn.net/course/detail/27087B:《热更新框架设计之热更流程与热补丁技术》https://edu.csdn.net/course/detail/27118C:《热更新框架设计之客户端热更框架(上)》https://edu.csdn.net/course/detail/27132D:《热更新框架设计之客户端热更框架(中)》https://edu.csdn.net/course/detail/27135E:《热更新框架设计之客户端热更框架(下)》https://edu.csdn.net/course/detail/27136
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值