sysplus.lua 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. --[[
  2. @module sysplus
  3. @summary LuaTask核心增强逻辑
  4. @version 1.0
  5. @date 2022.04.27
  6. @author 晨旭/刘清宇/李思琦
  7. @usage
  8. ]]
  9. local sys = require "sys"
  10. local sysplus = {}
  11. ----------------------------------------------
  12. -- 提供给异步c接口使用, by 晨旭
  13. sysplus.cwaitMt = {
  14. wait = function(t,r)
  15. return function()
  16. if r and type(r) == "table" then--新建等待失败的返回
  17. return table.unpack(r)
  18. end
  19. return sys.waitUntilMsg(t)
  20. end
  21. end,
  22. cb = function(t,r)
  23. return function(f)
  24. if type(f) ~= "function" then return end
  25. sys.taskInit(function ()
  26. if r and type(r) == "table" then
  27. --sys.wait(1)--如果回调里调用了sys.publish,直接调用回调,会触发不了下一行的吧。。。
  28. f(table.unpack(r))
  29. return
  30. end
  31. f(sys.waitUntilMsg(t))
  32. end)
  33. end
  34. end,
  35. }
  36. sysplus.cwaitMt.__index = function(t,i)
  37. if sysplus.cwaitMt[i] then
  38. return sysplus.cwaitMt[i](rawget(t,"w"),rawget(t,"r"))
  39. else
  40. rawget(t,i)
  41. end
  42. end
  43. _G.sys_cw = function (w,...)
  44. local r = {...}
  45. local t = {w=w,r=(#r > 0 and r or nil)}
  46. setmetatable(t,sysplus.cwaitMt)
  47. return t
  48. end
  49. -------------------------------------------------------------------
  50. ------------- 基于任务的task扩展 by 李思琦---------------------------
  51. --任务列表
  52. local taskList = {}
  53. --- 创建一个任务线程,在模块最末行调用该函数并注册模块中的任务函数,main.lua导入该模块即可
  54. -- @param fun 任务函数名,用于resume唤醒时调用
  55. -- @param taskName 任务名称,用于唤醒任务的id
  56. -- @param cbFun 接收到非目标消息时的回调函数
  57. -- @param ... 任务函数fun的可变参数
  58. -- @return co 返回该任务的线程号
  59. -- @usage sysplus.taskInitEx(task1,'a',callback)
  60. function sysplus.taskInitEx(fun, taskName, cbFun, ...)
  61. taskList[taskName]={msgQueue={}, To=false, cb=cbFun}
  62. return sys.taskInit(fun, ...)
  63. end
  64. --- 删除由taskInitEx创建的任务线程
  65. -- @param taskName 任务名称,用于唤醒任务的id
  66. -- @return 无
  67. -- @usage sysplus.taskDel('a')
  68. function sysplus.taskDel(taskName)
  69. taskList[taskName]=nil
  70. end
  71. local function waitTo(taskName)
  72. taskList[taskName].To = true
  73. sys.publish(taskName)
  74. end
  75. --- 等待接收一个目标消息
  76. -- @param taskName 任务名称,用于唤醒任务的id
  77. -- @param target 目标消息,如果为nil,则表示接收到任意消息都会退出
  78. -- @param ms 超时时间,如果为nil,则表示无超时,永远等待
  79. -- @return msg or false 成功返回table型的msg,超时返回false
  80. -- @usage sysplus.waitMsg('a', 'b', 1000)
  81. function sysplus.waitMsg(taskName, target, ms)
  82. if taskList[taskName] == nil then
  83. log.error("sysplus", "sys.taskInitEx启动的task才能使用waitMsg")
  84. return false
  85. end
  86. local msg = false
  87. local message = nil
  88. if #taskList[taskName].msgQueue > 0 then
  89. msg = table.remove(taskList[taskName].msgQueue, 1)
  90. if target == nil then
  91. return msg
  92. end
  93. if (msg[1] == target) then
  94. return msg
  95. elseif type(taskList[taskName].cb) == "function" then
  96. taskList[taskName].cb(msg)
  97. end
  98. end
  99. sys.subscribe(taskName, coroutine.running())
  100. sys.timerStop(waitTo, taskName)
  101. if ms and ms ~= 0 then
  102. sys.timerStart(waitTo, ms, taskName)
  103. end
  104. taskList[taskName].To = false
  105. local finish=false
  106. while not finish do
  107. message = coroutine.yield()
  108. if #taskList[taskName].msgQueue > 0 then
  109. msg = table.remove(taskList[taskName].msgQueue, 1)
  110. -- sys.info("check target", msg[1], target)
  111. if target == nil then
  112. finish = true
  113. else
  114. if (msg[1] == target) then
  115. finish = true
  116. elseif type(taskList[taskName].cb) == "function" then
  117. taskList[taskName].cb(msg)
  118. end
  119. end
  120. elseif taskList[taskName].To then
  121. -- sys.info(taskName, "wait message timeout")
  122. finish = true
  123. end
  124. end
  125. if taskList[taskName].To then
  126. msg = nil
  127. end
  128. taskList[taskName].To = false
  129. sys.timerStop(waitTo, taskName)
  130. sys.unsubscribe(taskName, coroutine.running())
  131. return msg
  132. end
  133. --- 向目标任务发送一个消息
  134. -- @param taskName 任务名称,用于唤醒任务的id
  135. -- @param param1 消息中的参数1,同时也是waitMsg里的target
  136. -- @param param2 消息中的参数2
  137. -- @param param3 消息中的参数3
  138. -- @param param4 消息中的参数4
  139. -- @return true or false 成功返回true
  140. -- @usage sysplus.sendMsg('a', 'b')
  141. function sysplus.sendMsg(taskName, param1, param2, param3, param4)
  142. if taskList[taskName]~=nil then
  143. table.insert(taskList[taskName].msgQueue, {param1, param2, param3, param4})
  144. sys.publish(taskName)
  145. return true
  146. end
  147. return false
  148. end
  149. function sysplus.cleanMsg(taskName)
  150. if taskList[taskName]~=nil then
  151. taskList[taskName].msgQueue = {}
  152. return true
  153. end
  154. return false
  155. end
  156. function sysplus.taskCB(taskName, msg)
  157. if taskList[taskName]~=nil then
  158. if type(taskList[taskName].cb) == "function" then
  159. taskList[taskName].cb(msg)
  160. return
  161. end
  162. end
  163. log.error(taskName, "no cb fun")
  164. end
  165. _G.sys_send = sysplus.sendMsg
  166. _G.sys_wait = sysplus.waitMsg
  167. return sysplus
  168. ----------------------------