Simplify rope recalculator (still slow)
This commit is contained in:
parent
429706dae9
commit
a8b921e05b
@ -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 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
|
||||
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 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
|
||||
|
Loading…
Reference in New Issue
Block a user