Quantcast
Channel: 看雪安全论坛
Viewing all articles
Browse latest Browse all 9556

其他内容 【测试】Lua脚本利用协程解决游戏中同时处理多个事务

$
0
0
--Lua脚本

function f1()
for i=1,5 do
delay(1000)
setCaption('脚本1 '..i )
end
setCaption('脚本1 结束')
end

function f2()
for i=1,5 do
delay(2000)
setCaption('脚本2 '..i )
end
setCaption('脚本2 结束')
end

function f3()
for i=1,5 do
delay(3000)
setCaption('脚本3 '..i )
end
setCaption('脚本3 结束')
end

co1=coroutine.create(f1)
co2=coroutine.create(f2)
co3=coroutine.create(f3)

coroutine.resume(co1)
coroutine.resume(co2)
coroutine.resume(co3)

运行结果

脚本1 1
脚本1 2
脚本2 1
脚本1 3
脚本3 1
脚本1 4
脚本2 2
脚本1 5
脚本1 结束
脚本2 3
脚本3 2
脚本2 4
脚本3 3
脚本2 5
脚本2 结束
脚本3 4
脚本3 5
脚本3 结束

实现原理
在主函数中为每个函数(f1,f2,f3)创建一个协程(co1,co2,co3)
在脚本中调用函数Delay时, 设置了一个定时器, 调用Yield把脚本挂起
当定时器时间到时, 调用Resume再恢复脚本的运行,
协程co1,co2,co3在运行到delay这个函数时,都会挂起自已,
让其它协程有机会获得执行权
任何时候最多只有1个协程是在运行的
但看起来就象是同时运行在运行函数f1,f2,f3

宿主程序中的代码(Delphi)如下
var
LuaTimerList:Tlist;

procedure LuaTimerProc(hWnd: HWND; uMsg: UINT; idEvent: UINT; Time: DWORD);stdcall;
var
i:integer;
id:UINT;
LuaState: TLuaState;
begin
killtimer(hwnd,idEvent);

for i:=(LuaTimerList.Count div 2) -1 downto 0 do begin
id:=UINT(LuaTimerList.Items[i*2+1]);
if id=idEvent then begin
LuaState:=TLuaState(LuaTimerList[i*2]);
LuaTimerList.Delete(i*2+1);
LuaTimerList.Delete(i*2);
lua_resume(LuaState,0);
end;
end;
end;

function TTestLua.delay(LuaState: TLuaState): Integer;
var
milliseconds:integer;
id:integer;
begin
if Lua_Gettop(LuaState)=0 then exit;
milliseconds := Lua_ToInteger(LuaState,1);
id := settimer(0,0,milliseconds,@LuaTimerProc);
if LuaTimerList=nil then LuaTimerList := TList.create;

LuaTimerList.Add(pointer(LuaState));
LuaTimerList.Add(pointer(id));
//登记一下定时器ID对应的Lua实例

result:=Lua_Yield(LuaState,0);
end;

Viewing all articles
Browse latest Browse all 9556

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>