recovery.lua 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. -- module catches execution errors and provides editing environment to fix them
  2. -- it's possible to override this source (with same filename in save directory)
  3. -- note that doing so can easily break the development environment
  4. if not arg['restart'] then
  5. lovr.errhand = function(message, traceback)
  6. traceback = traceback or debug.traceback('', 3)
  7. restartInfo = message .. '\n' .. traceback
  8. print(restartInfo)
  9. return function()
  10. return 'restart', restartInfo
  11. -- on restart, restartInfo string will be injected into arg table under 'restart' key
  12. end
  13. end
  14. lovr.event.pump()
  15. lovr.headset.update(0.1)
  16. local forceRecovery = lovr.headset.isDown('hand/right', 'grip')
  17. if not forceRecovery then
  18. return false -- resume booting user project
  19. end
  20. end
  21. -- application error detected -> enter the recovery mode
  22. local modifiers = {ctrl = false, alt = false, shift = false}
  23. -- unmount user save dir to make sure recovery versions are required, then remount to make sources available
  24. lovr.filesystem.unmount(lovr.filesystem.getSaveDirectory())
  25. local editors = require'editors'
  26. local errorpane = require'errorpane'
  27. lovr.filesystem.mount(lovr.filesystem.getSaveDirectory(), "", false)
  28. function lovr.load()
  29. -- parse restart information
  30. local restartInfo = arg['restart'] or 'User-triggered recovery mode'
  31. --error pane
  32. local panes = require'pane'
  33. -- editor
  34. local editor = editors.new(0.8, 1)
  35. editor.pane.transform:set(0,1.5,-1, 1,1,1, math.pi, 0,1,0)
  36. editor:refresh()
  37. lovr.graphics.setBackgroundColor(0x111E13)
  38. errorpane.init(1, 0.4, restartInfo .. '\n\nctrl+up/down scroll up/down\nctrl+enter jump to source')
  39. errorpane.pane.transform:set(0.7, 1.5, -0.4, 1,1,1, 2/3 * math.pi, 0,1,0)
  40. errorpane.jumpToSource()
  41. end
  42. function lovr.draw()
  43. for _, editor in ipairs(editors) do
  44. editor:draw()
  45. end
  46. errorpane.draw()
  47. end
  48. function lovr.keypressed(key, scancode, isrepeat)
  49. if key == 'lctrl' or key == 'rctrl' then
  50. modifiers.ctrl = true
  51. return
  52. elseif key == 'lalt' or key == 'ralt' then
  53. modifiers.alt = true
  54. return
  55. elseif key == 'lshift' or key == 'rshift' then
  56. modifiers.shift = true
  57. return
  58. end
  59. local combo = string.format('%s%s%s%s',
  60. modifiers.ctrl and 'ctrl+' or '',
  61. modifiers.alt and 'alt+' or '',
  62. modifiers.shift and 'shift+' or '',
  63. key)
  64. if combo == 'f5' or combo =='ctrl+shift+r' then
  65. lovr.event.push('restart')
  66. end
  67. if combo =='escape' then
  68. lovr.event.push('quit')
  69. end
  70. editors.keypressed(combo)
  71. errorpane.keypressed(combo)
  72. end
  73. function lovr.keyreleased(key, scancode)
  74. if key == 'lctrl' or key == 'rctrl' then
  75. modifiers.ctrl = false
  76. return
  77. elseif key == 'lalt' or key == 'ralt' then
  78. modifiers.alt = false
  79. return
  80. elseif key == 'lshift' or key == 'rshift' then
  81. modifiers.shift = false
  82. return
  83. end
  84. end
  85. function lovr.textinput(k)
  86. if k:match('[^\n]') then
  87. editors.textinput(k)
  88. end
  89. end