about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Manual_tests.md6
-rw-r--r--app.lua15
-rw-r--r--main.lua116
-rw-r--r--reference.md3
4 files changed, 100 insertions, 40 deletions
diff --git a/Manual_tests.md b/Manual_tests.md
index b6f3c99..4220dee 100644
--- a/Manual_tests.md
+++ b/Manual_tests.md
@@ -17,7 +17,8 @@ Initializing settings:
   - start out editing source, move window, press ctrl+e twice; window is editing source in same position+dimensions
   - no log file; switching to source works
 
-  - run with an unsupported version. Error message pops up and waits for a key. The app attempts to continue, and doesn't receive the key.
+  - run with an untested version. Error message pops up and waits for a key. The app attempts to continue, and doesn't receive the key.
+  - run with a LÖVE v12 release candidate. No errors; it is a supported version. All tests pass.
 
 Code loading:
 * run love with directory; text editor runs
@@ -29,7 +30,8 @@ Code loading:
     - 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.
-* run with an unsupported version. Error message pops up and waits for a key. The app attempts to continue, and doesn't receive the key. Press ctrl+e to edit source. Source editor opens up without checking version.
+* 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.
 
 ### Other compromises
 
diff --git a/app.lua b/app.lua
index e4b67cc..271fdc3 100644
--- a/app.lua
+++ b/app.lua
@@ -8,10 +8,10 @@
 --     and a source editor, while giving each the illusion of complete
 --     control.
 function love.run()
+  Version, Major_version = App.love_version()
   App.snapshot_love()
   -- Tests always run at the start.
   App.run_tests_and_initialize()
-  App.version_check()
 --?   print('==')
 
   love.timer.step()
@@ -85,6 +85,12 @@ end
 
 App = {}
 
+function App.love_version()
+  local major_version, minor_version = love.getVersion()
+  local version = major_version..'.'..minor_version
+  return version, major_version
+end
+
 -- save/restore various framework globals we care about -- only on very first load
 function App.snapshot_love()
   if Love_snapshot then return end
@@ -102,7 +108,12 @@ function App.run_tests_and_initialize()
   Test_errors = {}
   App.run_tests()
   if #Test_errors > 0 then
