summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/MirLua/Modules/m_schedule/src/main.cpp284
-rw-r--r--plugins/MirLua/src/m_core.cpp2
2 files changed, 150 insertions, 136 deletions
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<ScheduleTask> tasks(1, TaskCompare);
+static LIST<ScheduleTask> 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 },
diff --git a/plugins/MirLua/src/m_core.cpp b/plugins/MirLua/src/m_core.cpp
index 07c409a710..bf3b5233cf 100644
--- a/plugins/MirLua/src/m_core.cpp
+++ b/plugins/MirLua/src/m_core.cpp
@@ -342,6 +342,8 @@ void __cdecl ThreadFunc(void *p)
static int core_ForkThread(lua_State *L)
{
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+
core_ForkThreadParam *p = new core_ForkThreadParam();
p->L = lua_newthread(L);