Skip to content

Commit be44795

Browse files
committed
performance improvements
1 parent b54deb7 commit be44795

File tree

1 file changed

+67
-57
lines changed

1 file changed

+67
-57
lines changed

Diff for: control.lua

+67-57
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,16 @@ local function debug() end
1818
-- end
1919

2020
local function pos2s(pos)
21-
if pos then
21+
if pos.x then
2222
return pos.x..','..pos.y
23+
elseif pos[1] then
24+
return pos[1]..','..pos[2]
2325
end
2426
return ''
2527
end
2628

27-
local function rotate_pos(pos,dir)
28-
local x,y=pos.x,pos.y
29-
if not x then
30-
x,y=pos[1],pos[2]
31-
end
32-
if dir==defines.direction.north then
33-
elseif dir==defines.direction.south then
29+
local function rotate_pos(x,y,dir)
30+
if dir==defines.direction.south then
3431
x = -x
3532
y = -y
3633
elseif dir==defines.direction.east then
@@ -42,7 +39,7 @@ local function rotate_pos(pos,dir)
4239
x = y
4340
y = -t
4441
end
45-
return {x,y,x=x,y=y}
42+
return x,y
4643
end
4744

4845
local belt_speeds = {basic=1,fast=2,express=3,faster=4,purple=5}
@@ -61,11 +58,13 @@ local function terminal_belt_lines(entity,entity_to_ignore)
6158
end
6259
local dir = entity.direction
6360
local pos = entity.position
61+
pos[1] = pos.x
62+
pos[2] = pos.y
6463
local to_check = {}
6564
if entity.type=="splitter" then
6665
to_check = {
67-
{pos=rotate_pos({x=pos.x-0.5,y=pos.y},dir),lines={5,6}},
68-
{pos=rotate_pos({x=pos.x+0.5,y=pos.y},dir),lines={7,8}}}
66+
{pos={rotate_pos(pos.x-0.5,pos.y,dir)},lines={5,6}},
67+
{pos={rotate_pos(pos.x+0.5,pos.y,dir)},lines={7,8}}}
6968
elseif entity.type=="transport-belt-to-ground" and
7069
entity.belt_to_ground_type=="input" then
7170
to_check = {{pos=pos,lines={3,4}}}
@@ -81,10 +80,10 @@ local function terminal_belt_lines(entity,entity_to_ignore)
8180
end
8281
-- following code originally copied from https://github.com/sparr/factorio-mod-belt-combinators
8382
for _,check in pairs(to_check) do
84-
debug("checking "..pos2s(check.pos))
85-
local delta = rotate_pos({0,-1},dir)
86-
local tpos = {x=check.pos.x+delta.x,y=check.pos.y+delta.y}
87-
debug("tpos "..pos2s(tpos))
83+
-- debug("checking "..pos2s(check.pos))
84+
local dx,dy = rotate_pos(0,-1,dir)
85+
local tpos = {check.pos[1]+dx,check.pos[2]+dy}
86+
-- debug("tpos "..pos2s(tpos))
8887
local entities = game.get_surface(entity.surface.index).find_entities({tpos,tpos})
8988
local target = nil
9089
for _,candidate in pairs(entities) do
@@ -98,7 +97,7 @@ local function terminal_belt_lines(entity,entity_to_ignore)
9897
end
9998
end
10099
if target then
101-
debug("target found "..target.type)
100+
-- debug("target found "..target.type)
102101
local function beltspeedword(name)
103102
local m = string.match("^(.*)-transport-belt",name)
104103
if not m then m = string.match("^(.*)-transport-belt-to-ground",name) end
@@ -133,8 +132,8 @@ local function terminal_belt_lines(entity,entity_to_ignore)
133132
local belt_behind_target = false
134133
-- find a belt-like entity behind the target or on the far side
135134
local bpd = {
136-
{pos=rotate_pos({target.position.x,target.position.y+1},target.direction),dir=target.direction},
137-
{pos=rotate_pos({pos.x,pos.y-2},dir),dir=defines.direction.south}
135+
{pos={rotate_pos(target.position.x,target.position.y+1,target.direction)},dir=target.direction},
136+
{pos={rotate_pos(pos.x,pos.y-2,dir)},dir=defines.direction.south}
138137
}
139138
for _,bpos in pairs(bpd) do
140139
local entities = game.get_surface(entity.surface.index).find_entities({bpos.pos,bpos.pos})
@@ -170,45 +169,55 @@ local function terminal_belt_lines(entity,entity_to_ignore)
170169
return {}
171170
end
172171

