Skip to content

Commit f905577

Browse files
committed
Another attempt at optimizing around poor block iteration performance
1 parent 19268a6 commit f905577

File tree

3 files changed

+80
-15
lines changed

3 files changed

+80
-15
lines changed

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ githubRelease {
3939
prerelease = isUnstable
4040
}
4141

42+
tasks.publish { dependsOn(tasks.githubRelease) }
43+
4244
idea.project.settings.runConfigurations {
4345
register<JUnitExt>("Core Tests") {
4446
vmParameters = "-ea"

projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessNetwork.java

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@
1212
import dan200.computercraft.shared.util.WirelessHelpers;
1313
import net.minecraft.core.BlockPos;
1414
import net.minecraft.core.Vec3i;
15+
import net.minecraft.world.level.block.Block;
16+
import net.minecraft.world.level.chunk.LevelChunk;
17+
import org.slf4j.Logger;
18+
import org.slf4j.LoggerFactory;
1519

1620
import java.util.*;
1721
import java.util.concurrent.ConcurrentHashMap;
1822

1923
public class WirelessNetwork implements PacketNetwork {
24+
private static final Logger log = LoggerFactory.getLogger(WirelessNetwork.class);
2025
private final Set<PacketReceiver> receivers = Collections.newSetFromMap(new ConcurrentHashMap<>());
2126

22-
private final static List<Vec3i> obstructionBlocks = new ArrayList<Vec3i>(2048);
27+
private final static ArrayList<Vec3i> obstructionBlocks = new ArrayList<Vec3i>(2048);
28+
private final static ArrayList<BlockPos> unloadedBlocks = new ArrayList<BlockPos>(2048);
2329

2430
@Override
2531
public void addReceiver(PacketReceiver receiver) {
@@ -50,11 +56,11 @@ private static void tryTransmit(PacketReceiver receiver, Packet packet, double r
5056
if (receiver.getLevel() == sender.getLevel()) {
5157
var level = receiver.getLevel();
5258
var receiveRange = Math.max(range, receiver.getRange()); // Ensure range is symmetrical
53-
var distanceSq = receiver.getPosition().distanceToSqr(sender.getPosition());
59+
var distance = receiver.getPosition().distanceTo(sender.getPosition());
5460

5561
// Interdimensional - just send it
5662
if (interdimensional && receiver.isInterdimensional()) {
57-
receiver.receiveSameDimension(packet, Math.sqrt(distanceSq), 0.0);
63+
receiver.receiveSameDimension(packet, distance, 0.0);
5864
return;
5965
}
6066

@@ -74,7 +80,7 @@ private static void tryTransmit(PacketReceiver receiver, Packet packet, double r
7480
useCache = false;
7581
}
7682

77-
if (distanceSq <= receiveRange * receiveRange) {
83+
if (distance <= receiveRange) {
7884
Vec3i senderBlockPosition = WirelessHelpers.floorToVec3i(sender.getPosition());
7985
Vec3i receiverBlockPosition = WirelessHelpers.floorToVec3i(receiver.getPosition());
8086

@@ -93,32 +99,89 @@ private static void tryTransmit(PacketReceiver receiver, Packet packet, double r
9399
if (cachedSignalDegradation > receiveRange) {
94100
return;
95101
}
96-
receiver.receiveSameDimension(packet, Math.sqrt(distanceSq), receiveRange - cachedSignalDegradation);
102+
receiver.receiveSameDimension(packet, distance, receiveRange - cachedSignalDegradation);
97103
return;
98104
}
99105
}
100106

101107

102108
WirelessHelpers.Bresenham3D(obstructionBlocks, senderBlockPosition, receiverBlockPosition);
103-
var signalDegradation = 0.0;
109+
var signalDegradation = distance;
104110
var diagonalCompensation = WirelessHelpers.getDiagonalCompensation(senderBlockPosition, receiverBlockPosition);
105111

112+
var enumerationCounter = 0;
113+
var cancelled = false;
114+
115+
unloadedBlocks.clear();
116+
117+
var timer = System.currentTimeMillis(); // yes this is vulnerable to leap seconds, fight me
118+
106119
for (Vec3i blockVector : obstructionBlocks) {
107-
var explosionResistance = level.getBlockState(new BlockPos(blockVector))
108-
.getBlock()
109-
.getExplosionResistance();
110-
if (explosionResistance >= 100)
111-
explosionResistance /= 4;
112-
signalDegradation += (signalDegradation / 100.0 * explosionResistance + 1.0) * diagonalCompensation;
120+
var currentBlockPos = new BlockPos(blockVector);
121+
if (level.isLoaded(currentBlockPos) && !level.isEmptyBlock(currentBlockPos)) {
122+
var currentBlockState = level.getBlockState(currentBlockPos);
123+
if (!currentBlockState.isAir()) {
124+
var explosionResistance = currentBlockState.getBlock().getExplosionResistance();
125+
if (explosionResistance >= 100)
126+
explosionResistance /= 4;
127+
signalDegradation += Math.sqrt(explosionResistance) * 10.0 * diagonalCompensation;
128+
}
129+
} else {
130+
unloadedBlocks.add(currentBlockPos);
131+
}
132+
133+
if (signalDegradation > receiveRange) {
134+
break;
135+
}
136+
enumerationCounter++;
137+
if (timer + 500 <= System.currentTimeMillis()) {
138+
log.warn("Distance measure timeout in loaded blocks between [" + senderBlockPosition.getX() + ","
139+
+ senderBlockPosition.getY() + ","
140+
+ senderBlockPosition.getZ() + "] and ["
141+
+ receiverBlockPosition.getX() + ","
142+
+ receiverBlockPosition.getY() + ","
143+
+ receiverBlockPosition.getZ() + "]"
144+
+ " - blocks tested: " + enumerationCounter + "/" + obstructionBlocks.size());
145+
cancelled = true;
146+
break;
147+
}
148+
}
149+
150+
for (BlockPos currentBlockPos : unloadedBlocks) {
151+
var currentBlockState = level.getBlockState(currentBlockPos);
152+
if (!currentBlockState.isAir()) {
153+
var explosionResistance = currentBlockState.getBlock().getExplosionResistance();
154+
if (explosionResistance >= 100)
155+
explosionResistance /= 4;
156+
signalDegradation += Math.sqrt(explosionResistance) * 10.0 * diagonalCompensation;
157+
}
113158

114159
if (signalDegradation > receiveRange) {
115160
break;
116161
}
162+
enumerationCounter++;
163+
if (timer + 500 <= System.currentTimeMillis()) {
164+
log.warn("Distance measure timeout in unloaded blocks between [" + senderBlockPosition.getX() + ","
165+
+ senderBlockPosition.getY() + ","
166+
+ senderBlockPosition.getZ() + "] and ["
167+
+ receiverBlockPosition.getX() + ","
168+
+ receiverBlockPosition.getY() + ","
169+
+ receiverBlockPosition.getZ() + "]"
170+
+ " - blocks tested: " + enumerationCounter + "/" + unloadedBlocks.size());
171+
cancelled = true;
172+
break;
173+
}
174+
}
175+
176+
if (cancelled) {
177+
// Extrapolating the signal degradation for the rest of the path
178+
signalDegradation = ((signalDegradation - distance) / (double) enumerationCounter / obstructionBlocks.size()) + distance;
179+
} else {
180+
((WirelessModemPeripheral)sender).addCachedSignalDegradation(receiverBlockPosition, signalDegradation);
117181
}
118182

119-
((WirelessModemPeripheral)sender).addCachedSignalDegradation(receiverBlockPosition, signalDegradation);
120183
if (signalDegradation <= receiveRange) {
121-
receiver.receiveSameDimension(packet, Math.sqrt(distanceSq), receiveRange - signalDegradation);
184+
receiver.receiveSameDimension(packet, distance, receiveRange - signalDegradation);
122185
}
123186
}
124187
} else {

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ include(":forge")
5151

5252
include(":lints")
5353
include(":standalone")
54-
//include(":web")
54+
include(":web")
5555

5656
for (project in rootProject.children) {
5757
project.projectDir = file("projects/${project.name}")

0 commit comments

Comments
 (0)