toLua[七] Examples 06_LuaCoroutine2分析
一.运行工程
本例展示Lua模拟Unity的Coroutine携程的第二种做法
二.C#代码分析
TestCoroutine2.CS
using UnityEngine;
using System.Collections;
using LuaInterface;//两套协同勿交叉使用,类unity原生,大量使用效率低
public class TestCoroutine2 : LuaClient
{string script =@"function CoExample() WaitForSeconds(1)print('WaitForSeconds end time: '.. UnityEngine.Time.time) WaitForFixedUpdate()print('WaitForFixedUpdate end frameCount: '..UnityEngine.Time.frameCount)WaitForEndOfFrame()print('WaitForEndOfFrame end frameCount: '..UnityEngine.Time.frameCount)Yield(null)print('yield null end frameCount: '..UnityEngine.Time.frameCount)Yield(0)print('yield(0) end frameCime: '..UnityEngine.Time.frameCount)local www = UnityEngine.WWW('http://www.baidu.com')Yield(www)print('yield(www) end time: '.. UnityEngine.Time.time)local s = tolua.tolstring(www.bytes)print(s:sub(1, 128))print('coroutine over')endfunction TestCo() StartCoroutine(CoExample) endlocal coDelay = nilfunction Delay()local c = 1while true doWaitForSeconds(1) print('Count: '..c)c = c + 1endendfunction StartDelay()coDelay = StartCoroutine(Delay) endfunction StopDelay()StopCoroutine(coDelay)coDelay = nilend";protected override LuaFileUtils InitLoader(){return new LuaResLoader();}protected override void OnLoadFinished(){base.OnLoadFinished();luaState.DoString(script, "TestCoroutine2.cs");LuaFunction func = luaState.GetFunction("TestCo");func.Call();func.Dispose();func = null;}//屏蔽,例子不需要运行protected override void CallMain() { }bool beStart = false;string tips = null;void Start(){
#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += ShowTips;
#elseApplication.RegisterLogCallback(ShowTips);
#endif}void ShowTips(string msg, string stackTrace, LogType type){tips += msg;tips += "\r\n";}new void OnApplicationQuit(){
#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endifbase.OnApplicationQuit();}void OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);if (GUI.Button(new Rect(50, 50, 120, 45), "Start Counter")){if (!beStart){beStart = true;tips = "";LuaFunction func = luaState.GetFunction("StartDelay");func.Call();func.Dispose();}}else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter")){if (beStart){beStart = false;LuaFunction func = luaState.GetFunction("StopDelay");func.Call();func.Dispose();}}}
}
2.1 LuaClient.CS
首先看第六行TestCoroutine2 继承自 LuaClient
public class TestCoroutine2 : LuaClient
LuaClient的159-177行可以看出其初始化时创建了LuaState对象,故TestCoroutine2中没有LuaState对象的创建,可以直接使用父类的
protected void Init(){ InitLoader();luaState = new LuaState();OpenLibs();luaState.LuaSetTop(0);Bind(); LoadLuaFiles(); }protected void Awake(){Instance = this;Init();#if UNITY_5_4_OR_NEWERSceneManager.sceneLoaded += OnSceneLoaded;
#endif }
再来看TestCoroutine2.CS的64-66行,执行Lua方法TestCo
luaState.DoString(script, "TestCoroutine2.cs");LuaFunction func = luaState.GetFunction("TestCo");func.Call();
TestCoroutine2.CS的29-31行TestCo调用StartCoroutine
function TestCo() StartCoroutine(CoExample) end
2.2 LuaCoroutine.CS
全局搜索function StartCoroutine可以看到其定义位于文件LuaCoroutine.CS中
在DoString处加入断点,可以看到其由LuaClient的Awake中间接调用
三.Lua代码分析
从StartCoroutine的Lua实现来看,其用的是Lua语言自身的coroutine
function StartCoroutine(func)local co = coroutine.create(func) local flag, msg = coroutine.resume(co)if not flag thenmsg = debug.traceback(co, msg)error(msg)endreturn coend