1. 协程只能在Lua代码中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
c = require ( 'c' )
co = coroutine.create ( function ()
print ( 'coroutine yielding' )
c.callback( function ()
coroutine.yield ()
end )
print ( 'coroutine resumed' )
end )
coroutine.resume (co)
coroutine.resume (co)
print ( 'the end' )
|
1
|
local c = require 'c'
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include<stdio.h> #include<stdlib.h> #include<lua.h> #include<lualib.h> #include<lauxlib.h> static int c_callback(lua_State *L){
int ret = lua_pcall(L, 0, 0, 0);
if (ret){
fprintf (stderr, "Error: %s\n" , lua_tostring(L, -1));
lua_pop(L, 1);
exit (1);
}
return 0;
} static const luaL_Reg c[] = {
{ "callback" , c_callback},
{NULL, NULL}
}; LUALIB_API int luaopen_c (lua_State *L) {
luaL_register(L, "c" , c);
return 1;
} |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include<stdio.h> #include<stdlib.h> #define LUA_LIB /* 告诉Lua,这是一个LIB文件 */ #include<lua.h> #include<lualib.h> #include<lauxlib.h> static int c_cont(lua_State *L) {
/* 这里什么都不用做:因为你的原函数里面就没做什么 */ return 0;
} static int c_callback(lua_State *L){
/* 使用 lua_pcallk,而不是lua_pcall */ int ret = lua_pcallk(L, 0, 0, 0, 0, c_cont);
if (ret) {
fprintf (stderr, "Error: %s\n" , lua_tostring(L, -1));
lua_pop(L, 1);
exit (1);
}
/* 因为你这里什么都没做,所以c_cont里面才什么都没有。如果这里需要做
* 什么东西,将所有内容挪到c_cont里面去,然后在这里简单地调用
* return c_cont(L);
* 即可。
*/ return 0;
} static const luaL_Reg c[] = {
{ "callback" , c_callback},
{NULL, NULL}
}; LUALIB_API int luaopen_c (lua_State *L) {
/* 使用新的 luaL_newlib 函数 */ luaL_newlib(L, c);
return 1;
} |
1
2
3
4
|
lua -- co.lua coroutine yielding coroutine resumed the end |
1
2
3
4
5
6
7
8
9
|
function do_login(server)
server:login( function (data)
-- 错误处理先不管,假设有一个全局处理错误的机制(后面会提到,实际
-- 上就是newtry/protect机制)
server:get_player_info( function (data)
player:move_to(data.x, data.y)
end )
end , "username" , "password" )
end |
1
2
3
4
5
|
function d_login(server)
server:login( "username" , "password" )
local data = server:get_player_info()
player:move_to(data.x, data.y)
end |
1
2
3
4
5
6
7
8
9
10
11
|
local current
function server:login(name, password)
assert ( not current, "already send login message!" )
server:callback_login( function (data)
local cur = current
current = nil coroutine.resume (cur, data)
end , name, password)
current = coroutine.running ()
coroutine.yield ()
end |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function coroutinize(f, reenter_errmsg)
local current
return function (...)
assert ( not current, reenter_errmsg)
f( function (...)
local cur = current
current = nil coroutine.resume (cur, ...)
end , ...)
current = coroutine.running ()
coroutine.yield ()
end end |
2. 幽灵一般的 nil
1
2
3
4
5
6
7
|
全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论