5 lua coroutine
TestLuaCoroutine.lua:
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()
print('Coroutine started')
print("begin frameCount: "..Time.frameCount)
for i = 0, 10, 1 do
print(fib(i))
coroutine.wait(0.1)
end
print("current frameCount: "..Time.frameCount)
coroutine.step()
print("yield frameCount: "..Time.frameCount)
local www = UnityEngine.WWW("https://www.baidu.com")
coroutine.www(www)
print("after www frameCount: "..Time.frameCount)
local s = tolua.tolstring(www.bytes)
print(s:sub(1, 8))
print('Coroutine ended')
end
function TestCortinue()
coroutine.start(CoFunc)
end
local coDelay = nil
function Delay()
local c = 1
while true do
coroutine.wait(1)
print("Count: "..c)
c = c + 1
end
end
function StartDelay()
coDelay = coroutine.start(Delay)
end
function StopDelay()
coroutine.stop(coDelay)
end
lua中协程的使用:
协程函数的开启 : coroutine.start(协程函数)
协程函数的挂起: coroutine.step() 协同中等待一帧.
协程函数的延时: coroutine.wait(延时时间) 注意:时间的单位是秒
协程函数的结束: coroutine.stop(协程对象) 注意:协程函数关闭的协程对象是对应的协程开启函数的返回值
协程下载: coroutine.www(网址)
其中,除了 coroutine.start(协程函数) 和 coroutine.stop(协程对象) 之外,其他的协程方法只允许在协程函数的内部使用
C# 代码:
using UnityEngine;
using System;
using System.Collections;
using LuaInterface;
//例子5和6展示的两套协同系统勿交叉使用,此为推荐方案
public class TestCoroutine : MonoBehaviour
{
public TextAsset luaFile = null;
private LuaState lua = null;
private LuaLooper looper = null;
void Awake ()
{
#if UNITY_5 || UNITY_2017 || UNITY_2018
Application.logMessageReceived += ShowTips;
#else
Application.RegisterLogCallback(ShowTips);
#endif
new LuaResLoader();
lua = new LuaState();
lua.Start();
LuaBinder.Bind(lua);
DelegateFactory.Init();
looper = gameObject.AddComponent<LuaLooper>();
looper.luaState = lua;
//首先调用虚拟机的 lua.Start 函数初始化,
//然后调用LuaBinder的静态方法 LuaBinder.Bind(lua);
//参数就是你创建的虚拟机 , 然后为你的一个游戏对象添加组件 LuaLooper ,
//并将该 LuaLooper 的内部虚拟机引用指定为我们创建的虚拟机 ,
//然后我们就可以正常的使用Lua中的协程了,它会在c#每一帧驱动lua的协同完成所有的协同功能,
//这里的协同已经不单单是lua自身功能,而是tolua#模拟unity的所有的功能。
lua.DoString(luaFile.text, "TestLuaCoroutine.lua");
LuaFunction f = lua.GetFunction("TestCortinue");
f.Call();
f.Dispose();
f = null;
}
void OnApplicationQuit()
{
looper.Destroy();
lua.Dispose();
lua = null;
#if UNITY_5 || UNITY_2017 || UNITY_2018
Application.logMessageReceived -= ShowTips;
#else
Application.RegisterLogCallback(null);
#endif
}
string tips = null;
void ShowTips(string msg, string stackTrace, LogType type)
{
tips += msg;
tips += "\r\n";
}
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"))
{
tips = null;
LuaFunction func = lua.GetFunction("StartDelay");
func.Call();
func.Dispose();
}
else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter"))
{
LuaFunction func = lua.GetFunction("StopDelay"); //停掉的是最后一个start的
func.Call();
func.Dispose();
}
else if (GUI.Button(new Rect(50, 250, 120, 45), "GC"))
{
lua.DoString("collectgarbage('collect')", "TestCoroutine.cs");
Resources.UnloadUnusedAssets();
// Resources.UnloadUnusedAssets只是标记,并不清理,并且不是标记为空闲(这个//是GC干的,就是mono的清理,因为mono不归还内存给os,只在mono层标记为空闲,//os层还是使用中),只是把该块内存降级,让gc清理。
//所以destroy an object后调Resources.UnloadUnusedAssets并没有卵用,要等GC
//来了才生效。
}
}
}
结果 打开时候:
GC那里:
测试这个coDelay是否被设置成Nil
function IsNillCoDelay()
if (coDelay == nil) then
print("coDelay nil")
else
print("coDelay not nil")
end
end
结果没有