-    error(('There were %d test failures:\n\n%s'):format(#Test_errors, table.concat(Test_errors)))
+    local error_message = ''
+    if Warning_before_tests then
+      error_message = Warning_before_tests..'\n\n'
+    end
+    error_message = error_message .. ('There were %d test failures:\n%s'):format(#Test_errors, table.concat(Test_errors))
+    error(error_message)
   end
   App.disable_tests()
   App.initialize_globals()
diff --git a/main.lua b/main.lua
index 918d414..61b5939 100644
--- a/main.lua
+++ b/main.lua
@@ -32,6 +32,11 @@ function App.load()
     Current_app = Settings.current_app
   end
 
+  -- Current_app =
+  --  | run
+  --  | source
+  --  | {name=warning message='...' next_app = run|source}
+
   if Current_app == nil then
     Current_app = 'run'
   end
@@ -64,35 +69,21 @@ function App.load()
         load_file_from_source_or_save_directory('help.lua')
       load_file_from_source_or_save_directory('drawing_tests.lua')
     load_file_from_source_or_save_directory('source_tests.lua')
-  elseif Current_app == 'error' then
+  elseif current_app_is_warning() then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
 end
 
-function App.version_check()
-  -- available modes: run, error
-  Error_message = nil
-  Error_count = 0
-  -- we'll reuse error mode on load for an initial version check
-  local supported_versions = {'11.5', '11.4', '12.0'}  -- put the recommended version first
-  local minor_version
-  Major_version, minor_version = love.getVersion()
-  Version = Major_version..'.'..minor_version
-  if array.find(supported_versions, Version) == nil then
-    Current_app = 'error'
-    Error_message = ("This app doesn't support version %s; please use version %s. Press any key to try it with this version anyway."):format(Version, supported_versions[1])
-    print(Error_message)
-    -- continue initializing everything; hopefully we won't have errors during initialization
-  end
-end
-
 function App.initialize_globals()
+  Supported_versions = {'11.5', '11.4', '12.0'}  -- put the recommended version first
+  check_love_version_for_tests()
+
   if Current_app == 'run' then
     run.initialize_globals()
   elseif Current_app == 'source' then
     source.initialize_globals()
-  elseif Current_app == 'error' then
+  elseif current_app_is_warning() then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
@@ -101,6 +92,25 @@ function App.initialize_globals()
   Current_time = 0
   Last_focus_time = 0  -- https://love2d.org/forums/viewtopic.php?p=249700
   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
+  --   'warning', and immediately rolls back out of 'warning' 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
+end
+
+function check_love_version_for_tests()
+  if array.find(Supported_versions, Version) == nil then
+    -- 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)
+  end
 end
 
 function App.initialize(arg)
@@ -113,18 +123,28 @@ function App.initialize(arg)
     run.initialize(arg)
   elseif Current_app == 'source' then
     source.initialize(arg)
-  elseif Current_app == 'error' then
+  elseif current_app_is_warning() then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
+
+  check_love_version()
+end
+
+function check_love_version()
+  if array.find(Supported_versions, Version) == nil then
+    show_warning(
+      ("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
 
 function App.resize(w,h)
+  if current_app_is_warning() then return end
   if Current_app == 'run' then
     if run.resize then run.resize(w,h) end
   elseif Current_app == 'source' then
     if source.resize then source.resize(w,h) end
-  elseif Current_app == 'error' then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
@@ -132,17 +152,18 @@ function App.resize(w,h)
 end
 
 function App.filedropped(file)
+  if current_app_is_warning() then return end
   if Current_app == 'run' then
     if run.file_drop then run.file_drop(file) end
   elseif Current_app == 'source' then
     if source.file_drop then source.file_drop(file) end
-  elseif Current_app == 'error' then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
 end
 
 function App.focus(in_focus)
+  if current_app_is_warning() then return end
   if in_focus then
     Last_focus_time = Current_time
   end
@@ -150,7 +171,6 @@ function App.focus(in_focus)
     if run.focus then run.focus(in_focus) end
   elseif Current_app == 'source' then
     if source.focus then source.focus(in_focus) end
-  elseif Current_app == 'error' then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
@@ -161,11 +181,11 @@ function App.draw()
     run.draw()
   elseif Current_app == 'source' then
     source.draw()
-  elseif Current_app == 'error' then
+  elseif current_app_is_warning() then
     love.graphics.setColor(0,0,1)
     love.graphics.rectangle('fill', 0,0, App.screen.width, App.screen.height)
     love.graphics.setColor(1,1,1)
-    love.graphics.printf(Error_message, 40,40, 600)
+    love.graphics.printf(Current_app.message, 40,40, 600)
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
@@ -173,6 +193,7 @@ end
 
 function App.update(dt)
   Current_time = Current_time + dt
+  if current_app_is_warning() then return end
   -- some hysteresis while resizing
   if Current_time < Last_resize_time + 0.1 then
     return
@@ -182,7 +203,6 @@ function App.update(dt)
     run.update(dt)
   elseif Current_app == 'source' then
     source.update(dt)
-  elseif Current_app == 'error' then
   else
     assert(false, 'unknown app "'..Current_app..'"')
   end
@@ -194,9 +214,13 @@ function App.keychord_press(chord, key)
     return
   end
   --
-  if Current_app == 'error' then
+  Skip_rest_of_key_events = nil
+  if current_app_is_warning() then
     if chord == 'C-c' then
       love.system.setClipboardText(Error_message)
+    else
+      clear_warning()
+      Skip_rest_of_key_events = true
     end
     return
   end
@@ -214,7 +238,7 @@ function App.keychord_press(chord, key)
       if source.quit then source.quit() end
       Current_app = 'run'
       Error_message = nil
-    elseif Current_app == 'error' then
+    elseif current_app_is_warning() then
     else
       assert(false, 'unknown app "'..Current_app..'"')
     end
@@ -224,6 +248,7 @@ function App.keychord_press(chord, key)
     load_file_from_source_or_save_directory('main.lua')
     App.undo_initialize()
     App.run_tests_and_initialize()
+    Skip_rest_of_key_events = true
     return
   end
   if Current_app == 'run' then
@@ -236,12 +261,13 @@ function App.keychord_press(chord, key)
 end
 
 function App.textinput(t)
-  if Current_app == 'error' then return end
+  if current_app_is_warning() then return end
   -- ignore events for some time after window in focus (mostly alt-tab)
   if Current_time < Last_focus_time + 0.01 then
     return
   end
   --
+  if Skip_rest_of_key_events then return end
   if Current_app == 'run' then
     if run.text_input then run.text_input(t) end
   elseif Current_app == 'source' then
@@ -252,14 +278,14 @@ function App.textinput(t)
 end
 
 function App.keyreleased(key, scancode)
+  if current_app_is_warning() then return end
   -- ignore events for some time after window in focus (mostly alt-tab)
   if Current_time < Last_focus_time + 0.01 then
     return
   end
   --
-  if Current_app == 'error' then
-    Current_app = 'run'
-  elseif Current_app == 'run' then
+  if Skip_rest_of_key_events then return end
+  if Current_app == 'run' then
     if run.key_release then run.key_release(key, scancode) end
   elseif Current_app == 'source' then
     if source.key_release then source.key_release(key, scancode) end
@@ -269,7 +295,7 @@ function App.keyreleased(key, scancode)
 end
 
 function App.mousepressed(x,y, mouse_button)
-  if Current_app == 'error' then return end
+  if current_app_is_warning() then return end
 --?   print('mouse press', x,y)
   if Current_app == 'run' then
     if run.mouse_press then run.mouse_press(x,y, mouse_button) end
@@ -281,7 +307,7 @@ function App.mousepressed(x,y, mouse_button)
 end
 
 function App.mousereleased(x,y, mouse_button)
-  if Current_app == 'error' then return end
+  if current_app_is_warning() then return end
   if Current_app == 'run' then
     if run.mouse_release then run.mouse_release(x,y, mouse_button) end
   elseif Current_app == 'source' then
@@ -292,7 +318,7 @@ function App.mousereleased(x,y, mouse_button)
 end
 
 function App.wheelmoved(dx,dy)
-  if Current_app == 'error' then return end
+  if current_app_is_warning() then return end
   if Current_app == 'run' then
     if run.mouse_wheel_move then run.mouse_wheel_move(dx,dy) end
   elseif Current_app == 'source' then
@@ -303,7 +329,7 @@ function App.wheelmoved(dx,dy)
 end
 
 function love.quit()
-  if Current_app == 'error' then return end
+  if current_app_is_warning() then return end
   if Current_app == 'run' then
     local source_settings = Settings.source
     Settings = run.settings()
@@ -321,3 +347,21 @@ function love.quit()
     assert(false, 'unknown app "'..Current_app..'"')
   end
 end
+
+function current_app_is_warning()
+  return type(Current_app) == 'table' and Current_app.name == 'warning'
+end
+
+function show_warning(message)
+  assert(type(Current_app) == 'string')
+  Current_app = {
+    name = 'warning',
+    message = message,
+    next_app = Current_app,
+  }
+end
+
+function clear_warning()
+  assert(type(Current_app) == 'table')
+  Current_app = Current_app.next_app
+end
diff --git a/reference.md b/reference.md
index d0956ba..1f1f724 100644
--- a/reference.md
+++ b/reference.md
@@ -11,6 +11,9 @@ automatically called for you as appropriate.
   * `flags` -- some properties of the app window. See [`flags` in `love.graphics.getMode`](https://love2d.org/wiki/love.window.getMode)
     for details.
 
+* `Version` -- the running version of LÖVE as a string, e.g. '11.4'.
+* `Major_version` -- just the part before the period as an int, e.g. 11.
+
 ## Functions that get automatically called
 
 * `App.initialize_globals()` -- called before running each test and also