redo version checks yet again

I'm starting to feel better after replacing 1 line with 20 and 2 new
bits of global state. I'm now handling two scenarios more explicitly:

* If I change Current_app within key_press, the corresponding text_input
  and key_release events go to the new app. If it's an editor it might
  insert the key, which is undesirable. Putting such handlers in
  key_release now feels overly clever, particularly since it took me
  forever to realize why I was getting stuck in an infinite loop.

* Both 'run' and 'source' can hit the version check, so we need to be
  able to transition from the 'error' app to either. Which
  necessitates yet another global bit of state: Next_app.
This commit is contained in:
Kartik K. Agaram 2023-12-06 21:32:10 -08:00
parent 01a26cad5f
commit 19597e7619
3 changed files with 41 additions and 19 deletions

View File

@ -30,7 +30,7 @@ Code loading:
- analogously, how a shape precisely looks as you draw it - analogously, how a shape precisely looks as you draw it
* start out running the text editor, press ctrl+e to edit source, make a change to the source, press ctrl+e twice to return to the source editor; the change should be preserved. * start out running the text editor, press ctrl+e to edit source, make a change to the source, press ctrl+e twice to return to the source editor; the change should be preserved.
* run with an untested version. Error message pops up. Press a key. Text editor comes up, and doesn't receive the key. Press ctrl+e. Source editor opens up. Press ctrl+e. Text editor returns. * run with an untested version. Error message pops up. Press a key. Text editor comes up, and doesn't receive the key. Press ctrl+e. Error pops up. Press a key. Source editor opens up. Press ctrl+e. Error pops up. Press a key. Text editor returns.
* create a couple of spuriously failing tests. Run with an untested version. Error message includes message about untested version. * create a couple of spuriously failing tests. Run with an untested version. Error message includes message about untested version.
### Other compromises ### Other compromises

View File

@ -12,7 +12,6 @@ function love.run()
App.snapshot_love() App.snapshot_love()
-- Tests always run at the start. -- Tests always run at the start.
App.run_tests_and_initialize() App.run_tests_and_initialize()
App.love_version_check() -- hack: we want to run this just the first time and not every time we bounce between 'run' and 'source'
--? print('==') --? print('==')
love.timer.step() love.timer.step()

View File

