Advertisement
joebodo

sys.apis.process.lua

Jun 25th, 2014
754
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.61 KB | None | 0 0
  1. local Util = require('util')
  2.  
  3. local Process = { }
  4.  
  5. function Process:init(args)
  6.   self.args = { }
  7.   self.uid = 0
  8.   self.threads = { }
  9.   Util.merge(self, args)
  10.   self.name = self.name or 'Thread:' .. self.uid
  11. end
  12.  
  13. function Process:isDead()
  14.   return coroutine.status(self.co) == 'dead'
  15. end
  16.  
  17. function Process:terminate()
  18.   print('terminating ' .. self.name)
  19.   self:resume('terminate')
  20. end
  21.  
  22. function Process:threadEvent(...)
  23.  
  24.   for _,key in pairs(Util.keys(self.threads)) do
  25.     local thread = self.threads[key]
  26.     if thread then
  27.       thread:resume(...)
  28.     end
  29.   end
  30. end
  31.  
  32. function Process:addThread(fn, ...)
  33.   return self:newThread(nil, fn, ...)
  34. end
  35.  
  36. -- deprecated
  37. function Process:newThread(name, fn, ...)
  38.  
  39.   self.uid = self.uid + 1
  40.  
  41.   local thread = { }
  42.   setmetatable(thread, { __index = Process })
  43.   thread:init({
  44.     fn = fn,
  45.     name = name,
  46.     uid = self.uid,
  47.   })
  48.  
  49.   local args = { ... }
  50.   thread.co = coroutine.create(function()
  51.  
  52.     local s, m = pcall(function() fn(unpack(args)) end)
  53.     if not s and m then
  54.       if m == 'Terminated' then
  55.         --printError(thread.name .. ' terminated')
  56.       else
  57.         printError(m)
  58.       end
  59.     end
  60.  
  61. --print('thread died ' .. thread.name)
  62.     self.threads[thread.uid] = nil
  63.  
  64.     thread:threadEvent('terminate')
  65.  
  66.     return s, m
  67.   end)
  68.  
  69.   self.threads[thread.uid] = thread
  70.  
  71.   thread:resume()
  72.  
  73.   return thread
  74. end
  75.  
  76. function Process:resume(event, ...)
  77.  
  78.   -- threads get a chance to process the event regardless of the main process filter
  79.   self:threadEvent(event, ...)
  80.  
  81.   if not self.filter or self.filter == event or event == "terminate" then
  82.     local ok, result = coroutine.resume(self.co, event, ...)
  83.     if ok then
  84.       self.filter = result
  85.     end
  86.     return ok, result
  87.   end
  88.  
  89.   return true, self.filter
  90. end
  91.  
  92. -- confusing...
  93.  
  94. -- pull either one event if no filter or until event matches filter
  95. -- or until terminated (regardless of filter)
  96. function Process:pullEvent(filter)
  97.   while true do
  98.     local e = { os.pullEventRaw() }
  99.     self:threadEvent(unpack(e))
  100.  
  101.     if not filter or e[1] == filter or e[1] == 'terminate' then
  102.       return unpack(e)
  103.     end
  104.   end
  105. end
  106.  
  107. -- pull events until either the filter is matched or terminated
  108. function Process:pullEvents(filter)
  109.   while true do
  110.     local e = { os.pullEventRaw() }
  111.     self:threadEvent(unpack(e))
  112.     if (filter and e[1] == filter) or e[1] == 'terminate' then
  113.       return unpack(e)
  114.     end
  115.   end
  116. end
  117.  
  118. local process = { }
  119. setmetatable(process, { __index = Process })
  120. process:init({ name = 'Main', co = coroutine.running() })
  121. return process
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement