-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathlua_timer_handle.cpp
More file actions
133 lines (118 loc) · 4.41 KB
/
lua_timer_handle.cpp
File metadata and controls
133 lines (118 loc) · 4.41 KB
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "lua_timer_handle.h"
#include "uv_timer_handle.h"
#include "request.h"
#include "context_lua.h"
#include "network.h"
#define TIMER_METATABLE "class timer_handle_t"
int32_t lua_timer_handle_t::sleep(lua_State* L)
{
uint64_t timeout = 1000 * luaL_checknumber(L, 1);
context_lua_t* lctx = context_lua_t::lua_get_context(L);
request_t& request = lctx->get_yielding_request();
request.m_timer_start.m_timeout = timeout > 0 ? timeout : 1;
return lctx->lua_yield_send(L, 0, sleep_yield_finalize, NULL, sleep_yield_continue);
}
int32_t lua_timer_handle_t::sleep_yield_finalize(lua_State *root_coro, lua_State *main_coro, void *userdata, uint32_t destination)
{
if (root_coro != NULL) {
context_lua_t* lctx = context_lua_t::lua_get_context(root_coro);
request_t& request = lctx->get_yielding_request();
int32_t session = context_lua_t::lua_ref_yield_coroutine(root_coro);
context_lua_t::lua_ref_timer(root_coro, session, request.m_timer_start.m_timeout, 0, false);
}
return UV_OK;
}
int32_t lua_timer_handle_t::sleep_yield_continue(lua_State* L, int status, lua_KContext ctx)
{
return 0;
}
int32_t lua_timer_handle_t::timeout(lua_State* L)
{
int32_t top = lua_gettop(L);
uint64_t timeout = 1000 * luaL_checknumber(L, 1);
luaL_checktype(L, -1, LUA_TFUNCTION);
int32_t session = context_lua_t::lua_ref_callback(L, top - 2, LUA_REFNIL, timer_callback_adjust);
int32_t timer_ref = context_lua_t::lua_ref_timer(L, session, timeout > 0 ? timeout : 1, 0, true);
lua_pushinteger(L, timer_ref);
return 1;
}
int32_t lua_timer_handle_t::repeat(lua_State* L)
{
int32_t top = lua_gettop(L);
uint64_t interval = 1000 * luaL_checknumber(L, 1);
uint64_t repeat_time = 1000 * luaL_checknumber(L, 2);
luaL_checktype(L, -1, LUA_TFUNCTION);
if (interval != 0 || repeat_time != 0) {
int32_t session = context_lua_t::lua_ref_callback(L, top - 3, LUA_REFNIL, timer_callback_adjust);
int32_t timer_ref = context_lua_t::lua_ref_timer(L, session, interval, repeat_time, true);
lua_pushinteger(L, timer_ref);
return 1;
}
return 0;
}
int32_t lua_timer_handle_t::timer_callback_adjust(lua_State* L)
{
lua_pop(L, 4);
return 0;
}
lua_timer_handle_t* lua_timer_handle_t::create_timer(lua_State* L, int32_t session, uint64_t timeout, uint64_t repeat, bool is_cancel, void *userdata, timeout_callback_t callback)
{
lua_checkstack(L, 3);
uv_timer_handle_t* uv_timer = new uv_timer_handle_t(context_lua_t::lua_get_context_handle(L));
lua_timer_handle_t* lua_timer = new(lua_newuserdata(L, sizeof(lua_timer_handle_t)))lua_timer_handle_t(uv_timer, L, session, repeat > 0, is_cancel, userdata, callback);
if (luaL_newmetatable(L, TIMER_METATABLE)) { /* create new metatable */
lua_pushcfunction(L, lua_timer_handle_t::release);
lua_setfield(L, -2, "__gc");
}
lua_setmetatable(L, -2);
request_t request;
request.m_type = REQUEST_TIMER_START;
request.m_length = REQUEST_SIZE(request_timer_start_t, 0);
request.m_timer_start.m_timer_handle = uv_timer;
request.m_timer_start.m_timeout = timeout;
request.m_timer_start.m_repeat = repeat;
singleton_ref(network_t).send_request(request);
return lua_timer;
}
void lua_timer_handle_t::close()
{
m_session = LUA_REFNIL;
m_userdata = NULL;
m_callback = NULL;
_close();
}
int32_t lua_timer_handle_t::close(lua_State* L)
{
int32_t timer_ref = luaL_checkunsigned(L, 1);
lua_timer_handle_t* handle = (lua_timer_handle_t*)get_lua_handle(L, timer_ref, TIMER_SET);
if (handle && !handle->is_closed() && handle->is_cancel()) {
context_lua_t::lua_free_ref_session(L, handle->m_session);
}
return 0;
}
int32_t lua_timer_handle_t::wakeup(lua_State* L, message_t& message)
{
lua_timer_handle_t* handle = (lua_timer_handle_t*)get_lua_handle(L, message.m_session, TIMER_SET);
if (handle && !handle->is_closed() && handle->m_session != LUA_REFNIL) {
if (handle->m_callback) {
handle->m_callback(L, handle->m_session, handle->m_userdata, handle->is_repeat());
} else {
context_lua_t* lctx = context_lua_t::lua_get_context(L);
return lctx->wakeup_ref_session(handle->m_session, message, !handle->is_repeat());
}
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
int luaopen_timer(lua_State *L)
{
static const luaL_Reg l[] = {
{ "sleep", lua_timer_handle_t::sleep },
{ "timeout", lua_timer_handle_t::timeout },
{ "close", lua_timer_handle_t::close },
{ "loop", lua_timer_handle_t::repeat },
{ NULL, NULL },
};
luaL_newlib(L, l);
return 1;
}