首页
社区
课程
招聘
[测试]Lua脚本利用协程解决游戏中同时处理多个事务
发表于: 2013-5-11 15:03 5753

[测试]Lua脚本利用协程解决游戏中同时处理多个事务

2013-5-11 15:03
5753
--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;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
经测试 不用协程也能实现多个脚本同时运行
procedure TForm1.Button2Click(Sender: TObject);
var
  str:string;
  Lua1: TTestLua;
begin
    Lua1 := TTestLua.Create;
    str:=form1.Memo1.Text; //这里存放的是要执行的脚本
    luaL_loadstring(lua1.LuaInstance ,PAnsiChar(AnsiString(str)));
    lua_resume(lua1.LuaInstance ,0);

    //不能进行Free操作, 不然出错
    //lua1.Free ;
    //lua1:=nil;
end;

Button2这个按钮按几下 脚本就启动几次
2013-5-11 19:43
0
游客
登录 | 注册 方可回帖
返回
//