timer.lua 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. -- 定时器
  2. local skynet = require "skynet"
  3. local struct = require "struct"
  4. local ostime = os.time
  5. local osdate = os.date
  6. local currtime = function()
  7. return math.floor(skynet.time())
  8. end
  9. local debug = IS_TEST
  10. -- 时间事件类型
  11. local TIME_OF_INTER = 0 -- 每隔多久
  12. local TIME_OF_DAY = 1 -- 每天
  13. local TIME_OF_WEEK = 2 -- 每周
  14. local TIME_OF_MONTH = 3 -- 每月
  15. local TIME_OF_SPECIFIC = 4 -- 特定时间
  16. local TIME_OF_HOUR = 5 -- 整数点
  17. local INVALID_NUMBER = -1 -- 无效数字
  18. -- 时间类的定义
  19. local timeClass = struct()
  20. function timeClass:ctor()
  21. self.year = INVALID_NUMBER -- 年
  22. self.month = INVALID_NUMBER -- 月
  23. self.day = INVALID_NUMBER -- 日
  24. self.hour = INVALID_NUMBER -- 小时
  25. self.min = INVALID_NUMBER -- 分钟
  26. self.sec = INVALID_NUMBER -- 秒
  27. end
  28. -- 定时时间事件类的定义
  29. local timeEventClass = struct()
  30. function timeEventClass:ctor()
  31. self.timerType = INVALID_NUMBER -- 时间事件类型
  32. self.timeOut = INVALID_NUMBER -- 间隔时间
  33. self.func = nil -- 函数指针
  34. self.doTime = 0 -- 执行时间
  35. end
  36. -- 定点时间事件类的定义
  37. local timePointClass = struct()
  38. function timePointClass:ctor()
  39. self.timerType = INVALID_NUMBER -- 时间事件类型
  40. self.func = nil -- 函数指针
  41. self.doTime = 0 -- 执行时间
  42. self.time = timeClass.new() -- 定时时间
  43. end
  44. -- 帧事件
  45. local frameClass = struct()
  46. function frameClass:ctor(interval, func)
  47. self.interval = interval -- 时长
  48. self.func = func -- 函数指针
  49. end
  50. -- 计算下一次执行的时间
  51. local function doNextTime(timeEventObj)
  52. if timeEventObj.timerType == TIME_OF_INTER then -- 间隔时间
  53. timeEventObj.doTime = timeEventObj.doTime + timeEventObj.timeOut
  54. elseif timeEventObj.timerType == TIME_OF_DAY then -- 每天
  55. timeEventObj.time.day = timeEventObj.time.day + 1
  56. timeEventObj.doTime = ostime(timeEventObj.time)
  57. elseif timeEventObj.timerType == TIME_OF_WEEK then -- 每周
  58. timeEventObj.time.day = timeEventObj.time.day + 7
  59. timeEventObj.doTime = ostime(timeEventObj.time)
  60. elseif timeEventObj.timerType == TIME_OF_MONTH then -- 每月
  61. timeEventObj.time.month = timeEventObj.time.month + 1
  62. timeEventObj.doTime = ostime(timeEventObj.time)
  63. elseif timeEventObj.timerType == TIME_OF_SPECIFIC then -- 特定时间
  64. timeEventObj.doTime = INVALID_NUMBER
  65. elseif timeEventObj.timerType == TIME_OF_HOUR then -- 整数点
  66. timeEventObj.time.hour = timeEventObj.time.hour + 1
  67. timeEventObj.doTime = ostime(timeEventObj.time)
  68. end
  69. end
  70. ---------------------------------------------------------------------------------------
  71. local working
  72. local root = {}
  73. local timeList = {} -- 时间事件列表
  74. local function doWork()
  75. local nowTime = currtime()
  76. local delList = {}
  77. for index, timeEventObj in ipairs(timeList) do
  78. if timeEventObj.doTime == INVALID_NUMBER or (not timeEventObj.func) then
  79. table.insert(delList, index)
  80. goto continue
  81. end
  82. if timeEventObj.doTime > nowTime then
  83. goto continue
  84. end
  85. if debug then
  86. timeEventObj.func()
  87. else
  88. local isok, mag_error =
  89. pcall(
  90. function()
  91. return timeEventObj.func()
  92. end
  93. )
  94. if not isok then
  95. log.error(mag_error)
  96. end
  97. end
  98. doNextTime(timeEventObj)
  99. -- print(" 下一次执行的时间 ", osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime))
  100. ::continue::
  101. end
  102. for i = #delList, 1, -1 do
  103. table.remove(timeList, delList[i])
  104. end
  105. working = nil
  106. if #timeList > 0 then
  107. working = true
  108. skynet.timeout(
  109. 100,
  110. function()
  111. doWork()
  112. end
  113. )
  114. end
  115. end
  116. -- 每隔多久(单位是秒)
  117. function root.timeOut(timeCount, func)
  118. local timeEventObj = timeEventClass.new()
  119. timeEventObj.timerType = TIME_OF_INTER
  120. timeEventObj.timeOut = timeCount -- 间隔时间
  121. timeEventObj.func = func -- 函数指针
  122. timeEventObj.doTime = currtime() + timeCount -- 执行时间
  123. -- print("每隔多久 ----- " ,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime))
  124. table.insert(timeList, timeEventObj)
  125. if not working then
  126. doWork()
  127. end
  128. return timeEventObj
  129. end
  130. -- 每天 (格式 )
  131. function root.timeOfDay(hour, min, sec, func)
  132. local timeEventObj = timePointClass.new()
  133. timeEventObj.timerType = TIME_OF_DAY -- 时间事件类型
  134. timeEventObj.func = func -- 函数指针
  135. -- 计算第一次开始的时间
  136. local nowTime = osdate("*t")
  137. timeEventObj.time.year = nowTime.year
  138. timeEventObj.time.month = nowTime.month
  139. timeEventObj.time.day = nowTime.day
  140. timeEventObj.time.hour = hour
  141. timeEventObj.time.min = min
  142. timeEventObj.time.sec = sec
  143. if ostime(nowTime) >= ostime(timeEventObj.time) then --
  144. timeEventObj.time.day = timeEventObj.time.day + 1
  145. end
  146. timeEventObj.doTime = ostime(timeEventObj.time)
  147. -- print("每天 ----- " ,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime))
  148. table.insert(timeList, timeEventObj)
  149. if not working then
  150. doWork()
  151. end
  152. return timeEventObj
  153. end
  154. -- 每周 (1表示周日)
  155. function root.timeOfWeek(wday, hour, min, sec, func)
  156. local timeEventObj = timePointClass.new()
  157. timeEventObj.timerType = TIME_OF_WEEK -- 时间事件类型
  158. timeEventObj.func = func -- 函数指针
  159. -- 计算第一次开始的时间
  160. local nowTime = osdate("*t")
  161. timeEventObj.time.year = nowTime.year
  162. timeEventObj.time.month = nowTime.month
  163. timeEventObj.time.hour = hour
  164. timeEventObj.time.min = min
  165. timeEventObj.time.sec = sec
  166. if nowTime.wday > wday then
  167. timeEventObj.time.day = nowTime.day + (5 + nowTime.wday - wday)
  168. elseif nowTime.wday == wday then
  169. timeEventObj.time.day = nowTime.day
  170. if ostime(nowTime) > ostime(timeEventObj.time) then
  171. timeEventObj.time.day = timeEventObj.time.day + 7
  172. end
  173. else
  174. timeEventObj.time.day = nowTime.day + (wday - nowTime.wday)
  175. end
  176. timeEventObj.doTime = ostime(timeEventObj.time) ---- 执行时间
  177. -- print("每周 ----- " , wday,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime))
  178. table.insert(timeList, timeEventObj)
  179. if not working then
  180. doWork()
  181. end
  182. return timeEventObj
  183. end
  184. -- 每月
  185. function root.timeOfMonth(day, hour, min, sec, func)
  186. local timeEventObj = timePointClass.new()
  187. timeEventObj.timerType = TIME_OF_MONTH -- 时间事件类型
  188. timeEventObj.func = func -- 函数指针
  189. -- 计算第一次开始的时间
  190. local nowTime = osdate("*t")
  191. timeEventObj.time.year = nowTime.year
  192. timeEventObj.time.month = nowTime.month
  193. timeEventObj.time.day = day
  194. timeEventObj.time.hour = hour
  195. timeEventObj.time.min = min
  196. timeEventObj.time.sec = sec
  197. if ostime(nowTime) >= ostime(timeEventObj.time) then --
  198. timeEventObj.time.month = timeEventObj.time.month + 1
  199. end
  200. timeEventObj.doTime = ostime(timeEventObj.time) -- 执行时间
  201. -- print("每月 ----- " ,osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime))
  202. table.insert(timeList, timeEventObj)
  203. if not working then
  204. doWork()
  205. end
  206. return timeEventObj
  207. end
  208. -- 特定时间
  209. function root.specificTime(year, month, day, hour, min, sec, func)
  210. local timeEventObj = timePointClass.new()
  211. timeEventObj.timerType = TIME_OF_SPECIFIC -- 时间事件类型
  212. timeEventObj.func = func -- 函数指针
  213. -- 计算第一次开始的时间
  214. timeEventObj.time.year = year
  215. timeEventObj.time.month = month
  216. timeEventObj.time.day = day
  217. timeEventObj.time.hour = hour
  218. timeEventObj.time.min = min
  219. timeEventObj.time.sec = sec
  220. local nowTime = currtime()
  221. local workTime = ostime(timeEventObj.time)
  222. if nowTime >= workTime then
  223. timeEventObj.doTime = INVALID_NUMBER
  224. else
  225. timeEventObj.doTime = workTime
  226. end
  227. -- print("特定时间 ----- ", osdate("%Y-%m-%d %H:%M:%S", timeEventObj.doTime))
  228. table.insert(timeList, timeEventObj)
  229. if not working then
  230. doWork()
  231. end
  232. return timeEventObj
  233. end
  234. -- 整点时间
  235. function root.hourOfTime(func)
  236. local timeEventObj = timePointClass.new()
  237. timeEventObj.timerType = TIME_OF_HOUR -- 时间事件类型
  238. timeEventObj.func = func -- 函数指针
  239. local nowTime = osdate("*t")
  240. timeEventObj.time.year = nowTime.year
  241. timeEventObj.time.month = nowTime.month
  242. timeEventObj.time.day = nowTime.day
  243. timeEventObj.time.hour = nowTime.hour
  244. timeEventObj.time.min = 0
  245. timeEventObj.time.sec = 0
  246. if ostime(nowTime) >= ostime(timeEventObj.time) then --
  247. timeEventObj.time.hour = timeEventObj.time.hour + 1
  248. end
  249. timeEventObj.doTime = ostime(timeEventObj.time) -- 执行时间
  250. table.insert(timeList, timeEventObj)
  251. if not working then
  252. doWork()
  253. end
  254. return timeEventObj
  255. end
  256. return root