From 4eaa06c31f91c9a5de85d0745cf9f11908cebea9 Mon Sep 17 00:00:00 2001 From: aunsane Date: Tue, 24 Oct 2017 23:21:27 +0300 Subject: MirLua: add method wait into m_schedule --- plugins/MirLua/Modules/m_schedule/src/main.cpp | 284 +++++++++++++------------ 1 file changed, 148 insertions(+), 136 deletions(-) (limited to 'plugins/MirLua/Modules') diff --git a/plugins/MirLua/Modules/m_schedule/src/main.cpp b/plugins/MirLua/Modules/m_schedule/src/main.cpp index 5a18702f5d..093a95ca94 100644 --- a/plugins/MirLua/Modules/m_schedule/src/main.cpp +++ b/plugins/MirLua/Modules/m_schedule/src/main.cpp @@ -16,18 +16,28 @@ struct ScheduleTask { time_t timestamp; time_t interval; + bool repeat; lua_State *L; int threadRef; int callbackRef; -}; -static int TaskCompare(const ScheduleTask *p1, const ScheduleTask *p2) -{ - return p1->timestamp - p2->timestamp; -} + ScheduleTask() + { + timestamp = time(NULL); + interval = 0; + repeat = false; + } + + void Append(time_t value) + { + if (repeat) + interval = value; + timestamp += value; + } +}; -static LIST tasks(1, TaskCompare); +static LIST tasks(1, HandleKeySortT); void DestroyTask(ScheduleTask *task) { @@ -44,7 +54,6 @@ void ExecuteTaskThread(void *arg) lua_pcall(task->L, 0, 1, 0); void *res = lua_touserdata(task->L, -1); - if (res == STOP || task->interval == 0) { DestroyTask(task); @@ -54,13 +63,14 @@ void ExecuteTaskThread(void *arg) { mir_cslock lock(threadLock); - time_t timestamp = time(NULL); - if(task->timestamp + task->interval >= timestamp) + time_t now = time(NULL); + if (task->timestamp + task->interval >= now) task->timestamp += task->interval; else - task->timestamp = timestamp + task->interval; + task->timestamp += (((now - task->timestamp) / task->interval) + 1) * task->interval; tasks.insert(task); } + SetEvent(hScheduleEvent); } @@ -77,16 +87,17 @@ wait: WaitForSingleObject(hScheduleEvent, waitTime); if (Miranda_IsTerminated()) return; - mir_cslock lock(threadLock); - - time_t timestamp = time(NULL); - if (task->timestamp > timestamp) + time_t now = time(NULL); + if (task->timestamp > now) { - waitTime = (task->timestamp - timestamp - 1) * 1000; + waitTime = (task->timestamp - now) * 1000; goto wait; } - tasks.remove(task); + { + mir_cslock lock(threadLock); + tasks.remove(task); + } mir_forkthread(ExecuteTaskThread, task); } @@ -133,6 +144,19 @@ static time_t luaM_opttimestamp(lua_State *L, int idx, time_t def = 0) return def; } +static void luaM_change__index(lua_State *L, const luaL_Reg *funcs) +{ + int idx = lua_gettop(L); + if (lua_getmetatable(L, idx)) + { + lua_newtable(L); + lua_pushvalue(L, idx); + luaL_setfuncs(L, funcs, 1); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + } +} + /***********************************************/ static int fluent_Do(lua_State *L) @@ -160,40 +184,34 @@ static int fluent_Do(lua_State *L) mir_cslock lock(threadLock); tasks.insert(task); } + SetEvent(hScheduleEvent); return 0; } -static int fluent_At(lua_State *L) +static int fluent_From(lua_State *L) { + luaL_checktype(L, 1, LUA_TSTRING); + ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); task->timestamp = luaM_opttimestamp(L, 1, 0); - time_t now = time(NULL); - if (task->timestamp < now) + const luaL_Reg funcs[] = { - lua_getfield(L, -1, "Interval"); - int interval = luaL_optinteger(L, -1, 0); - lua_pop(L, 1); - if (task->interval > 0) - task->timestamp += (((now - task->timestamp) / task->interval) + 1) * task->interval; - } + { "Do", fluent_Do }, + { NULL, NULL } + }; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - lua_pushcclosure(L, fluent_Do, 1); - lua_setfield(L, -2, "Do"); - lua_setmetatable(L, -2); + luaM_change__index(L, funcs); return 1; } -static const luaL_Reg scheduleEvery3Api[] = +static const luaL_Reg fluentApi[] = { - { "At", fluent_At }, + { "From", fluent_From }, { "Do", fluent_Do }, { NULL, NULL } @@ -202,14 +220,10 @@ static const luaL_Reg scheduleEvery3Api[] = static int fluent_Second(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = SECOND; + task->Append(SECOND); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -217,14 +231,12 @@ static int fluent_Second(lua_State *L) static int fluent_Seconds(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * SECOND; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); + time_t interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * SECOND; + task->Append(interval); + lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -232,14 +244,10 @@ static int fluent_Seconds(lua_State *L) static int fluent_Minute(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = MINUTE; + task->Append(MINUTE); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -247,14 +255,11 @@ static int fluent_Minute(lua_State *L) static int fluent_Minutes(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * MINUTE; + time_t interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * MINUTE; + task->Append(interval); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -262,14 +267,10 @@ static int fluent_Minutes(lua_State *L) static int fluent_Hour(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = HOUR; + task->Append(HOUR); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -277,14 +278,11 @@ static int fluent_Hour(lua_State *L) static int fluent_Hours(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * HOUR; + time_t interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * HOUR; + task->Append(interval); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -292,14 +290,10 @@ static int fluent_Hours(lua_State *L) static int fluent_Day(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = DAY; + task->Append(DAY); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -307,14 +301,11 @@ static int fluent_Day(lua_State *L) static int fluent_Days(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * DAY; + time_t interval = luaL_optinteger(L, lua_upvalueindex(2), 1) * DAY; + task->Append(interval); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -322,14 +313,10 @@ static int fluent_Days(lua_State *L) static int fluent_Week(lua_State *L) { ScheduleTask *task = *(ScheduleTask**)lua_touserdata(L, lua_upvalueindex(1)); - task->interval = WEEK; + task->Append(WEEK); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -344,12 +331,8 @@ static int fluent_Monday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -364,12 +347,8 @@ static int fluent_Tuesday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -384,12 +363,8 @@ static int fluent_Wednesday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -404,12 +379,8 @@ static int fluent_Thursday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -424,12 +395,8 @@ static int fluent_Friday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -444,12 +411,8 @@ static int fluent_Saturday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); - lua_setmetatable(L, -2); + luaM_change__index(L, fluentApi); return 1; } @@ -464,16 +427,39 @@ static int fluent_Sunday(lua_State *L) task->timestamp = mktime(ti); task->interval = WEEK; + lua_pushvalue(L, lua_upvalueindex(1)); + luaM_change__index(L, fluentApi); + + return 1; +} + +/***********************************************/ + +static const luaL_Reg scheduleAtApi[] = +{ + { "Do", fluent_Do }, + + { NULL, NULL } +}; + +static int schedule_At(lua_State *L) +{ + ScheduleTask **task = (ScheduleTask**)lua_newuserdata(L, sizeof(ScheduleTask)); + *task = new ScheduleTask(); + (*task)->timestamp = luaM_opttimestamp(L, 1, time(NULL)); + lua_newtable(L); - lua_pushvalue(L, -1); + lua_newtable(L); + lua_pushvalue(L, -3); + luaL_setfuncs(L, scheduleAtApi, 1); lua_setfield(L, -2, "__index"); - lua_pushvalue(L, lua_upvalueindex(1)); - luaL_setfuncs(L, scheduleEvery3Api, 1); lua_setmetatable(L, -2); return 1; } +/***********************************************/ + static const luaL_Reg scheduleEvery1Api[] = { { "Second", fluent_Second }, @@ -502,39 +488,63 @@ static const luaL_Reg scheduleEvery2Api[] = { NULL, NULL } }; -/***********************************************/ - -static int schedule_At(lua_State *L) +static int schedule_Every(lua_State *L) { - ScheduleTask **task = (ScheduleTask**)lua_newuserdata(L, sizeof(ScheduleTask)); + int count = luaL_optinteger(L, 1, 0); + + ScheduleTask **task = (ScheduleTask**)lua_newuserdata(L, sizeof(ScheduleTask*)); *task = new ScheduleTask(); - (*task)->timestamp = luaM_opttimestamp(L, 1, time(NULL)); - (*task)->interval = 0; + (*task)->repeat = true; lua_newtable(L); - lua_pushvalue(L, -1); + lua_newtable(L); + lua_pushvalue(L, -3); + if (count) + { + lua_pushinteger(L, count); + luaL_setfuncs(L, scheduleEvery2Api, 2); + } + else + luaL_setfuncs(L, scheduleEvery1Api, 1); lua_setfield(L, -2, "__index"); - lua_pushvalue(L, -2); - lua_pushcclosure(L, fluent_Do, 1); - lua_setfield(L, -2, "Do"); lua_setmetatable(L, -2); return 1; } -static int schedule_Every(lua_State *L) +/***********************************************/ + +static const luaL_Reg scheduleWait1Api[] = +{ + { "Second", fluent_Second }, + { "Minute", fluent_Minute }, + { "Hour", fluent_Hour }, + { "Day", fluent_Day }, + { "Week", fluent_Week }, + + { NULL, NULL } +}; + +static const luaL_Reg scheduleWait2Api[] = +{ + { "Seconds", fluent_Seconds }, + { "Minutes", fluent_Minutes }, + { "Hours", fluent_Hours }, + { "Days", fluent_Days }, + + { NULL, NULL } +}; + +static int schedule_Wait(lua_State *L) { int count = luaL_optinteger(L, 1, 0); ScheduleTask **task = (ScheduleTask**)lua_newuserdata(L, sizeof(ScheduleTask*)); *task = new ScheduleTask(); - (*task)->timestamp = 0; - (*task)->interval = 0; lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_pushvalue(L, -2); + lua_newtable(L); + lua_pushvalue(L, -3); if (count) { lua_pushinteger(L, count); @@ -542,6 +552,7 @@ static int schedule_Every(lua_State *L) } else luaL_setfuncs(L, scheduleEvery1Api, 1); + lua_setfield(L, -2, "__index"); lua_setmetatable(L, -2); return 1; @@ -551,6 +562,7 @@ static const luaL_Reg scheduleApi[] = { { "At", schedule_At }, { "Every", schedule_Every }, + { "Wait", schedule_Wait }, { "STOP", NULL }, -- cgit v1.2.3