ToLua Example 7 TestLuaThread

13 篇文章 0 订阅

 

using UnityEngine;

using System.Collections;

using LuaInterface;

 

public class TestLuaThread : MonoBehaviour // luacoroutine映射到C#tolua的封装成luathread对象,resume来控制Lua中线程的运行

{

    string script =

        @"

            function fib(n)

                local a, b = 0, 1

                while n > 0 do

                    a, b = b, a + b

                    n = n - 1

                end

 

                return a

            end

 

            function CoFunc(len)

                print('Coroutine started')               

                local i = 0

                for i = 0, len, 1 do                   

                    local flag = coroutine.yield(fib(i))   --等待resume,返回值就是fib(i)                 

                    if not flag then

                        print('Coroutine not flag')

                        break

                    end                                     

                end

                print('Coroutine ended')

            end

 

            function Test()               

                local co = coroutine.create(CoFunc)                               

                return co

            end           

        ";

 

    LuaState state = null;

    LuaThread thread = null;

    string tips = null;

 

    void Start ()

    {

#if UNITY_5 || UNITY_2017 || UNITY_2018

        Application.logMessageReceived += ShowTips;

#else

        Application.RegisterLogCallback(ShowTips);

#endif

        new LuaResLoader();

        state = new LuaState();

        state.Start();

        state.LogGC = true;

        state.DoString(script);

 

        LuaFunction func = state.GetFunction("Test");

        func.BeginPCall();

        func.PCall();       //创建线程

        thread = func.CheckLuaThread();     //获取LuaThread

        thread.name = "LuaThread";

        func.EndPCall();

        func.Dispose();

        func = null;

 

        thread.Resume(10);  //第一次resume,参数10

    }

 

    void OnApplicationQuit()

    {

        if (thread != null)

        {

            thread.Dispose();

            thread = null;

        }

 

        state.Dispose();

        state = null;

#if UNITY_5 || UNITY_2017 || UNITY_2018

        Application.logMessageReceived -= ShowTips;

#else

        Application.RegisterLogCallback(null);

#endif

    }

 

    void ShowTips(string msg, string stackTrace, LogType type)

    {

        tips += msg;

        tips += "\r\n";

    }

 

    void Update()

    {

        state.CheckTop();

        state.Collect();

    }

 

    void OnGUI()

    {

        GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);

 

        if (GUI.Button(new Rect(10, 50, 120, 40), "Resume Thead"))

        {

            int ret = -1;

 

            if (thread != null && thread.Resume(true, out ret) == (int)LuaThreadStatus.LUA_YIELD)

            {               

                Debugger.Log("lua yield: " + ret);

            }

        }

        else if (GUI.Button(new Rect(10, 150, 120, 40), "Close Thread"))

        {

            if (thread != null)

            {               

                thread.Dispose();               

                thread = null;

            }

        }

    }

}

 

在执行到yield之后,代码跳转到上一次resume代码的后一条代码执行

再次调用resume,代码就跳转到上一次yield代码的后一条代码执行。

一般来说,resume方法在主线程中调用;而yield则是在coroutine内调用,包括coroutine内部调用的函数内部。

当然了,在coroutine中调用resume没有什么问题,但这样是没有什么意义的,因为如果代码还在coroutine中执行的话,则说明其状态一定是running的,这个时候的resume是没有任何意义的。而在主线程中调用yield,会导致 “lua: attempt to yield across metamethod/C-call boundary”的错误。

 

 

 

 

Stop的情况:

 

Resume完毕的情况:

 

 

Lualooper的update里面会有:

luaState.Collect();

#if UNITY_EDITOR

        luaState.CheckTop();

#endif

 

所以c#的update因为没有用lualooper就要手动checktop()和collect() ?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值