So rufen Sie Lua-Methoden und GC-freie Methoden in C# im Toluaframework auf

Frage

Wer das Luaframework-Framework verwendet hat, sollte wissen, dass das Framework die Util-Tool-Klasse und die Tool-Klasse eine Methode bereitstellt:Util.CallMethod-Methode, um den direkten Aufruf von Lua-Layer-Methoden in Unity zu erleichtern.

Util.CallMethod

        /// <summary>
        /// 执行Lua方法
        /// </summary>
        public static object[] CallMethod(string module, string func, params object[] args)
        {
    
    
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
    
    
                Debug.LogError("lua模块“" + module + "”未被找到");
                return null;
            }
            return luaMgr.CallFunction(module + "." + func, args);
        }

LuaManager.CallFunction

Die vom hier verwendeten Framework bereitgestellte Methode, aber diese Methode verfügt über GC. Schauen wir uns das nach der Eingabe anluaMgr.CallFunction

// Update is called once per frame
        public object[] CallFunction(string funcName, params object[] args) {
    
    
            LuaFunction func = lua.GetFunction(funcName);
            if (func != null) {
    
    
                return func.LazyCall(args);
            }
            return null;
        }

Aus dem obigen Code können wir erkennen, dass er tatsächlich LazyCall() aufruft. Der Rückgabewert dieser Methode ist object[]. Dazu müssen wir sie selbst entpacken und packen. Es gibt GC-Operationen, um das Entpacken so weit wie möglich zu vermeiden. Boxen kann den Leistungsverbrauch senken.

LuaFunction.LazyCall

Der Autor dieser Methode wies auch darauf hin, dass es einen GC gibt. Hier verwenden wir den Aufruf der Invoke-Methode, sodass wir den Konvertierungsvorgang des Ein- und Auspackens nicht benötigen und ihn direkt in die benötigten Daten konvertieren können.

        //慎用, 有gc alloc
        [System.Obsolete("LuaFunction.LazyCall() is obsolete.Use LuaFunction.Invoke()")]
        public object[] LazyCall(params object[] args)
        {
    
    
            BeginPCall();
            int count = args == null ? 0 : args.Length;

            if (!luaState.LuaCheckStack(count + 6))
            {
    
    
                EndPCall();
                throw new LuaException("stack overflow");
            }
            
            PushArgs(args);
            PCall();
            object[] objs = luaState.CheckObjects(oldTop);
            EndPCall();
            return objs;
        }

Lösung

Hier gebe ich nur ein Beispiel zum Schreiben einer Methode mit zwei Parametern. Für Methoden mit mehreren Parametern imitieren Sie einfach meine Methode und schreiben Sie sie selbst. Sie können so viele Methoden mit so vielen Parametern schreiben, wie Sie benötigen.

LuaFunction-Skript

Werfen wir zunächst einen Blick darauf, was uns der Autor dieses Skripts zur Verfügung stellt
Hier stellt uns der AutorMultiparameter-Aufruf ohne Rückgabewert zur Verfügung a> Methode bietet auch Multiparameter-Invoke mit Rückgabewert
Fügen Sie hier eine Bildbeschreibung ein

GC-freie Anrufe

Suchen Sie das Originalskript mit GC-Verbrauch im LuaManager-Skript, und darunter fügen wir zwei polymorphe Schreibmethoden hinzu
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie zwei polymorphe Methoden ohne GC-Verbrauch hinzu

 	// Update is called once per frame 原始有GC的方法
    public object[] CallFunction(string funcName, params object[] args) {
    
    
        LuaFunction func = lua.GetFunction(funcName);
        if (func != null) {
    
    
            return func.LazyCall(args);//这里有GC
        }
        return null;
    }

	//有返回值并且有两个参数的无GC调用方法
    public R CallFunction<T1,T2,R>(string funcName, T1 t1,T2 t2)
    {
    
    
        LuaFunction func = lua.GetFunction(funcName);
        if (func != null)
        {
    
    
            return func.Invoke<T1,T2,R>(t1,t2);
        }
        return default;
    }

	//无返回值并且有两个参数的无GC调用方法
    public void CallFunction<T1, T2>(string funcName, T1 t1, T2 t2)
    {
    
    
        LuaFunction func = lua.GetFunction(funcName);
        if (func != null)
        {
    
    
            func.Call<T1, T2>(t1, t2);
        }
    }

Öffnen Sie das Util-Toolklassenskript und suchen Sie die ursprüngliche Toolklassen-Aufrufmethode mit GC
Fügen Sie hier eine Bildbeschreibung ein
Nachfolgend schreiben wir zwei Aufrufmethoden, um sie zu kapseln

		/// <summary>
        /// 执行Lua方法 有GC
        /// </summary>
        public static object[] CallMethod(string module, string func, params object[] args)
        {
    
    
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
    
    
                Debug.LogError("lua模块“" + module + "”未被找到");
                return null;
            }
            return luaMgr.CallFunction(module + "." + func, args);
        }

		//无返回值无GC两个参数的方法
        public static void NoGCCallMethod<T1, T2>(string module, string func, T1 t1, T2 t2)
        {
    
    
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
    
    
                Debug.LogError("lua模块“" + module + "”未被找到");
            }
            luaMgr.CallFunction(module + "." + func, t1 ,t2);
        }

		//有返回值无GC两个参数的方法
        public static R InvokeMethod<T1, T2, R>(string module, string func, T1 t1, T2 t2)
        {
    
    
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
    
    
                Debug.LogError("lua模块“" + module + "”未被找到");
                return default;
            }
            return luaMgr.CallFunction<T1, T2, R>(module + "." + func, t1, t2);
        }

Nutzungszusammenfassung

Das Folgende ist die ursprüngliche aufrufende Methode mit GC und die aufrufende Methode ohne GC. Aufrufreferenz
Fügen Sie hier eine Bildbeschreibung ein

Guess you like

Origin blog.csdn.net/qq_42194657/article/details/134060255