Implement levels:anchor_in as a generator.

This gets rid of the (substantial!) overhead of preparing a list and then iterating over it, in exchange for a bit of bookkeeping to simulate the prior behavior of the for loop, which is much cheaper.
This commit is contained in:
Kistaro Windrider 2022-12-17 17:43:45 -08:00
parent db157b7952
commit 4a53992c3a
Signed by: kistaro
SSH Key Fingerprint: SHA256:TBE2ynfmJqsAf0CP6gsflA0q5X5wD5fVKWPsZ7eVUg8

View File

@ -270,14 +270,17 @@ function level:anchor_points()
end end
function level:anchors_in(px0,py0,px1,py1) function level:anchors_in(px0,py0,px1,py1)
ancs={} local anch,ax,xlim,sy,ylim=self._anch,px0\4,(px1+3)\4,py0\4,(py1+3)\4
for ax=px0\4,(px1+3)\4 do local ay=sy-1
for ay=py0\4,(py1+3)\4 do return function()
local anc=self._anch[_amix(ax,ay)] while true do
if (anc!=nil) add(ancs, anc) ay+=1
if(ay>ylim)ay,ax=sy,ax+1
if(ax>xlim)return nil
local anc=anch[_amix(ax,ay)]
if (anc) return anc
end end
end end
return ancs
end end
function level:get_open_pit(mx,my) function level:get_open_pit(mx,my)
@ -955,7 +958,7 @@ function rope:_find_needed_anchors(i)
local anchors_bydist={} local anchors_bydist={}
local x0,x2=_mnmx(a0.x,a2.x) local x0,x2=_mnmx(a0.x,a2.x)
local y0,y2=_mnmx(a0.y,a2.y) local y0,y2=_mnmx(a0.y,a2.y)
for a1 in all(level:anchors_in(x0-1,y0-1,x2+1,y2+1)) do for a1 in level:anchors_in(x0-1,y0-1,x2+1,y2+1) do
add(anchors_bydist,{el=a1,key=_linedist(a0,a1,a2)}) add(anchors_bydist,{el=a1,key=_linedist(a0,a1,a2)})
end end
shellsort(anchors_bydist) shellsort(anchors_bydist)