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