172+
local line_caps = {curve_right={5,2},curve_left={2,5},straight={4,4},ground={2,2,4,4},splitter={nil,nil,nil,nil,2,2,2,2}}
173+
173174
local function onTick(event)
174175
if event.tick%polling_cycles == 0 then
175176
for y,row in pairs(termbelts) do
176177
for x,belt in pairs(row) do
177-
debug(x..','..y)
178+
-- debug(x..','..y)
178179
if not belt.entity or not belt.entity.valid then
179180
termbelts[y][x]=nil
180181
else
181182
local e = belt.entity
182183
local pos = e.position
183-
local line_caps = {}
184+
local caps
184185
if e.type=="transport-belt" then
185186
if curvebelts[pos.y] and curvebelts[pos.y][pos.x]=="right" then
186-
line_caps={5,2}
187+
caps=line_caps.curve_right
187188
elseif curvebelts[pos.y] and curvebelts[pos.y][pos.x]=="left" then
188-
line_caps={2,5}
189+
caps=line_caps.curve_left
189190
else
190-
line_caps={4,4}
191+
caps=line_caps.straight
191192
end
192193
elseif e.type=="transport-belt-to-ground" then
193-
-- caps for lines 3/4 will get set iff 1/2 are full
194-
line_caps={2,2,9999,9999}
194+
caps=line_caps.ground
195195
elseif e.type=="splitter" then
196-
line_caps={nil,nil,nil,nil,2,2,2,2}
196+
caps=line_caps.splitter
197197
end
198-
for _,line in pairs(belt.lines) do
198+
local ground_prefill = {}
199+
for i=1,#belt.lines do
200+
line = belt.lines[i]
199201
-- debug(pos2s(pos)..' line '..line..':')
200202
local tl = e.get_transport_line(line)
201203
local item_name = nil
202-
for name,count in pairs(tl.get_contents()) do
203-
-- debug(line..' '..name..' '..count)
204-
item_name = name
205-
end
206-
if tl.get_item_count()>=line_caps[line] then
207-
if e.type=="transport-belt-to-ground" and e.belt_to_ground_type=="input" and line<3 then
208-
-- overflow lines 3/4 iff 1/2 are full, and don't overflor 1/2
209-
line_caps[line+2] = 4
204+
if tl.get_item_count()>=caps[line] then
205+
for name,count in pairs(tl.get_contents()) do
206+
-- debug(line..' '..name..' '..count)
207+
item_name = name
208+
break
209+
end
210+
if e.type=="transport-belt-to-ground" and
211+
e.belt_to_ground_type=="input" and
212+
line<3 then
213+
-- track this for future reference, but don't overflow here
214+
ground_prefill[line]=true
215+
elseif e.type=="transport-belt-to-ground" and
216+
e.belt_to_ground_type=="input" and
217+
line>2 and not ground_prefill[line-2] then
218+
-- do nothing, this won't overflow until the prior line overflows
210219
else
211-
debug("overflow "..e.type.." "..line.." "..tl.get_item_count())
220+
-- debug("overflow "..e.type.." "..line.." "..tl.get_item_count())
212221
-- overflow!
213222
-- figure out where the overflow spot is
214223
local x,y = pos.x,pos.y
@@ -231,20 +240,21 @@ local function onTick(event)
231240
if (line%2)==0 then dx = dx + 0.23 else dx = dx - 0.23 end
232241
end
233242
-- rotate the coordinate deltas
234-
local rp = rotate_pos({dx,dy},dir)
235-
x = x + rp.x
236-
y = y + rp.y
237-
if e.surface.find_entity("item-on-ground", {x,y}) then
238-
e.surface.spill_item_stack({x,y}, {name=item_name, count=1})
239-
else -- spill always skips the target spot, fill it first
240-
e.surface.create_entity{name="item-on-ground",
241-
position={x,y}, force=e.force,
242-
stack={name=item_name, count=1}}
243-
end
244-
if tl.remove_item({name=item_name, count=1})==0 then
245-
debug("failed to remove "..item_name)
243+
local rpx,rpy = rotate_pos(dx,dy,dir)
244+
local spill_pos = {x + rpx, y + rpy}
245+
local itemstack = {name=item_name, count=1}
246+
-- if e.surface.find_entity("item-on-ground", spill_pos) then
247+
e.surface.spill_item_stack(spill_pos, itemstack)
248+
-- disabled this condition for performance reasons
249+
-- else -- spill always skips the target spot, fill it first
250+
-- e.surface.create_entity{name="item-on-ground",
251+
-- position=spill_pos, force=e.force,
252+
-- stack={name=item_name, count=1}}
253+
-- end
254+
if tl.remove_item(itemstack)==0 then
255+
debug("belt-overflow failed to remove "..item_name)
246256
else
247-
debug("removed "..item_name.." at "..pos2s(pos))
257+
-- debug("removed "..item_name.." at "..pos2s(pos))
248258
end
249259
end
250260
end
@@ -284,10 +294,10 @@ local function check_and_update(entity,ignore_entity,just_one)
284294
t = terminal_belt_lines(candidate,ignore_entity and entity or nil)
285295
if #t>0 then
286296
termbelts[pos.y][pos.x] = {entity=candidate,lines=t}
287-
debug(pos2s(pos)..' terminal '..candidate.type..' '..lines2s(termbelts[pos.y][pos.x].lines))
297+
-- debug(pos2s(pos)..' terminal '..candidate.type..' '..lines2s(termbelts[pos.y][pos.x].lines))
288298
else
289299
termbelts[pos.y][pos.x] = nil
290-
debug(pos2s(pos)..' non-terminal '..candidate.type)
300+
-- debug(pos2s(pos)..' non-terminal '..candidate.type)
291301
end
292302
end
293303
end
@@ -330,7 +340,7 @@ local function find_all_entities(args)
330340
for _, ent in pairs(surface.find_entities_filtered(args)) do
331341
entities[#entities+1] = ent
332342
end
333-
debug("checked chunk during initialisation")
343+
-- debug("checked chunk during initialisation")
334344
end
335345
end
336346
return entities
@@ -372,11 +382,11 @@ local function onLoad()
372382
refreshData()
373383
end
374384

375-
for y,row in pairs(termbelts) do
376-
for x,belt in pairs(row) do
377-
debug(x..','..y)
378-
end
379-
end
385+
-- for y,row in pairs(termbelts) do
386+
-- for x,belt in pairs(row) do
387+
-- debug(x..','..y)
388+
-- end
389+
-- end
380390

381391
end
382392

0 commit comments

Comments
 (0)