Skip to content

Commit b7fac47

Browse files
committed
Optimized Spell Circle flood-fill by removing an unneeded for loop
1 parent 4667ef6 commit b7fac47

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir,
105105
var todo = new Stack<Pair<Direction, BlockPos>>();
106106
todo.add(Pair.of(impetus.getStartDirection(), impetus.getBlockPos().relative(impetus.getStartDirection())));
107107
var seenGoodPosSet = new HashSet<BlockPos>();
108-
var seenGoodPositions = new ArrayList<BlockPos>();
108+
var positiveBlock = new BlockPos.MutableBlockPos();
109+
var negativeBlock = new BlockPos.MutableBlockPos();
110+
var lastBlockPos = new BlockPos.MutableBlockPos();
111+
BlockPos firstBlock = null;
109112

110113
while (!todo.isEmpty()) {
111114
/*
@@ -137,27 +140,41 @@ cost and generally cheating the system. What would be best would be (somehow) ge
137140
}
138141

139142
if (seenGoodPosSet.add(herePos)) {
143+
if (firstBlock == null) {
144+
firstBlock = herePos;
145+
negativeBlock.set(firstBlock);
146+
positiveBlock.set(firstBlock);
147+
}
148+
lastBlockPos.set(herePos);
149+
// Checks to see if it should update the most positive/negative block pos
150+
if (herePos.getX() > positiveBlock.getX()) positiveBlock.setX(herePos.getX());
151+
if (herePos.getX() < negativeBlock.getX()) negativeBlock.setX(herePos.getX());
152+
153+
if (herePos.getY() > positiveBlock.getY()) positiveBlock.setY(herePos.getY());
154+
if (herePos.getY() < negativeBlock.getY()) negativeBlock.setY(herePos.getY());
155+
156+
if (herePos.getZ() > positiveBlock.getZ()) positiveBlock.setZ(herePos.getZ());
157+
if (herePos.getZ() < negativeBlock.getZ()) negativeBlock.setZ(herePos.getZ());
158+
140159
// it's new
141-
seenGoodPositions.add(herePos);
142160
var outs = cmp.possibleExitDirections(herePos, hereBs, level);
143161
for (var out : outs) {
144162
todo.add(Pair.of(out, herePos.relative(out)));
145163
}
146164
}
147165
}
148166

149-
if (seenGoodPositions.isEmpty()) {
167+
if (firstBlock == null) {
150168
return new Result.Err<>(null);
151169
} else if (!seenGoodPosSet.contains(impetus.getBlockPos())) {
152170
// we can't enter from the side the directrix exits from, so this means we couldn't loop back.
153171
// the last item we tried to examine will always be a terminal slate (b/c if it wasn't,
154172
// then the *next* slate would be last qed)
155-
return new Result.Err<>(seenGoodPositions.get(seenGoodPositions.size() - 1));
173+
return new Result.Err<>(lastBlockPos);
156174
}
157175

158176
var reachedPositions = new HashSet<BlockPos>();
159177
reachedPositions.add(impetus.getBlockPos());
160-
var start = seenGoodPositions.get(0);
161178

162179
FrozenPigment colorizer = null;
163180
UUID casterUUID;
@@ -167,11 +184,10 @@ cost and generally cheating the system. What would be best would be (somehow) ge
167184
colorizer = HexAPI.instance().getColorizer(caster);
168185
casterUUID = caster.getUUID();
169186
}
170-
AABB aabb = BlockEntityAbstractImpetus.getBounds(seenGoodPositions);
171187
return new Result.Ok<>(
172188
new CircleExecutionState(impetus.getBlockPos(), impetus.getStartDirection(),
173-
reachedPositions, start, impetus.getStartDirection(), new CastingImage(), casterUUID, colorizer,
174-
0L, new BlockPos((int) aabb.maxX, (int) aabb.maxY, (int) aabb.maxZ), new BlockPos((int) aabb.minX, (int) aabb.minY, (int) aabb.minZ)));
189+
reachedPositions, firstBlock, impetus.getStartDirection(), new CastingImage(), casterUUID, colorizer,
190+
0L, positiveBlock.move(1,1,1), negativeBlock));
175191
}
176192

177193
public CompoundTag save() {

0 commit comments

Comments
 (0)