after.lua 1012 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. local jobs = {}
  2. local time = 0.0
  3. local time_next = math.huge
  4. core.register_globalstep(function(dtime)
  5. time = time + dtime
  6. if time < time_next then
  7. return
  8. end
  9. time_next = math.huge
  10. -- Iterate backwards so that we miss any new timers added by
  11. -- a timer callback.
  12. for i = #jobs, 1, -1 do
  13. local job = jobs[i]
  14. if time >= job.expire then
  15. core.set_last_run_mod(job.mod_origin)
  16. job.func(unpack(job.arg))
  17. local jobs_l = #jobs
  18. jobs[i] = jobs[jobs_l]
  19. jobs[jobs_l] = nil
  20. elseif job.expire < time_next then
  21. time_next = job.expire
  22. end
  23. end
  24. end)
  25. function core.after(after, func, ...)
  26. assert(tonumber(after) and type(func) == "function",
  27. "Invalid minetest.after invocation")
  28. local expire = time + after
  29. local new_job = {
  30. func = func,
  31. expire = expire,
  32. arg = {...},
  33. mod_origin = core.get_last_run_mod(),
  34. }
  35. jobs[#jobs + 1] = new_job
  36. time_next = math.min(time_next, expire)
  37. return {
  38. cancel = function()
  39. new_job.func = function() end
  40. new_job.args = {}
  41. end
  42. }
  43. end