天天看點

08.XLua Lua通路C#中的方法

01.操作符重載和函數重載

C#中定義的操作符重載和函數重載在Lua中基本上能夠使用,不過需要注意的是由于Lua中表示數值的類型隻有一種(number),是以C#中對于數值類型之間的重載是不能夠正确的識别的,通常隻會調用類型符合的重載函數清單中先定義的函數

[LuaCallCSharp]
public class Overload
{
    public int Add(int num1, int num2)
    {
        Debug.Log("Add-int");
        return num1 + num2;
    }

    public float Add(float num1, float num2)
    {
        Debug.Log("Add-float");
        return num1 + num2;
    }

    public string Add(string num1, string num2)
    {
        Debug.Log("Add-string");
        return num1 + num2;
    }
}      
local Overload=CS.Overload--擷取一個類的映射
local overload=CS.Overload()--執行個體化一個類
print(overload:Add(1,2));
print(overload:Add(1.5,2.1));
print(overload:Add("22","22"));      
08.XLua Lua通路C#中的方法

由于在Lua中隻有一種數值類型(number),是以參數為int和float類型的Add函數都滿足要求,這個時候會調用先定義的重載函數,也就是重載為int類型的Add

當先定義參數float類型後定義int類型的Add函數時,Lua代碼調用就是參數類型為float的Add函數了

02.可變參數與預設參數

在Lua中調用它們的時候,參數的規則與C#中相同

對于C#的如下方法:

void VariableParamsFunc(int a, params string[] strs)

可以在lua裡頭這樣調用:

testobj:VariableParamsFunc(5, ‘hello’, ‘john’)

public void DefaultParam(int arg0, string arg1 = "1", int arg2 = 2)
    {
        Debug.Log("arg0:" + arg0);
        Debug.Log("arg1:" + arg1);
        Debug.Log("arg2:" + arg2);
    }

    public void VariableParam(int arg0, params string[] args)
    {
        Debug.Log("arg0:" + arg0);
        Debug.Log(args.Length);
        foreach (string arg in args)
        {
            Debug.Log(arg + " ");
        }
    }      
local Overload=CS.Overload--擷取一個類的映射
local overload=CS.Overload()--執行個體化一個類
overload:VariableParam(10,"1", "2", "3", "4");
overload:DefaultParam(1);      
08.XLua Lua通路C#中的方法

03.通路C#枚舉

枚舉值就像枚舉類型下的靜态屬性一樣。

testobj:EnumTestFunc(CS.Tutorial.TestEnum.E1)

上面的EnumTestFunc函數參數是Tutorial.TestEnum類型的

另外,如果枚舉類加入到生成代碼的話,枚舉類将支援__CastFrom方法,可以實作從一個整數或者字元串到枚舉值的轉換,例如:

CS.Tutorial.TestEnum.__CastFrom(1)

CS.Tutorial.TestEnum.__CastFrom(‘E1’)

在Lua中有以下五種方法可以通路到枚舉變量:

1當作普通的靜态屬性通路

2使用__CastFrom函數,從枚舉值對應的數值做類型轉換

3使用__CastFrom函數,從枚舉值對應的字元串做類型轉換

4直接傳入枚舉值對應的數值

5直接傳入枚舉值對應的字元串

[LuaCallCSharp]
public enum Language
{
    C_PLUS_PLUS,
    C_SHARP
}


[LuaCallCSharp]
public class EnumParam
{
  public void PrintEnum(Language language)
  {
      switch(language){
           case Language.C_PLUS_PLUS:
                Debug.Log("C++");
                break;
            case Language.C_SHARP:
                Debug.Log("C#");
                break;
      }   
  }
}      
--通路枚舉
local enumParam=CS.EnumParam();
local Language=CS.Language;

--當作普通的靜态屬性通路
enumParam:PrintEnum(Language.C_PLUS_PLUS);
--直接傳入枚舉值對應的字元串
enumParam:PrintEnum("C_SHARP")
--直接傳入枚舉值對應的數值
enumParam:PrintEnum(1);
--使用__CastFrom函數,從枚舉值對應的數值做類型轉換
enumParam:PrintEnum(Language.__CastFrom("C_PLUS_PLUS"));
--使用__CastFrom函數,從枚舉值對應的數值做類型轉換
enumParam:PrintEnum(Language.__CastFrom(1));      
08.XLua Lua通路C#中的方法

04.

通路C#委托

delegate使用(調用,+,-)

C#的delegate調用:和調用普通lua函數一樣

+操作符:對應C#的+操作符,把兩個調用串成一個調用鍊,右操作數可以是同類型的C# delegate或者是lua函數。

-操作符:和+相反,把一個delegate從調用鍊中移除。

Ps:delegate屬性可以用一個luafunction來指派。

[LuaCallCSharp]
class DelegateClass
{
    public delegate void ActionString(string arg);

    public ActionString action = (arg) =>
        {
            Debug.Log("action:" + arg);
        };

    public ActionString actionString1 = (arg) =>
        {
            Debug.Log("actionString1:" + arg);
        };

    public ActionString actionString2 = (arg) =>
        {
            Debug.Log("actionString2:" + arg);
        };
}      
--通路委托
local delegateClass=CS.DelegateClass();
--使用delegateClass類的對象通路委托變量action
local action1=delegateClass.action;
action1("hi-1");
--由于在Lua中沒有"+="和"-="操作符,在增加委托鍊的時候隻能使用"+"和"-"操作符
action1=action1+delegateClass.actionString1+delegateClass.actionString2;
action1("hi-2");
action1=action1-delegateClass.actionString2;
action1("hi-3");      
08.XLua Lua通路C#中的方法

在使用Lua代碼通路C#委托時需要注意,通路委托類型的方式與通路靜态變量的方式相同,通路(靜态/非靜态)委托的變量的方式與通路(靜态/非靜态)成員變量的方式相同

--使用DelegateClass類通路委托類型ActionString,
--定義一個ActionString類型的委托變量action2
local DelegateClass=CS.DelegateClass;
local delegateClass=CS.DelegateClass();
---此時action2的值為nil
local action2=DelegateClass.ActionString;
action2=delegateClass.actionString1;
action2("hi-4");
action2=action2+delegateClass.actionString2;
action2("hi-5");      
08.XLua Lua通路C#中的方法

05.通路C#事件

比如testobj裡頭有個事件定義是這樣:public event Action TestEvent;

增加事件回調

testobj:TestEvent(’+’, lua_event_callback)

移除事件回調

testobj:TestEvent(’-’, lua_event_callback)

在通路C#事件的時候需要生成代碼,是以必須要為事件的委托類型加上一個Attribute:[CSharpCallLua],關于為什麼這裡需要加[CSharpCallLua]而不是[LuaCallCSharp],在xLua的github首頁的FAQ上作者是這麼解釋的:

LuaCallCSharp以及CSharpCallLua兩種生成各在什麼場景下用?

看調用者和被調用者,比如要在lua調用C#的GameObject.Find函數,或者調用gameobject的執行個體方法,屬性等,GameObject類要加LuaCallSharp,而想把一個lua函數挂到UI回調,這是調用者是C#,被調用的是一個lua函數,是以回調聲明的delegate要加CSharpCallLua。

有時會比較迷惑人,比如List.Find(Predicate match)的調用,List當然是加LuaCallSharp,而Predicate卻要加CSharpCallLua,因為match的調用者在C#,被調用的是一個lua函數。

更無腦一點的方式是看到“This delegate/interface must add to CSharpCallLua : XXX”,就把XXX加到CSharpCallLua即可。

[LuaCallCSharp]
class EventClass
{
    //在通路C#事件的時候需要生成代碼
    //是以必須要為事件的委托類型加上一個Attribute:[CSharpCallLua],
    [CSharpCallLua]
   public delegate void EventAction();
   public event EventAction Events;
   public EventAction action1 = () =>
   {
           Debug.Log("action1");
   };

    public EventAction action2 = () =>
    {
            Debug.Log("action2");
    };

    public void TriggerEvent()
    {
        Events();
    }
}      

在添加事件的時候,既可以使用C#中的委托變量,也可以使用Lua中的函數

同時在添加和移除事件的時候應該使用以下的方式

function lua_action()
    print("lua_action:")
end

local eventClass=CS.EventClass();
eventClass:Events("+",lua_action);
eventClass:Events("+",eventClass.action1);
eventClass:Events("+",eventClass.action2);
eventClass:TriggerEvent();