Slightly improve redstone link performance

This commit is contained in:
Snownee 2020-12-13 08:19:28 +08:00
parent 45465fb69b
commit 48d66c7e55
2 changed files with 32 additions and 24 deletions

View file

@ -1,8 +1,9 @@
package com.simibubi.create.content.logistics; package com.simibubi.create.content.logistics;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.IdentityHashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -20,14 +21,24 @@ import net.minecraft.world.World;
public class RedstoneLinkNetworkHandler { public class RedstoneLinkNetworkHandler {
static Map<IWorld, Map<Pair<Frequency, Frequency>, Set<LinkBehaviour>>> connections = new HashMap<>(); static final Map<IWorld, Map<Pair<Frequency, Frequency>, Set<LinkBehaviour>>> connections = new IdentityHashMap<>();
public static class Frequency { public static class Frequency {
public static final Frequency EMPTY = new Frequency(ItemStack.EMPTY);
private static final Map<Item, Frequency> simpleFrequencies = new IdentityHashMap<>();
private ItemStack stack; private ItemStack stack;
private Item item; private Item item;
private int color; private int color;
public Frequency(ItemStack stack) { public static Frequency of(ItemStack stack) {
if (stack.isEmpty())
return EMPTY;
if (!stack.hasTag())
return simpleFrequencies.computeIfAbsent(stack.getItem(), $ -> new Frequency(stack));
return new Frequency(stack);
}
private Frequency(ItemStack stack) {
this.stack = stack; this.stack = stack;
item = stack.getItem(); item = stack.getItem();
CompoundNBT displayTag = stack.getChildTag("display"); CompoundNBT displayTag = stack.getChildTag("display");
@ -35,7 +46,7 @@ public class RedstoneLinkNetworkHandler {
} }
public ItemStack getStack() { public ItemStack getStack() {
return stack.copy(); return stack;
} }
@Override @Override
@ -45,6 +56,8 @@ public class RedstoneLinkNetworkHandler {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj)
return true;
return obj instanceof Frequency ? ((Frequency) obj).item == item && ((Frequency) obj).color == color return obj instanceof Frequency ? ((Frequency) obj).item == item && ((Frequency) obj).color == color
: false; : false;
} }
@ -65,7 +78,7 @@ public class RedstoneLinkNetworkHandler {
Map<Pair<Frequency, Frequency>, Set<LinkBehaviour>> networksInWorld = networksIn(actor.getWorld()); Map<Pair<Frequency, Frequency>, Set<LinkBehaviour>> networksInWorld = networksIn(actor.getWorld());
Pair<Frequency, Frequency> key = actor.getNetworkKey(); Pair<Frequency, Frequency> key = actor.getNetworkKey();
if (!networksInWorld.containsKey(key)) if (!networksInWorld.containsKey(key))
networksInWorld.put(key, new HashSet<>()); networksInWorld.put(key, new LinkedHashSet<>());
return networksInWorld.get(key); return networksInWorld.get(key);
} }
@ -105,31 +118,26 @@ public class RedstoneLinkNetworkHandler {
} }
if (!withinRange(actor, other)) if (!withinRange(actor, other))
continue; continue;
power = Math.max(other.getTransmittedStrength(), power);
if (power == 15) if (power < 15)
break; power = Math.max(other.getTransmittedStrength(), power);
} }
// fix one-to-one loading order problem // fix one-to-one loading order problem
if(actor.isListening()){ if (actor.isListening()) {
actor.newPosition = true; actor.newPosition = true;
actor.updateReceiver(power); actor.updateReceiver(power);
} }
for (Iterator<LinkBehaviour> iterator = network.iterator(); iterator.hasNext();) { for (LinkBehaviour other : network) {
LinkBehaviour other = iterator.next(); if (other != actor && other.isListening() && withinRange(actor, other))
if (other.tileEntity.isRemoved()) {
iterator.remove();
continue;
}
if (!withinRange(actor, other))
continue;
if (other.isListening())
other.updateReceiver(power); other.updateReceiver(power);
} }
} }
public static boolean withinRange(LinkBehaviour from, LinkBehaviour to) { public static boolean withinRange(LinkBehaviour from, LinkBehaviour to) {
if (from == to)
return true;
return from.getPos().withinDistance(to.getPos(), AllConfigs.SERVER.logistics.linkRange.get()); return from.getPos().withinDistance(to.getPos(), AllConfigs.SERVER.logistics.linkRange.get());
} }

View file

@ -39,8 +39,8 @@ public class LinkBehaviour extends TileEntityBehaviour {
protected LinkBehaviour(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots) { protected LinkBehaviour(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots) {
super(te); super(te);
frequencyFirst = new Frequency(ItemStack.EMPTY); frequencyFirst = Frequency.EMPTY;
frequencyLast = new Frequency(ItemStack.EMPTY); frequencyLast = Frequency.EMPTY;
firstSlot = slots.getLeft(); firstSlot = slots.getLeft();
secondSlot = slots.getRight(); secondSlot = slots.getRight();
textShift = Vec3d.ZERO; textShift = Vec3d.ZERO;
@ -133,8 +133,8 @@ public class LinkBehaviour extends TileEntityBehaviour {
newPosition = positionInTag != positionKey; newPosition = positionInTag != positionKey;
super.read(nbt, clientPacket); super.read(nbt, clientPacket);
frequencyFirst = new Frequency(ItemStack.read(nbt.getCompound("FrequencyFirst"))); frequencyFirst = Frequency.of(ItemStack.read(nbt.getCompound("FrequencyFirst")));
frequencyLast = new Frequency(ItemStack.read(nbt.getCompound("FrequencyLast"))); frequencyLast = Frequency.of(ItemStack.read(nbt.getCompound("FrequencyLast")));
} }
public void setFrequency(boolean first, ItemStack stack) { public void setFrequency(boolean first, ItemStack stack) {
@ -148,9 +148,9 @@ public class LinkBehaviour extends TileEntityBehaviour {
getHandler().removeFromNetwork(this); getHandler().removeFromNetwork(this);
if (first) if (first)
frequencyFirst = new Frequency(stack); frequencyFirst = Frequency.of(stack);
else else
frequencyLast = new Frequency(stack); frequencyLast = Frequency.of(stack);
if (!changed) if (!changed)
return; return;