diff --git a/0005-animate b/0005-animate index 2ffb915..10d46c0 100644 --- a/0005-animate +++ b/0005-animate @@ -1,8 +1,5 @@ --- A debugging aid to help animate intermediate results within f. --- Pause animation in the current frame using loiter(). --- Try to only have one such call in your program. --- You can have multiple, but things might get confusing if one of them indirectly calls the other, --- or more generally if a single function ever loiters sometimes under the call tree of one and sometimes under the other. +-- Animate 'f' by smearing its work across multiple frames. +-- Pause animation in the current frame using end_frame(). animate = function(f, ...) local args = {...} Error_with_callstack = nil @@ -17,5 +14,5 @@ animate = function(f, ...) if Error_with_callstack then error(Error_with_callstack) end - table.insert(Debug_animations_in_progress, {co=co, next_run=Current_time+0.3}) -end + table.insert(Animations_in_progress, {co=co}) +end \ No newline at end of file diff --git a/0006-loiter b/0006-loiter index 6c06705..514396e 100644 --- a/0006-loiter +++ b/0006-loiter @@ -1,5 +1,5 @@ -- A debugging aid to animate intermediate results in computations. --- Can only be called from functions invoked using `animate()`. +-- Can only be called from functions invoked using `enable_loiter()`. loiter = function() coroutine.yield() -end +end \ No newline at end of file diff --git a/0007-save_callstack b/0007-save_callstack index 2cd0970..121ba62 100644 --- a/0007-save_callstack +++ b/0007-save_callstack @@ -1,7 +1,7 @@ --- Internal helper for animate() +-- Internal helper for animations. -- Records the stack of function calls that led to any error within a debug animation coroutine. -- Lua normally prints out errors with callstacks, but coroutines interrupt the stack unless we do some additional work. save_callstack = function(err) local callstack = debug.traceback('', --[[stack frame]]2) Error_with_callstack = 'Error: ' .. cleaned_up_frame(tostring(err))..'\n'..cleaned_up_callstack(callstack) -end +end \ No newline at end of file diff --git a/0012-on.draw b/0012-on.draw index 0bf0c7b..58de3d7 100644 --- a/0012-on.draw +++ b/0012-on.draw @@ -10,4 +10,5 @@ on.draw = function() edit.draw(Current_pane.output_editor_state, Normal_color, --[[hide cursor]] true) draw_scrollbar(Current_pane.output_editor_state) draw_menu() + draw_next_frames_of_animations() end \ No newline at end of file diff --git a/0021-draw_menu b/0021-draw_menu index 1a51955..2d5433c 100644 --- a/0021-draw_menu +++ b/0021-draw_menu @@ -25,6 +25,7 @@ draw_menu = function() onpress1 = function() Current_pane_index = Current_pane_index-1 Current_pane = Panes[Current_pane_index] + animate(slide_canvas(Current_pane_index+1, 'right')) end, }) end @@ -39,6 +40,7 @@ draw_menu = function() table.insert(Panes, new_pane()) Current_pane_index = Current_pane_index+1 Current_pane = Panes[Current_pane_index] + animate(slide_canvas(Current_pane_index-1, 'left')) end, }) else @@ -50,6 +52,7 @@ draw_menu = function() onpress1 = function() Current_pane_index = Current_pane_index+1 Current_pane = Panes[Current_pane_index] + animate(slide_canvas(Current_pane_index-1, 'left')) end, }) end diff --git a/0052-enable_loiter b/0052-enable_loiter new file mode 100644 index 0000000..8279839 --- /dev/null +++ b/0052-enable_loiter @@ -0,0 +1,21 @@ +-- A debugging aid to help animate intermediate results within f. +-- Pause animation in the current frame using loiter(). +-- Try to only have one such call in your program. +-- You can have multiple, but things might get confusing if one of them indirectly calls the other, +-- or more generally if a single function ever loiters sometimes under the call tree of one and sometimes under the other. +enable_loiter = function(f, ...) + local args = {...} + Error_with_callstack = nil + local co = coroutine.create( + function() + xpcall(function() + f(unpack(args)) + end, + save_callstack) + end) + coroutine.resume(co, ...) + if Error_with_callstack then + error(Error_with_callstack) + end + table.insert(Debug_animations_in_progress, {co=co, next_run=Current_time+0.3}) +end \ No newline at end of file diff --git a/0054-Animations_in_progress b/0054-Animations_in_progress new file mode 100644 index 0000000..125e04c --- /dev/null +++ b/0054-Animations_in_progress @@ -0,0 +1,2 @@ +-- Intermediate state during animations. +Animations_in_progress = {} \ No newline at end of file diff --git a/0056-end_frame b/0056-end_frame new file mode 100644 index 0000000..4cd1b22 --- /dev/null +++ b/0056-end_frame @@ -0,0 +1,4 @@ +-- Pause a drawing called by animate(). +end_frame = function() + coroutine.yield() +end \ No newline at end of file diff --git a/0058-draw_next_frames_of_animations b/0058-draw_next_frames_of_animations new file mode 100644 index 0000000..9472b6a --- /dev/null +++ b/0058-draw_next_frames_of_animations @@ -0,0 +1,14 @@ +-- update any in-progress animations +-- return whether any work remains +draw_next_frames_of_animations = function() + local a = Animations_in_progress + for i=#a,1,-1 do + if coroutine.status(a[i].co) == 'dead' then + table.remove(a, i) + else + local status, err = coroutine.resume(a[i].co) + if status == false then error(err) end + end + end + return #a > 0 +end \ No newline at end of file diff --git a/0059-slide_canvas b/0059-slide_canvas new file mode 100644 index 0000000..0e27982 --- /dev/null +++ b/0059-slide_canvas @@ -0,0 +1,18 @@ +slide_canvas = function(pane_index, dir) + return function() + end_frame() + if dir == 'right' then + for i=1,40 do + print(Current_time, i) + love.graphics.rectangle('fill', i*10,0, 30, App.screen.height) + end_frame() + end + elseif dir == 'left' then + for i=20,1,-1 do + print(i) + love.graphics.line(i*50,0, i*50, App.screen.height) + end_frame() + end + end + end +end \ No newline at end of file