diff options
-rw-r--r-- | plugins/MirLua/src/m_schedule.cpp | 563 | ||||
-rw-r--r-- | plugins/MirLua/src/m_schedule.h | 9 | ||||
-rw-r--r-- | plugins/MirLua/src/mlua.cpp | 10 | ||||
-rw-r--r-- | plugins/MirLua/src/mlua_metatable.h | 3 | ||||
-rw-r--r-- | plugins/MirLua/src/mlua_module_loader.cpp | 1 | ||||
-rw-r--r-- | plugins/MirLua/src/stdafx.h | 7 |
6 files changed, 580 insertions, 13 deletions
diff --git a/plugins/MirLua/src/m_schedule.cpp b/plugins/MirLua/src/m_schedule.cpp new file mode 100644 index 0000000000..8d2330f626 --- /dev/null +++ b/plugins/MirLua/src/m_schedule.cpp @@ -0,0 +1,563 @@ +#include "stdafx.h"
+
+static mir_cs threadLock;
+static HANDLE hScheduleEvent = NULL;
+static HANDLE hScheduleThread = NULL;
+
+struct ScheduleTask
+{
+ time_t startTime;
+ time_t endTime;
+ time_t interval;
+
+ lua_State *L;
+ lua_State *T;
+ int threadRef;
+ int callbackRef;
+};
+
+static int TaskCompare(const ScheduleTask *p1, const ScheduleTask *p2)
+{
+ return p1->startTime - p2->startTime;
+}
+
+static LIST<ScheduleTask> tasks(1, TaskCompare);
+
+void DestroyScheduleTask(ScheduleTask *task)
+{
+ luaL_unref(task->L, LUA_REGISTRYINDEX, task->threadRef);
+ delete task;
+}
+
+void ScheduleThread(void*)
+{
+ time_t waitTime = INFINITE;
+
+ while (true)
+ {
+wait: WaitForSingleObject(hScheduleEvent, waitTime);
+
+ while (ScheduleTask *task = tasks[0])
+ {
+ mir_cslock lock(threadLock);
+
+ time_t timestamp = time(NULL);
+ if (task->startTime > timestamp)
+ {
+ waitTime = (task->startTime - timestamp - 1) * 1000;
+ goto wait;
+ }
+
+ tasks.remove(task);
+
+ if (task->endTime > 0 && task->endTime < timestamp)
+ {
+ DestroyScheduleTask(task);
+ continue;
+ }
+
+ lua_rawgeti(task->T, LUA_REGISTRYINDEX, task->callbackRef);
+ if (lua_pcall(task->T, 0, 2, 0))
+ CallService(MS_NETLIB_LOG, (WPARAM)hNetlib, (LPARAM)lua_tostring(task->T, -1));
+
+ if (task->interval == 0)
+ {
+ DestroyScheduleTask(task);
+ continue;
+ }
+
+ task->startTime += task->interval;
+ tasks.insert(task);
+ }
+
+ waitTime = INFINITE;
+ }
+}
+
+void KillModuleScheduleTasks()
+{
+ mir_cslock lock(threadLock);
+
+ while (ScheduleTask *task = tasks[0])
+ {
+ tasks.remove(task);
+ DestroyScheduleTask(task);
+ }
+}
+
+/***********************************************/
+
+enum DayOfWeek
+{
+ None = -1,
+ Sunday = 0,
+ Monday = 1,
+ Tuesday = 2,
+ Wednesday = 3,
+ Thursday = 4,
+ Friday = 5,
+ Saturday = 6
+};
+
+static int lua__Second(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 1);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, time(NULL));
+ lua_setfield(L, -2, "Timestamp");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Seconds(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, -2);
+ int seconds = luaL_optinteger(L, -1, 1);
+ lua_pop(L, 1);
+ lua_pushinteger(L, seconds);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Minute(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Minutes(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, -2);
+ int interval = luaL_optinteger(L, -1, 1);
+ lua_pop(L, 1);
+ lua_pushinteger(L, interval * 60);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Hour(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Hours(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, -2);
+ int interval = luaL_optinteger(L, -1, 1);
+ lua_pop(L, 1);
+ lua_pushinteger(L, interval * 60 * 60);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Day(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Days(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, -2);
+ int interval = luaL_optinteger(L, -1, 1);
+ lua_pop(L, 1);
+ lua_pushinteger(L, interval * 60 * 60 * 24);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Week(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Weeks(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, -2);
+ int interval = luaL_optinteger(L, -1, 1);
+ lua_pop(L, 1);
+ lua_pushinteger(L, interval * 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, DayOfWeek::None);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Monday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Monday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Tuesday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Tuesday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Wednesday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Wednesday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Thursday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Thursday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Friday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Friday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Saturday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Saturday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__Sunday(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ lua_pushinteger(L, 60 * 60 * 24 * 7);
+ lua_setfield(L, -2, "Interval");
+ lua_pushinteger(L, Sunday);
+ lua_setfield(L, -2, "DayOfWeek");
+
+ return 1;
+}
+
+static int lua__From(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ time_t startTime, timestamp = time(NULL);
+ switch (lua_type(L, 2))
+ {
+ case LUA_TNUMBER:
+ startTime = luaL_optinteger(L, 2, timestamp);
+ break;
+
+ case LUA_TSTRING:
+ {
+ const char *strtime = luaL_optstring(L, 2, "00:00:00");
+
+ int hour = 0, min = 0, sec = 0;
+ sscanf_s(strtime, "%02d:%02d:%02d", &hour, &min, &sec);
+ struct tm *ti = localtime(×tamp);
+ ti->tm_hour = hour;
+ ti->tm_min = min;
+ ti->tm_sec = sec;
+ startTime = mktime(ti);
+ break;
+ }
+
+ default:
+ startTime = timestamp;
+ break;
+ }
+
+ if (startTime < timestamp)
+ {
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, 1);
+ int interval = luaL_optinteger(L, -1, 1);
+ lua_pop(L, 1);
+ startTime += (((timestamp - startTime) / interval) + 1) * interval;
+ }
+
+ lua_pushvalue(L, 1);
+ lua_pushinteger(L, startTime);
+ lua_setfield(L, -2, "StartTime");
+
+ return 1;
+}
+
+static int lua__Untill(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ time_t endTime = 0;
+ switch (lua_type(L, 2))
+ {
+ case LUA_TNUMBER:
+ endTime = luaL_optinteger(L, 2, 0);
+ break;
+
+ case LUA_TSTRING:
+ {
+ const char *strtime = luaL_optstring(L, 2, "00:00:00");
+
+ int hour = 0, min = 0, sec = 0;
+ sscanf_s(strtime, "%02d:%02d:%02d", &hour, &min, &sec);
+ time_t timestamp = time(NULL);
+ struct tm *ti = localtime(×tamp);
+ ti->tm_hour = hour;
+ ti->tm_min = min;
+ ti->tm_sec = sec;
+ endTime = mktime(ti);
+ break;
+ }
+ }
+
+ lua_pushvalue(L, 1);
+ lua_pushinteger(L, endTime);
+ lua_setfield(L, -2, "EndTime");
+
+ return 1;
+}
+
+static int lua__Do(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+
+ lua_pushliteral(L, "Interval");
+ lua_gettable(L, 1);
+ int interval = luaL_optinteger(L, -1, 0);
+ lua_pop(L, 1);
+
+ time_t timestamp = time(NULL);
+
+ lua_pushliteral(L, "StartTime");
+ lua_gettable(L, 1);
+ time_t startTime = luaL_optinteger(L, -1, timestamp);
+ lua_pop(L, 1);
+
+ if (startTime < timestamp && interval == 0)
+ return 0;
+
+ lua_pushliteral(L, "DayOfWeek");
+ lua_gettable(L, 1);
+ DayOfWeek dayOfWeek = (DayOfWeek)luaL_optinteger(L, -1, DayOfWeek::None);
+ lua_pop(L, 1);
+
+ if (dayOfWeek > DayOfWeek::None && dayOfWeek <= DayOfWeek::Saturday)
+ {
+ struct tm *ti = localtime(&startTime);
+ ti->tm_mday += abs((int)dayOfWeek - ti->tm_wday);
+ startTime = mktime(ti);
+ }
+
+ lua_pushliteral(L, "EndTime");
+ lua_gettable(L, 1);
+ time_t endTime = luaL_optinteger(L, -1, 0);
+ lua_pop(L, 1);
+
+ if (endTime > 0 && endTime < timestamp)
+ return 0;
+
+ ScheduleTask *task = new ScheduleTask();
+ task->startTime = startTime;
+ task->endTime = endTime;
+ task->interval = interval;
+ task->L = L;
+ lua_pushvalue(L, 2);
+ task->callbackRef = luaL_ref(L, LUA_REGISTRYINDEX);
+ task->T = lua_newthread(L);
+ task->threadRef = luaL_ref(L, LUA_REGISTRYINDEX);
+ {
+ mir_cslock lock(threadLock);
+ tasks.insert(task);
+ }
+ SetEvent(hScheduleEvent);
+
+ return 0;
+}
+
+static const luaL_Reg schedule[] =
+{
+ { "Second", lua__Second },
+ { "Seconds", lua__Seconds },
+ { "Minute", lua__Minute },
+ { "Minutes", lua__Minutes },
+ { "Hour", lua__Hour },
+ { "Hours", lua__Hours },
+ { "Day", lua__Day },
+ { "Days", lua__Days },
+ { "Week", lua__Week },
+ { "Weeks", lua__Weeks },
+ { "Monday", lua__Week },
+ { "Tuesday", lua__Tuesday },
+ { "Wednesday", lua__Wednesday },
+ { "Thursday", lua__Thursday },
+ { "Friday", lua__Friday },
+ { "Saturday", lua__Saturday },
+ { "Sunday", lua__Sunday },
+ { "From", lua__From },
+ { "Untill", lua__Untill },
+ { "Do", lua__Do },
+
+ { NULL, NULL }
+};
+
+/***********************************************/
+
+static int lua__At(lua_State *L)
+{
+ time_t startTime, timestamp = time(NULL);
+ switch (lua_type(L, 1))
+ {
+ case LUA_TNUMBER:
+ startTime = luaL_optinteger(L, 1, timestamp);
+ break;
+
+ case LUA_TSTRING:
+ {
+ const char *strtime = luaL_optstring(L, 1, "00:00:00");
+
+ int hour = 0, min = 0, sec = 0;
+ sscanf_s(strtime, "%02d:%02d:%02d", &hour, &min, &sec);
+ struct tm *ti = localtime(×tamp);
+ ti->tm_hour = hour;
+ ti->tm_min = min;
+ ti->tm_sec = sec;
+ startTime = mktime(ti);
+ break;
+ }
+
+ default:
+ startTime = timestamp;
+ break;
+ }
+
+ lua_newtable(L);
+ lua_pushcclosure(L, lua__Untill, 0);
+ lua_setfield(L, -2, "Untill");
+ lua_pushcclosure(L, lua__Do, 0);
+ lua_setfield(L, -2, "Do");
+ lua_pushinteger(L, startTime);
+ lua_setfield(L, -2, "StartTime");
+
+ return 1;
+}
+
+static int lua__Every(lua_State *L)
+{
+ int interval = luaL_optinteger(L, 1, 0);
+
+ luaL_newlib(L, schedule);
+ lua_pushinteger(L, interval);
+ lua_setfield(L, -2, "Interval");
+
+ return 1;
+}
+
+static const luaL_Reg scheduleApi[] =
+{
+ { "At", lua__At },
+ { "Every", lua__Every },
+
+ { NULL, NULL }
+};
+
+LUAMOD_API int luaopen_m_schedule(lua_State *L)
+{
+ luaL_newlib(L, scheduleApi);
+
+ if (hScheduleEvent == NULL)
+ hScheduleEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ if (hScheduleThread == NULL)
+ hScheduleThread = mir_forkthread(ScheduleThread);
+
+ return 1;
+}
diff --git a/plugins/MirLua/src/m_schedule.h b/plugins/MirLua/src/m_schedule.h new file mode 100644 index 0000000000..48874dd126 --- /dev/null +++ b/plugins/MirLua/src/m_schedule.h @@ -0,0 +1,9 @@ +#ifndef _LUA_M_SCHEDULE_H_
+#define _LUA_M_SCHEDULE_H_
+
+#define MLUA_SCHEDULE "m_schedule"
+LUAMOD_API int (luaopen_m_schedule)(lua_State *L);
+
+void KillModuleScheduleTasks();
+
+#endif //_LUA_M_SCHEDULE_H_
\ No newline at end of file diff --git a/plugins/MirLua/src/mlua.cpp b/plugins/MirLua/src/mlua.cpp index 5a17246a5f..de7690356e 100644 --- a/plugins/MirLua/src/mlua.cpp +++ b/plugins/MirLua/src/mlua.cpp @@ -1,8 +1,5 @@ #include "stdafx.h"
-//LIST<void> CMLua::Hooks(1, PtrKeySortT);
-//LIST<void> CMLua::Events(1, PtrKeySortT);
-//LIST<void> CMLua::Services(1, PtrKeySortT);
LIST<void> CMLua::HookRefs(1, HandleKeySortT);
LIST<void> CMLua::ServiceRefs(1, HandleKeySortT);
@@ -65,6 +62,7 @@ void CMLua::Unload() delete script;
}
+ ::KillModuleScheduleTasks();
::KillModuleMBButtons();
::KillModuleTTBButton();
@@ -73,12 +71,8 @@ void CMLua::Unload() ::KillModuleHotkeys(hScriptsLangpack);
::KillObjectEventHooks(L);
::KillObjectServices(L);
- //KillModuleSubclassing
- //CMLua::KillLuaRefs();
-
- if (L)
- lua_close(L);
+ lua_close(L);
}
void CMLua::KillLuaRefs()
diff --git a/plugins/MirLua/src/mlua_metatable.h b/plugins/MirLua/src/mlua_metatable.h index b0d31cf707..f2143d5f27 100644 --- a/plugins/MirLua/src/mlua_metatable.h +++ b/plugins/MirLua/src/mlua_metatable.h @@ -1,9 +1,6 @@ #ifndef _LUA_METATABLE_H_
#define _LUA_METATABLE_H_
-#include <map>
-#include <string>
-
#define LUA_TINTEGER LUA_NUMTAGS + 1
#define LUA_TSTRINGA LUA_NUMTAGS + 2
#define LUA_TSTRINGW LUA_NUMTAGS + 3
diff --git a/plugins/MirLua/src/mlua_module_loader.cpp b/plugins/MirLua/src/mlua_module_loader.cpp index a236a76691..a40f24b7ab 100644 --- a/plugins/MirLua/src/mlua_module_loader.cpp +++ b/plugins/MirLua/src/mlua_module_loader.cpp @@ -16,6 +16,7 @@ void CLuaModuleLoader::LoadModules() {
// regirter delay loading of miranda modules
PreloadModule(MLUA_CORE, luaopen_m_core);
+ PreloadModule(MLUA_SCHEDULE, luaopen_m_schedule);
PreloadModule(MLUA_CLIST, luaopen_m_clist);
PreloadModule(MLUA_DATABASE, luaopen_m_database);
PreloadModule(MLUA_ICOLIB, luaopen_m_icolib);
diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h index 0929db0d56..1c1677a2bd 100644 --- a/plugins/MirLua/src/stdafx.h +++ b/plugins/MirLua/src/stdafx.h @@ -6,6 +6,9 @@ #include <malloc.h>
#include <time.h>
+#include <map>
+#include <string>
+
#include <newpluginapi.h>
#include <m_core.h>
#include <m_utils.h>
@@ -69,6 +72,8 @@ extern HANDLE hNetlib; #define MLUA_CORE "m_core"
LUAMOD_API int (luaopen_m_core)(lua_State *L);
+#include "m_schedule.h"
+
#define MLUA_CLIST "m_clist"
LUAMOD_API int (luaopen_m_clist)(lua_State *L);
@@ -121,6 +126,4 @@ void ShowNotification(const char *caption, const char *message, int flags, MCONT void ObsoleteMethod(lua_State *L, const char *message);
-#include <typeinfo>
-
#endif //_COMMON_H_
|