runner.lua 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. local M = {}
  2. local callbacks = {
  3. "draw",
  4. "errhand",
  5. "errorhandler",
  6. "load",
  7. "lowmemory",
  8. "quit",
  9. "run",
  10. "threaderror",
  11. "update",
  12. "directorydropped",
  13. "filedropped",
  14. "focus",
  15. "mousefocus",
  16. "resize",
  17. "visible",
  18. "keypressed",
  19. "keyreleased",
  20. "textedited",
  21. "textinput",
  22. "mousemoved",
  23. "mousepressed",
  24. "mousereleased",
  25. "wheelmoved",
  26. "gamepadaxis",
  27. "gamepadpressed",
  28. "gamepadreleased",
  29. "joystickadded",
  30. "joystickaxis",
  31. "joystickhat",
  32. "joystickpressed",
  33. "joystickreleased",
  34. "joystickremoved",
  35. "touchmoved",
  36. "touchpressed",
  37. "touchreleased",
  38. }
  39. -- revert these back to backup asap
  40. -- local protected = {"errhand", "errorhandler", "run"}
  41. M.backupCallbacks = function()
  42. local backup = {}
  43. for k, v in ipairs(callbacks) do backup[v] = love[v] end
  44. return backup
  45. end
  46. local restoreCallbacks= function(backup)
  47. for k,v in ipairs(callbacks) do love[v] = backup[v] end
  48. end
  49. local clearCallbacks = function()
  50. for k,v in ipairs(callbacks) do love[v] = nil end
  51. end
  52. local avReset = function()
  53. love.audio.stop()
  54. love.mouse.setCursor()
  55. love.mouse.setVisible(true)
  56. love.mouse.setGrabbed(false)
  57. love.mouse.setRelativeMode(false)
  58. love.graphics.reset()
  59. end
  60. local restoreState = function(backup)
  61. if not backup then -- nothing to go back
  62. love.quit = nil
  63. love.event.quit("restart")
  64. return
  65. end
  66. restoreCallbacks(backup)
  67. avReset()
  68. if love.load then love.load() end
  69. end
  70. local dummy = function() end
  71. local quitHook = function(fn, backup)
  72. fn = fn or dummy
  73. return function()
  74. fn()
  75. restoreState(backup)
  76. return true
  77. end
  78. end
  79. local errorHandler = function(msg)
  80. print(msg)
  81. return function()
  82. return "restart"
  83. end
  84. end
  85. local keypressedHook = function(fn, backup)
  86. fn = fn or dummy
  87. return function(k)
  88. if k == "escape" then restoreState(backup) end
  89. fn(k)
  90. return
  91. end
  92. end
  93. local errhand = love.errhand
  94. M.run = function(file, backup, ...)
  95. if not love.filesystem.getInfo(file) then
  96. return false, ("File '%s' does not exit"):format(file)
  97. end
  98. local ok, result = pcall(love.filesystem.load, file)
  99. if not ok then
  100. return false, ("Load error: '%s'"):format(result)
  101. end
  102. clearCallbacks()
  103. ok, result = pcall(result, ...)
  104. if not ok then
  105. restoreState(backup)
  106. return false, ("Run error: '%s'"):format(result)
  107. end
  108. -- hooks
  109. love.keypressed = keypressedHook(love.keypressed, backup)
  110. love.quit = quitHook(love.quit, backup)
  111. -- overrides
  112. love.errhand = backup and backup.errhand or errhand
  113. love.errorhandler = errorHandler
  114. --love.run = nil -- no effect
  115. avReset()
  116. if love.load then love.load() end
  117. return true
  118. end
  119. return M