forked from pyrex/chameleonic
		
	Simplify rope recalculator (still slow)
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user