@ -89,25 +89,30 @@ function App.initialize_globals()
Current_time = 0 Current_time = 0
Last_focus_time = 0 -- https://love2d.org/forums/viewtopic.php?p=249700 Last_focus_time = 0 -- https://love2d.org/forums/viewtopic.php?p=249700
Last_resize_time = 0 Last_resize_time = 0
-- Another weird bit for a class of corner cases. E.g.:
-- * I press ctrl+e, switch Current_app. I don't want the new app to receive
-- text_input and key_release events.
-- If I try to avoid text_input events by switching modes on key_release, I
-- hit a new problem:
-- * I press ctrl+e, am running an untested version, Current_app goes to
-- 'error', and immediately rolls back out of 'error' in the key_release
-- event.
-- Skip_rest_of_key_events is ugly, but feels cleaner than creating yet
-- another possible value for Current_app.
Skip_rest_of_key_events = nil
-- Where to go from 'error' app.
Next_app = nil
end end
function check_love_version_for_tests() function check_love_version_for_tests()
if array.find(Supported_versions, Version) == nil then if array.find(Supported_versions, Version) == nil then
Unsupported_version = true
-- warning to include in an error message if any tests failed -- warning to include in an error message if any tests failed
Warning_before_tests = ("This app hasn't been tested with LÖVE version %s."):format(Version) Warning_before_tests = ("This app hasn't been tested with LÖVE version %s."):format(Version)
end end
end end
function App.love_version_check()
if Unsupported_version then
Current_app = 'error'
Error_message = ("This app hasn't been tested with LÖVE version %s; please switch to version %s if you run into issues. Press any key to continue."):format(Version, Supported_versions[1])
print(Error_message)
-- continue initializing everything; hopefully we won't have errors during initialization
end
end
function App.initialize(arg) function App.initialize(arg)
love.keyboard.setTextInput(true) -- bring up keyboard on touch screen love.keyboard.setTextInput(true) -- bring up keyboard on touch screen
love.keyboard.setKeyRepeat(true) love.keyboard.setKeyRepeat(true)
@ -122,14 +127,25 @@ function App.initialize(arg)
else else
assert(false, 'unknown app "'..Current_app..'"') assert(false, 'unknown app "'..Current_app..'"')
end end
check_love_version()
end
function check_love_version()
if array.find(Supported_versions, Version) == nil then
Next_app = Current_app
Current_app = 'error'
Error_message = ("This app hasn't been tested with LÖVE version %s; please switch to version %s if you run into issues. Press any key to continue."):format(Version, Supported_versions[1])
-- continue initializing everything; hopefully we won't have errors during initialization
end
end end
function App.resize(w,h) function App.resize(w,h)
if Current_app == 'error' then return end
if Current_app == 'run' then if Current_app == 'run' then
if run.resize then run.resize(w,h) end if run.resize then run.resize(w,h) end
elseif Current_app == 'source' then elseif Current_app == 'source' then
if source.resize then source.resize(w,h) end if source.resize then source.resize(w,h) end
elseif Current_app == 'error' then
else else
assert(false, 'unknown app "'..Current_app..'"') assert(false, 'unknown app "'..Current_app..'"')
end end
@ -137,17 +153,18 @@ function App.resize(w,h)
end end
function App.filedropped(file) function App.filedropped(file)
if Current_app == 'error' then return end
if Current_app == 'run' then if Current_app == 'run' then
if run.file_drop then run.file_drop(file) end if run.file_drop then run.file_drop(file) end
elseif Current_app == 'source' then elseif Current_app == 'source' then
if source.file_drop then source.file_drop(file) end if source.file_drop then source.file_drop(file) end
elseif Current_app == 'error' then
else else
assert(false, 'unknown app "'..Current_app..'"') assert(false, 'unknown app "'..Current_app..'"')
end end
end end
function App.focus(in_focus) function App.focus(in_focus)
if Current_app == 'error' then return end
if in_focus then if in_focus then
Last_focus_time = Current_time Last_focus_time = Current_time
end end
@ -155,7 +172,6 @@ function App.focus(in_focus)
if run.focus then run.focus(in_focus) end if run.focus then run.focus(in_focus) end
elseif Current_app == 'source' then elseif Current_app == 'source' then
if source.focus then source.focus(in_focus) end if source.focus then source.focus(in_focus) end
elseif Current_app == 'error' then
else else
assert(false, 'unknown app "'..Current_app..'"') assert(false, 'unknown app "'..Current_app..'"')
end end
@ -178,6 +194,7 @@ end
function App.update(dt) function App.update(dt)
Current_time = Current_time + dt Current_time = Current_time + dt
if Current_app == 'error' then return end
-- some hysteresis while resizing -- some hysteresis while resizing
if Current_time < Last_resize_time + 0.1 then if Current_time < Last_resize_time + 0.1 then
return return
@ -187,7 +204,6 @@ function App.update(dt)
run.update(dt) run.update(dt)
elseif Current_app == 'source' then elseif Current_app == 'source' then
source.update(dt) source.update(dt)
elseif Current_app == 'error' then
else else
assert(false, 'unknown app "'..Current_app..'"') assert(false, 'unknown app "'..Current_app..'"')
end end
@ -199,9 +215,14 @@ function App.keychord_press(chord, key)
return return
end end
-- --
Skip_rest_of_key_events = nil
if Current_app == 'error' then if Current_app == 'error' then
if chord == 'C-c' then if chord == 'C-c' then
love.system.setClipboardText(Error_message) love.system.setClipboardText(Error_message)
else
Current_app = Next_app
Next_app = nil
Skip_rest_of_key_events = true
end end
return return
end end
@ -229,6 +250,7 @@ function App.keychord_press(chord, key)
load_file_from_source_or_save_directory('main.lua') load_file_from_source_or_save_directory('main.lua')
App.undo_initialize() App.undo_initialize()
App.run_tests_and_initialize() App.run_tests_and_initialize()
Skip_rest_of_key_events = true
return return
end end
if Current_app == 'run' then if Current_app == 'run' then
@ -247,6 +269,7 @@ function App.textinput(t)
return return
end end
-- --
if Skip_rest_of_key_events then return end
if Current_app == 'run' then if Current_app == 'run' then
if run.text_input then run.text_input(t) end if run.text_input then run.text_input(t) end
elseif Current_app == 'source' then elseif Current_app == 'source' then
@ -257,14 +280,14 @@ function App.textinput(t)
end end
function App.keyreleased(key, scancode) function App.keyreleased(key, scancode)
if Current_app == 'error' then return end
-- ignore events for some time after window in focus (mostly alt-tab) -- ignore events for some time after window in focus (mostly alt-tab)
if Current_time < Last_focus_time + 0.01 then if Current_time < Last_focus_time + 0.01 then
return return
end end
-- --
if Current_app == 'error' then if Skip_rest_of_key_events then return end
Current_app = 'run' if Current_app == 'run' then
elseif Current_app == 'run' then
if run.key_release then run.key_release(key, scancode) end if run.key_release then run.key_release(key, scancode) end
elseif Current_app == 'source' then elseif Current_app == 'source' then
if source.key_release then source.key_release(key, scancode) end if source.key_release then source.key_release(key, scancode) end