sysplus.lua 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. local msg = false
  83. local message = nil
  84. if #taskList[taskName].msgQueue > 0 then
  85. msg = table.remove(taskList[taskName].msgQueue, 1)
  86. if target == nil then
  87. return msg
  88. end
  89. if (msg[1] == target) then
  90. return msg
  91. elseif type(taskList[taskName].cb) == "function" then
  92. taskList[taskName].cb(msg)
  93. end
  94. end
  95. sys.subscribe(taskName, coroutine.running())
  96. sys.timerStop(waitTo, taskName)
  97. if ms and ms ~= 0 then
  98. sys.timerStart(waitTo, ms, taskName)
  99. end
  100. taskList[taskName].To = false
  101. local finish=false
  102. while not finish do
  103. message = coroutine.yield()
  104. if #taskList[taskName].msgQueue > 0 then
  105. msg = table.remove(taskList[taskName].msgQueue, 1)
  106. -- sys.info("check target", msg[1], target)
  107. if target == nil then
  108. finish = true
  109. else
  110. if (msg[1] == target) then
  111. finish = true
  112. elseif type(taskList[taskName].cb) == "function" then
  113. taskList[taskName].cb(msg)
  114. end
  115. end
  116. elseif taskList[taskName].To then
  117. -- sys.info(taskName, "wait message timeout")
  118. finish = true
  119. end
  120. end
  121. if taskList[taskName].To then
  122. msg = nil
  123. end
  124. taskList[taskName].To = false
  125. sys.timerStop(waitTo, taskName)
  126. sys.unsubscribe(taskName, coroutine.running())
  127. return msg
  128. end
  129. --- 向目标任务发送一个消息
  130. -- @param taskName 任务名称,用于唤醒任务的id
  131. -- @param param1 消息中的参数1,同时也是waitMsg里的target
  132. -- @param param2 消息中的参数2
  133. -- @param param3 消息中的参数3
  134. -- @param param4 消息中的参数4
  135. -- @return true or false 成功返回true
  136. -- @usage sysplus.sendMsg('a', 'b')
  137. function sysplus.sendMsg(taskName, param1, param2, param3, param4)
  138. if taskList[taskName]~=nil then
  139. table.insert(taskList[taskName].msgQueue, {param1, param2, param3, param4})
  140. sys.publish(taskName)
  141. return true
  142. end
  143. return false
  144. end
  145. function sysplus.cleanMsg(taskName)
  146. if taskList[taskName]~=nil then
  147. taskList[taskName].msgQueue = {}
  148. return true
  149. end
  150. return false
  151. end
  152. function sysplus.taskCB(taskName, msg)
  153. if taskList[taskName]~=nil then
  154. if type(taskList[taskName].cb) == "function" then
  155. taskList[taskName].cb(msg)
  156. return
  157. end
  158. end
  159. log.error(taskName, "no cb fun")
  160. end
  161. _G.sys_send = sysplus.sendMsg
  162. _G.sys_wait = sysplus.waitMsg
  163. return sysplus
  164. ----------------------------