snapshot: insight

Ugh, it's been in front of my eyes all along. The logs have been
repeatedly showing a recurrence within a single frame:

key press -> update Viewport.y from screen_top -> A -> B -> update_editor_box -> update screen_top from Viewport.y

We need both those updates, but both should never occur at the same
time to the same node.

I think this is why screen panning works if I take out the scale inside
update_editor_box: the scale has already happened "once" in
updating Viewport.y, and it doesn't converge if we perform it a second
time in a frame. But the solution is just to do one or the other to a
node, never both.

I knew this (learned it the hard way) when I first built pensieve.love,
and I had an assertion to avoid it. But my assertion was brittle, and it
kept failing, and I took it out, and then I slowly took out all the code
that prevented this recurrence.
This commit is contained in:
Kartik K. Agaram 2023-10-25 16:14:08 -07:00
parent 2f34ef4eb8
commit e10ac63be5
5 changed files with 24 additions and 21 deletions

View File

@ -70,7 +70,7 @@ Page = {
'59',
'60',
},
width=400, bg={r=1,g=1,b=0}
width=400, bg={r=0,g=0.8,b=0}
},
},
}
}

View File

@ -1,9 +1,18 @@
on.draw = function()
love.graphics.setColor(0,0,0)
love.graphics.line(50, 0, 50, App.screen.height)
for i=0,100 do
love.graphics.print(tostring(i), 30, i*100)
end
local vy0 = vy(0)
love.graphics.line(100, vy0, 100, App.screen.height)
for i=0,100 do
love.graphics.print(tostring(i), 80, vy0+i*100)
end
love.graphics.line(vx(0), vy(0), vx(0), vy(1000000))
love.graphics.line(vx(0), vy(0), vx(1000000), vy(0))
for i=0,100 do
love.graphics.print(tostring(i), vx(0), vy(i*100))
love.graphics.print(tostring(i), vx(0)-20, vy(i*100))
end
for _,obj in ipairs(Surface) do
love.graphics.setColor(obj.r or 0, obj.g or 0, obj.b or 0)
@ -27,4 +36,4 @@ on.draw = function()
end
end
end
end
end

13
0028-A
View File

@ -1,17 +1,8 @@
A = function()
love.graphics.setFont(love.graphics.newFont(scale(20))) -- editor objects implicitly depend on current font
-- translate Page to Surface
while #Surface > 3 do table.remove(Surface) end -- HACK
local red = false
for x=-1000,2000,300 do
for y=-10000,10000,200 do
add_thick_line({type='line', data={x,y, x+200,y+200, x,y+400}, r=red and 1 or 0,g=red and 0 or 0.5,b=0}, 10)
red = not red
end
end
Surface = {}
compute_layout(Page, Page.x,Page.y, Surface)
compute_layout(Page2, Page2.x,Page2.y, Surface)
-- continue the pipeline
B()
-- TODO: ugly that we're manipulating editor objects twice
end
end

View File

@ -1,5 +1,6 @@
update_editor_box = function(node)
if node.editor == nil then return end
edit.update_font_settings(node.editor, scale(20))
if node.y > Viewport.y then
if node ~= Cursor_node then
node.editor.screen_top1.line = 1
@ -12,6 +13,5 @@ update_editor_box = function(node)
node.editor.left = math.floor(vx(node.x))
node.editor.right = math.ceil(vx(node.x+node.w))
node.editor.width = node.editor.right - node.editor.left
edit.update_font_settings(node.editor, scale(20))
Text.redraw_all(node.editor)
end

View File

@ -1,10 +1,13 @@
dump_state = function()
print('===')
print('zoom', Viewport.zoom)
print('viewport', Viewport.y)
print('node', Page.data[1].y)
print('node renders from', Page.data[1].editor.top)
print('screen top', Page.data[1].editor.screen_top1.line)
print('viewport', Viewport.y, 'spx')
local node = Page.data[1]
print('node', node.y, 'spx')
print('line height', node.editor.line_height, 'vpx')
print('node renders from', node.editor.top, 'vpx')
print('screen top', node.editor.screen_top1.line)
print('invariant', Viewport.y-node.y+node.editor.top - y_of_schema1(node.editor, node.editor.screen_top1))
local l = 25
print('y of line', l, y_of_schema1(Page.data[1].editor, {line=l, pos=1}))
print('y of line', l, y_of_schema1(node.editor, {line=l, pos=1}), 'spx')
end