案例七:
在这里,总有种被作者套路的赶脚,众所周知,在Lua中不存在那种传统意义上的多线程,所谓的多线程都是基于协程而实现的,所以Lua中的线程也都只是那种协作式的多线程,而无法实现那种抢占式的多线程的效果,这也就导致有些效果我们无法得到实现~~~
如果有的时候真的需要那种抢占式的效果,可以考虑使用我之前提到的那个tolua的作者封装过的协程,功能上赶脚几乎可以替代真正的那种抢占式多线程了
在这个案例之中,其实主要可以学到的就是如何获取到原生的lua线程,并在C#端进行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('len = '..len)
print('Coroutine started')
local i = 0
for i = 0, len, 1 do
local flag = coroutine.yield(fib(i))
if not flag then
break
end
end
print('Coroutine ended')
end
function Test()
local co = coroutine.create(CoFunc)
return co
end
";
LuaState state = null;
//lua线程类型
LuaThread thread = null;
void Start ()
{
//初始化Lua虚拟机
state = new LuaState();
state.Start();
state.LogGC = true;
state.DoString(script);
//从虚拟机中获取到lua函数对象
LuaFunction func = state.GetFunction("Test");
func.BeginPCall();
func.PCall();
thread = func.CheckLuaThread(); //获取对应的线程对象
thread.name = "LuaThread";
func.EndPCall();
func.Dispose();
func = null;
thread.Resume(10); //运行线程并同时传递参数10
}
顺便值得说的一句就是,在对lua线程操作的时候,还要在C#的Update中调用如下代码
void Update()
{
state.CheckTop();
state.Collect();
}
貌似是用于垃圾回收的作用,我大概记得之前也是这个用法,这里暂且留个坑,如果坑了回头一定会补
核心函数:
int Resume(params object[] args)
该方法为thread的内置公有方法,主要作用等同于lua中的
coroutine.resume()
这样说应该基本上都可以懂了吧,如果还是不理解,请回去好好看一下《lua程序设计》中关于协程的那一章
最后还是想补一句,作者对于这种协作式多线程总的而言还是不甚满意,后期有机会作者将会尝试直接在lua引入C#的多线程以及锁机制,具体的方案等我做出来再说
案例8:
这个部分感觉还是相当有用处的,主要是介绍了对于C#中的数组对象的基本的几种访问方法
核心代码全部在那段lua代码中:
function TestArray(array)
local len = array.Length
print('直接输出')
for i = 0, len - 1 do
print('Array: '..tostring(array[i]))
end
print('转Table表后输出')
local t = array:ToTable()
for i = 1, #t do
print('table: '.. tostring(t[i]))
end
local iter = array:GetEnumerator()
while iter:MoveNext() do
print('iter: '..iter.Current)
end
local pos = array:BinarySearch(3)
print('array BinarySearch: pos: '..pos..' value: '..array[pos])
pos = array:IndexOf(4)
print('array indexof 4 pos is: '..pos)
return 1, '123', true
end
在这里,我们可以得出如下几部分结论:
1 :对于C#中的数组,在lua中,我们可以直接通过下标索引访问,写法形式与C#中完全一致,例如: array[i] , 同时还可以通过直接调用 array.Length 获取到数组的大小,感觉对于这类访问作者已经做的使用极度方便了
2:对于C#中的数组,我们可以调用 array:ToTable() 实现将数组对象转化为对应的lua中的Table表的形式
3:第3中访问方式我也不是很熟悉,好像是将其转化成迭代器格式,具体方法为 array:GetEnumerator() ,访问元素的时候可以通过调用 iter:Current 来获取到,通过使用方法iter:MoveNext() 来将迭代器的所指位置移至下一个
4:除了上述的方法之外,可以通过方法 array:BinarySerach(元素下表位置) 的方法来获取到数组对应位置的元素
调用方法 array:IndexOf(数据值) 的方法获取到指定元素的下标的值
实际效果图如下:
以上也就是整个案例8的全部知识点了,
最近找工作的事情终于有了着落,在剩下的一点学生时代,有机会还是乘着这段时间来回忆一下过去所学,留下点东西,也算是了却一桩心愿了