-- 定时器 local skynet = require "skynet" local struct = require "struct" local ostime = os.time local osdate = os.date local currtime = function() return math.floor(skynet.time()) end local debug = IS_TEST -- 时间事件类型 local TIME_OF_INTER = 0 -- 每隔多久 local TIME_OF_DAY = 1 -- 每天 local TIME_OF_WEEK = 2 -- 每周 local TIME_OF_MONTH = 3 -- 每月 local TIME_OF_SPECIFIC = 4 -- 特定时间 local TIME_OF_HOUR = 5 -- 整数点 local INVALID_NUMBER = -1 -- 无效数字 -- 时间类的定义 local timeClass = struct() function timeClass:ctor() self.year = INVALID_NUMBER -- 年 self.month = INVALID_NUMBER -- 月 self.day = INVALID_NUMBER -- 日 self.hour = INVALID_NUMBER -- 小时 self.min = INVALID_NUMBER -- 分钟 self.sec = INVALID_NUMBER -- 秒 end -- 定时时间事件类的定义 local timeEventClass = struct() function timeEventClass:ctor() self.timerType = INVALID_NUMBER -- 时间事件类型 self.timeOut = INVALID_NUMBER -- 间隔时间 self.func = nil -- 函数指针 self.doTime = 0 -- 执行时间 end -- 定点时间事件类的定义 local timePointClass = struct() function timePointClass:ctor() self.timerType = INVALID_NUMBER -- 时间事件类型 self.func = nil -- 函数指针 self.doTime = 0 -- 执行时间 self.time = timeClass.new() -- 定时时间 end -- 帧事件 local frameClass = struct() function frameClass:ctor(interval, func) self.interval = interval -- 时长 self.func = func -- 函数指针 end -- 计算下一次执行的时间 local function doNextTime(timeEventObj) if timeEventObj.timerType == TIME_OF_INTER then -- 间隔时间 timeEventObj.doTime = timeEventObj.doTime + timeEventObj.timeOut elseif timeEventObj.timerType == TIME_OF_DAY then -- 每天 timeEventObj.time.day = timeEventObj.time.day + 1 timeEventObj.doTime = ostime(timeEventObj.time) elseif timeEventObj.timerType == TIME_OF_WEEK then -- 每周 timeEventObj.time.day = timeEventObj.time.day + 7 timeEventObj.doTime = ostime(timeEventObj.time) elseif timeEventObj.timerType == TIME_OF_MONTH then -- 每月 timeEventObj.time.month = timeEventObj.time.month + 1 timeEventObj.doTime = ostime(timeEventObj.time) elseif timeEventObj.timerType == TIME_OF_SPECIFIC then -- 特定时间 timeEventObj.doTime = INVALID_NUMBER elseif timeEventObj.timerType == TIME_OF_HOUR then -- 整数点 timeEventObj.time.hour = timeEventObj.time.hour + 1 timeEventObj.doTime = ostime(timeEventObj.time) end end --------------------------------------------------------------------------------------- local working local root = {} local timeList = {} -- 时间事件列表 local function doWork() local nowTime = currtime() local delList = {} for index, timeEventObj in ipairs(timeList) do if timeEventObj.doTime == INVALID_NUMBER or (not timeEventObj.func) then table.insert(delList, index) goto continue end if timeEventObj.doTime > nowTime then goto continue end if debug then timeEventObj.func() else local isok, mag_error = pcall( function() return timeEventObj.func() end ) if not isok then log.error(mag_error) end end doNextTime(timeEventObj) -- print(" 下一次执行的时间 ", osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime)) ::continue:: end for i = #delList, 1, -1 do table.remove(timeList, delList[i]) end working = nil if #timeList > 0 then working = true skynet.timeout( 100, function() doWork() end ) end end -- 每隔多久(单位是秒) function root.timeOut(timeCount, func) local timeEventObj = timeEventClass.new() timeEventObj.timerType = TIME_OF_INTER timeEventObj.timeOut = timeCount -- 间隔时间 timeEventObj.func = func -- 函数指针 timeEventObj.doTime = currtime() + timeCount -- 执行时间 -- print("每隔多久 ----- " ,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime)) table.insert(timeList, timeEventObj) if not working then doWork() end return timeEventObj end -- 每天 (格式 ) function root.timeOfDay(hour, min, sec, func) local timeEventObj = timePointClass.new() timeEventObj.timerType = TIME_OF_DAY -- 时间事件类型 timeEventObj.func = func -- 函数指针 -- 计算第一次开始的时间 local nowTime = osdate("*t") timeEventObj.time.year = nowTime.year timeEventObj.time.month = nowTime.month timeEventObj.time.day = nowTime.day timeEventObj.time.hour = hour timeEventObj.time.min = min timeEventObj.time.sec = sec if ostime(nowTime) >= ostime(timeEventObj.time) then -- timeEventObj.time.day = timeEventObj.time.day + 1 end timeEventObj.doTime = ostime(timeEventObj.time) -- print("每天 ----- " ,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime)) table.insert(timeList, timeEventObj) if not working then doWork() end return timeEventObj end -- 每周 (1表示周日) function root.timeOfWeek(wday, hour, min, sec, func) local timeEventObj = timePointClass.new() timeEventObj.timerType = TIME_OF_WEEK -- 时间事件类型 timeEventObj.func = func -- 函数指针 -- 计算第一次开始的时间 local nowTime = osdate("*t") timeEventObj.time.year = nowTime.year timeEventObj.time.month = nowTime.month timeEventObj.time.hour = hour timeEventObj.time.min = min timeEventObj.time.sec = sec if nowTime.wday > wday then timeEventObj.time.day = nowTime.day + (5 + nowTime.wday - wday) elseif nowTime.wday == wday then timeEventObj.time.day = nowTime.day if ostime(nowTime) > ostime(timeEventObj.time) then timeEventObj.time.day = timeEventObj.time.day + 7 end else timeEventObj.time.day = nowTime.day + (wday - nowTime.wday) end timeEventObj.doTime = ostime(timeEventObj.time) ---- 执行时间 -- print("每周 ----- " , wday,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime)) table.insert(timeList, timeEventObj) if not working then doWork() end return timeEventObj end -- 每月 function root.timeOfMonth(day, hour, min, sec, func) local timeEventObj = timePointClass.new() timeEventObj.timerType = TIME_OF_MONTH -- 时间事件类型 timeEventObj.func = func -- 函数指针 -- 计算第一次开始的时间 local nowTime = osdate("*t") timeEventObj.time.year = nowTime.year timeEventObj.time.month = nowTime.month timeEventObj.time.day = day timeEventObj.time.hour = hour timeEventObj.time.min = min timeEventObj.time.sec = sec if ostime(nowTime) >= ostime(timeEventObj.time) then -- timeEventObj.time.month = timeEventObj.time.month + 1 end timeEventObj.doTime = ostime(timeEventObj.time) -- 执行时间 -- print("每月 ----- " ,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime)) table.insert(timeList, timeEventObj) if not working then doWork() end return timeEventObj end -- 特定时间 function root.specificTime(year, month, day, hour, min, sec, func) local timeEventObj = timePointClass.new() timeEventObj.timerType = TIME_OF_SPECIFIC -- 时间事件类型 timeEventObj.func = func -- 函数指针 -- 计算第一次开始的时间 timeEventObj.time.year = year timeEventObj.time.month = month timeEventObj.time.day = day timeEventObj.time.hour = hour timeEventObj.time.min = min timeEventObj.time.sec = sec local nowTime = currtime() local workTime = ostime(timeEventObj.time) if nowTime >= workTime then timeEventObj.doTime = INVALID_NUMBER else timeEventObj.doTime = workTime end -- print("特定时间 ----- ", osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime)) table.insert(timeList, timeEventObj) if not working then doWork() end return timeEventObj end -- 整点时间 function root.hourOfTime(func) local timeEventObj = timePointClass.new() timeEventObj.timerType = TIME_OF_HOUR -- 时间事件类型 timeEventObj.func = func -- 函数指针 local nowTime = osdate("*t") timeEventObj.time.year = nowTime.year timeEventObj.time.month = nowTime.month timeEventObj.time.day = nowTime.day timeEventObj.time.hour = nowTime.hour timeEventObj.time.min = 0 timeEventObj.time.sec = 0 if ostime(nowTime) >= ostime(timeEventObj.time) then -- timeEventObj.time.hour = timeEventObj.time.hour + 1 end timeEventObj.doTime = ostime(timeEventObj.time) -- 执行时间 table.insert(timeList, timeEventObj) if not working then doWork() end return timeEventObj end return root