Simplify rope recalculator (still slow)

This commit is contained in:
Pyrex 2022-12-17 13:19:43 -08:00
parent 429706dae9
commit a8b921e05b

View File

@ -676,38 +676,76 @@ end
function rope:_tidy_up_gen()
if (self:busy()) return
for i=0,#self.ancs+1 do
local a=self:_anc(i)
a.dirty=true
end
if (self.under_destruction) return
local settled=true
local touched={}
local loop=function(f)
local a=0
while a<=#self.ancs+1 do
local anc=self:_anc(a)
if anc.dirty and #anc.todo==0 then
while not self.under_destruction and (
self:_find_needed_anchors(a) or
self:_find_touched_anchors(a) or
self:_elide_point(a)
) do end
anc.dirty=false
a=0
else
if anc.dirty then
anc.seen=true
if self[f](self,a) then
settled=false anc.changed=true
end
end
a+=1
end
end
local mark_unseen=function()
touched={}
for a=0,#self.ancs+1,1 do
local anc=self:_anc(a)
anc.seen=false
anc.changed=false
end
end
local propagate_dirty=function(f)
for a=0,#self.ancs+1,1 do
local a1=self:_anc(a)
if a1.dirty then
local a0=self:_anc(a-1)
if (a0!=nil) a0.dirty=true
local a2=self:_anc(a+1)
if (a2!=nil) a2.dirty=true
end
end
end
while true do
settled=true
mark_unseen()
propagate_dirty()
loop("_find_needed_anchors")
loop("_find_touched_anchors")
loop("_elide_point")
for a=0,#self.ancs+1,1 do
local anc=self:_anc(a)
if anc.seen then
anc.dirty=anc.changed
end
end
if (settled) break
end
end
function rope:_drag1(
i,x,y
)
local a_old=self:_anc(i)
local a_new={x=x,y=y}
if (_point_eq(a_old, a_new)) return
local a=self:_anc(i)
if (_point_eq(a, {x=x,y=y})) return
a_old.x=x
a_old.y=y
a.x=x
a.y=y
a.dirty=true
end
function rope:_find_needed_anchors(i)
@ -741,11 +779,9 @@ function rope:_find_needed_anchors(i)
self:_can_stretch(a1,a2)
then
local id=self.id
add(self.ancs,{id=id,x=a1.x,y=a1.y,todo={}},i)
add(self.ancs,{id=id,x=a1.x,y=a1.y,dirty=true,todo={}},i)
self.id+=1
self:_anc(i-1).dirty=true
self:_anc(i+1).dirty=true
return true
end
end
@ -765,12 +801,9 @@ function rope:_find_touched_anchors(i)
-- and self:_can_stretch(p,a2)
then
local id=self.id
add(self.ancs,{id=id,x=a1.x,y=a1.y,todo={}},i)
add(self.ancs,{id=id,x=a1.x,y=a1.y,dirty=true,todo={}},i)
self.id+=1
self:_anc(i-1).dirty=true
self:_anc(i+1).dirty=true
return true
end
end
@ -808,8 +841,6 @@ function rope:_elide_point(i)
end
deli(self.ancs,i)
self:_anc(i-1).dirty=true
self:_anc(i).dirty=true
return true
end
@ -1034,7 +1065,6 @@ function rope:_tug()
if force or not level:pcoll(x,y) then
s.x=x
s.y=y
s.dirty=true
end
return true
end}
@ -1048,7 +1078,6 @@ function rope:_tug()
end
for node=ancs[i-1].ix-1,ancs[i].ix+1 do
local anc=self:_anc(node)
if (anc!=nil) anc.dirty=true
end
return
end