diff options
author | Jason Mitchell <mitchej@gmail.com> | 2024-06-29 10:48:10 -0700 |
---|---|---|
committer | Jason Mitchell <mitchej+github@gmail.com> | 2024-07-09 21:38:05 -0700 |
commit | 59766c69f7622309075efd577c9543a8ac24c3f9 (patch) | |
tree | 1181f958421381e1a1464d1d004a9b7c849a7df3 /src/main/java/gregtech/api/multitileentity/multiblock/base | |
parent | 3724fbbcb67ee2566419654e31eb88eb5b7f88f6 (diff) | |
download | GT5-Unofficial-59766c69f7622309075efd577c9543a8ac24c3f9.tar.gz GT5-Unofficial-59766c69f7622309075efd577c9543a8ac24c3f9.tar.bz2 GT5-Unofficial-59766c69f7622309075efd577c9543a8ac24c3f9.zip |
MultiTileEntityBlock work
* Merge MultiTileEntityBlockRegistryInternal into MultiTileEntityBlock
* Add a hard dep on NEID for meta extension
* Use in world block meta for MuTE ID
* Use one block per MuTE Registry
* Add WeakTargetRef
* Migrate `controller` reference for parts over to a non non cachable WeakTargetRef
* Migrate controller WeakReference usage to WeakTargetRef
Diffstat (limited to 'src/main/java/gregtech/api/multitileentity/multiblock/base')
3 files changed, 103 insertions, 114 deletions
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java index 442d37a47a..552cf6d94e 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java @@ -4,11 +4,9 @@ import static gregtech.api.util.GT_Utility.moveMultipleItemStacks; import static gregtech.common.misc.WirelessNetworkManager.strongCheckOrAddUser; import static mcp.mobius.waila.api.SpecialChars.*; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -16,6 +14,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -31,6 +30,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.NotNull; import org.lwjgl.input.Keyboard; import com.gtnewhorizon.structurelib.StructureLibAPI; @@ -57,6 +57,7 @@ import gregtech.api.logic.FluidInventoryLogic; import gregtech.api.logic.ItemInventoryLogic; import gregtech.api.logic.MuTEProcessingLogic; import gregtech.api.logic.PowerLogic; +import gregtech.api.multitileentity.WeakTargetRef; import gregtech.api.multitileentity.enums.MultiTileCasingPurpose; import gregtech.api.multitileentity.interfaces.IMultiBlockController; import gregtech.api.multitileentity.interfaces.IMultiBlockPart; @@ -81,8 +82,8 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce protected static final int AUTO_OUTPUT_FREQUENCY_TICK = 20; private static final Map<Integer, GT_Multiblock_Tooltip_Builder> tooltip = new ConcurrentHashMap<>(); - private final List<UpgradeCasing> upgradeCasings = new ArrayList<>(); - private final List<FunctionalCasing> functionalCasings = new ArrayList<>(); + private final List<WeakTargetRef<UpgradeCasing>> upgradeCasings = new ArrayList<>(); + private final List<WeakTargetRef<FunctionalCasing>> functionalCasings = new ArrayList<>(); protected BuildState buildState = new BuildState(); private boolean structureOkay = false, structureChanged = false; @@ -104,20 +105,20 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce // A list of sides // Each side has a list of parts that have a cover that need to be ticked - protected List<LinkedList<WeakReference<IMultiBlockPart>>> registeredCoveredParts = Arrays.asList( - new LinkedList<>(), - new LinkedList<>(), - new LinkedList<>(), - new LinkedList<>(), - new LinkedList<>(), - new LinkedList<>()); + protected List<List<WeakTargetRef<IMultiBlockPart>>> registeredCoveredParts = Arrays.asList( + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>()); // A list for each purpose that a casing can register to, to be ticked - protected List<LinkedList<WeakReference<IMultiBlockPart>>> registeredTickableParts = new ArrayList<>(); + protected List<List<WeakTargetRef<IMultiBlockPart>>> registeredTickableParts = new ArrayList<>(); public Controller() { for (int i = 0; i < MultiTileCasingPurpose.values().length; i++) { - registeredTickableParts.add(new LinkedList<>()); + registeredTickableParts.add(new ArrayList<>()); } } @@ -157,11 +158,13 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce } protected void calculateTier() { - double sum = 0; - if (functionalCasings == null || functionalCasings.size() == 0) { + if (functionalCasings.size() == 0) { return; } - for (FunctionalCasing casing : functionalCasings) { + double sum = 0; + for (WeakTargetRef<FunctionalCasing> casingRef : functionalCasings) { + final FunctionalCasing casing = casingRef.get(); + if (casing == null) continue; sum += casing.getPartTier() * casing.getPartModifier(); } tier = (int) Math.min(Math.floor(sum / functionalCasings.size()), 14); @@ -432,17 +435,17 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce public void registerCoveredPartOnSide(final ForgeDirection side, IMultiBlockPart part) { if (side == ForgeDirection.UNKNOWN) return; - final LinkedList<WeakReference<IMultiBlockPart>> registeredCovers = registeredCoveredParts.get(side.ordinal()); + final List<WeakTargetRef<IMultiBlockPart>> registeredCovers = registeredCoveredParts.get(side.ordinal()); // TODO: Make sure that we're not already registered on this side - registeredCovers.add(new WeakReference<>(part)); + registeredCovers.add(new WeakTargetRef<>(part, true)); } @Override public void unregisterCoveredPartOnSide(final ForgeDirection side, IMultiBlockPart aPart) { if (side == ForgeDirection.UNKNOWN) return; - final LinkedList<WeakReference<IMultiBlockPart>> coveredParts = registeredCoveredParts.get(side.ordinal()); - final Iterator<WeakReference<IMultiBlockPart>> it = coveredParts.iterator(); + final List<WeakTargetRef<IMultiBlockPart>> coveredParts = registeredCoveredParts.get(side.ordinal()); + final Iterator<WeakTargetRef<IMultiBlockPart>> it = coveredParts.listIterator(); while (it.hasNext()) { final IMultiBlockPart part = (it.next()).get(); if (part == null || part == aPart) it.remove(); @@ -451,8 +454,8 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce @Override public void registerCaseWithPurpose(MultiTileCasingPurpose purpose, IMultiBlockPart part) { - final LinkedList<WeakReference<IMultiBlockPart>> tickableParts = registeredTickableParts.get(purpose.ordinal()); - final Iterator<WeakReference<IMultiBlockPart>> it = tickableParts.iterator(); + final List<WeakTargetRef<IMultiBlockPart>> tickableParts = registeredTickableParts.get(purpose.ordinal()); + final Iterator<WeakTargetRef<IMultiBlockPart>> it = tickableParts.listIterator(); while (it.hasNext()) { final IMultiBlockPart next = (it.next()).get(); if (next == null) { @@ -461,13 +464,13 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce return; } } - tickableParts.add(new WeakReference<>(part)); + tickableParts.add(new WeakTargetRef<>(part, true)); } @Override public void unregisterCaseWithPurpose(MultiTileCasingPurpose purpose, IMultiBlockPart part) { - final LinkedList<WeakReference<IMultiBlockPart>> tickableParts = registeredTickableParts.get(purpose.ordinal()); - final Iterator<WeakReference<IMultiBlockPart>> it = tickableParts.iterator(); + final List<WeakTargetRef<IMultiBlockPart>> tickableParts = registeredTickableParts.get(purpose.ordinal()); + final Iterator<WeakTargetRef<IMultiBlockPart>> it = tickableParts.listIterator(); while (it.hasNext()) { final IMultiBlockPart next = (it.next()).get(); if (next == null || next == part) it.remove(); @@ -487,9 +490,8 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce private boolean tickCovers() { for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { // TODO: Tick controller covers, if any - final LinkedList<WeakReference<IMultiBlockPart>> coveredParts = this.registeredCoveredParts - .get(side.ordinal()); - final Iterator<WeakReference<IMultiBlockPart>> it = coveredParts.iterator(); + final List<WeakTargetRef<IMultiBlockPart>> coveredParts = this.registeredCoveredParts.get(side.ordinal()); + final Iterator<WeakTargetRef<IMultiBlockPart>> it = coveredParts.listIterator(); while (it.hasNext()) { final IMultiBlockPart part = (it.next()).get(); if (part == null) { @@ -505,9 +507,7 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce @Override public void onTick(long tick, boolean isServerSide) { - if (!tickCovers()) { - return; - } + tickCovers(); } @Override @@ -535,9 +535,9 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce protected void pushItemOutputs(long tick) { if (tick % AUTO_OUTPUT_FREQUENCY_TICK != 0) return; - final LinkedList<WeakReference<IMultiBlockPart>> registeredItemOutputs = registeredTickableParts + final List<WeakTargetRef<IMultiBlockPart>> registeredItemOutputs = registeredTickableParts .get(MultiTileCasingPurpose.ItemOutput.ordinal()); - final Iterator<WeakReference<IMultiBlockPart>> itemOutputIterator = registeredItemOutputs.iterator(); + final Iterator<WeakTargetRef<IMultiBlockPart>> itemOutputIterator = registeredItemOutputs.listIterator(); while (itemOutputIterator.hasNext()) { final IMultiBlockPart part = (itemOutputIterator.next()).get(); if (part == null) { @@ -567,7 +567,8 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce (byte) 1, part.getSizeInventory()); for (int i = 0; i < part.getSizeInventory(); i++) { - if (part.getStackInSlot(i) != null && part.getStackInSlot(i).stackSize <= 0) { + final ItemStack stack = part.getStackInSlot(i); + if (stack != null && stack.stackSize <= 0) { part.setInventorySlotContents(i, null); } } @@ -577,9 +578,9 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce protected void pushFluidOutputs(long tick) { if (tick % AUTO_OUTPUT_FREQUENCY_TICK != 0) return; - final LinkedList<WeakReference<IMultiBlockPart>> registeredFluidOutputs = registeredTickableParts + final List<WeakTargetRef<IMultiBlockPart>> registeredFluidOutputs = registeredTickableParts .get(MultiTileCasingPurpose.FluidOutput.ordinal()); - final Iterator<WeakReference<IMultiBlockPart>> fluidOutputIterator = registeredFluidOutputs.iterator(); + final Iterator<WeakTargetRef<IMultiBlockPart>> fluidOutputIterator = registeredFluidOutputs.listIterator(); while (fluidOutputIterator.hasNext()) { final IMultiBlockPart part = (fluidOutputIterator.next()).get(); if (part == null) { @@ -694,11 +695,11 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce } public void registerSpecialCasings(MultiBlockPart part) { - if (part instanceof UpgradeCasing) { - upgradeCasings.add((UpgradeCasing) part); + if (part instanceof UpgradeCasing upgradeCasing) { + upgradeCasings.add(new WeakTargetRef<>(upgradeCasing, true)); } - if (part instanceof FunctionalCasing) { - functionalCasings.add((FunctionalCasing) part); + if (part instanceof FunctionalCasing functionalCasing) { + functionalCasings.add(new WeakTargetRef<>(functionalCasing, true)); } } @@ -715,12 +716,13 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce }; } - @Nullable - public FluidInventoryLogic getFluidLogic(@Nonnull InventoryType type, @Nullable UUID id) { + @Override + @Nonnull + public @NotNull FluidInventoryLogic getFluidLogic(@Nonnull InventoryType type, @Nullable UUID id) { return switch (type) { case Input -> controllerFluidInput.getInventoryLogic(id); case Output -> controllerFluidOutput.getInventoryLogic(id); - default -> null; + default -> throw new IllegalStateException("Unexpected value: " + type); }; } @@ -753,9 +755,8 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce FluidInventoryLogic input = controllerFluidInput.removeInventory(id); FluidInventoryLogic output = controllerFluidOutput.removeInventory(id); yield new FluidInventoryLogic( - Arrays.asList(input, output) - .stream() - .map(inv -> inv.getInventory()) + Stream.of(input, output) + .map(FluidInventoryLogic::getInventory) .collect(Collectors.toList())); } }; @@ -794,12 +795,12 @@ public abstract class Controller<C extends Controller<C, P>, P extends MuTEProce } @Override - @Nullable + @Nonnull public ItemInventoryLogic getItemLogic(@Nonnull InventoryType type, @Nullable UUID id) { return switch (type) { case Input -> controllerItemInput.getInventoryLogic(id); case Output -> controllerItemOutput.getInventoryLogic(id); - default -> null; + default -> throw new IllegalStateException("Unexpected value: " + type); }; } diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java index 2b030899ed..5a16ed4b38 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java @@ -48,6 +48,7 @@ import gregtech.api.logic.NullPowerLogic; import gregtech.api.logic.PowerLogic; import gregtech.api.logic.interfaces.PowerLogicHost; import gregtech.api.multitileentity.MultiTileEntityRegistry; +import gregtech.api.multitileentity.WeakTargetRef; import gregtech.api.multitileentity.base.NonTickableMultiTileEntity; import gregtech.api.multitileentity.enums.MultiTileCasingPurpose; import gregtech.api.multitileentity.interfaces.IMultiBlockController; @@ -70,7 +71,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity protected Set<MultiTileCasingPurpose> registeredPurposes = new HashSet<>(); - protected ChunkCoordinates targetPosition = null; + protected final WeakTargetRef<IMultiBlockController> controller = new WeakTargetRef<>( + IMultiBlockController.class, + false); protected int allowedModes = NOTHING; // BITMASK - Modes allowed for this part protected int mode = 0; // Mode selected for this part @@ -95,17 +98,17 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity return lockedInventory; } - public void setTarget(IMultiBlockController newTarget, int aAllowedModes) { - final IMultiBlockController currentTarget = getTarget(false); - if (currentTarget != null && currentTarget != newTarget) { + public void setTarget(IMultiBlockController newController, int aAllowedModes) { + final IMultiBlockController currentController = getTarget(false); + if (currentController != null && currentController != newController) { for (MultiTileCasingPurpose purpose : registeredPurposes) { unregisterPurpose(purpose); } } - targetPosition = (newTarget == null ? null : newTarget.getCoords()); + allowedModes = aAllowedModes; - if (newTarget != null) { - registerCovers(newTarget); + if (newController != currentController) { + registerCovers(newController); registerPurposes(); } } @@ -156,26 +159,11 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity } public IMultiBlockController getTarget(boolean aCheckValidity) { - if (targetPosition == null) { - return null; - } - - if (!worldObj.blockExists(targetPosition.posX, targetPosition.posY, targetPosition.posZ)) { - return null; - } - final TileEntity te = worldObj.getTileEntity(targetPosition.posX, targetPosition.posY, targetPosition.posZ); - IMultiBlockController target = null; - if (te instanceof IMultiBlockController targetFound) { - target = targetFound; - } else { - targetPosition = null; - return null; - } - - if (aCheckValidity) { - return target != null && target.checkStructure(false) ? target : null; + final IMultiBlockController res = controller.get(); + if (res != null && aCheckValidity) { + return res.checkStructure(false) ? res : null; } - return target; + return res; } public void registerCovers(IMultiBlockController controller) { @@ -232,10 +220,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity if (aNBT.hasKey(NBT.ALLOWED_MODES)) allowedModes = aNBT.getInteger(NBT.ALLOWED_MODES); if (aNBT.hasKey(NBT.MODE)) setMode(aNBT.getByte(NBT.MODE)); if (aNBT.hasKey(NBT.TARGET)) { - targetPosition = new ChunkCoordinates( - aNBT.getInteger(NBT.TARGET_X), - aNBT.getShort(NBT.TARGET_Y), - aNBT.getInteger(NBT.TARGET_Z)); + controller + .setPosition(aNBT.getInteger(NBT.TARGET_X), aNBT.getShort(NBT.TARGET_Y), aNBT.getInteger(NBT.TARGET_Z)); + controller.setWorld(worldObj); } if (aNBT.hasKey(NBT.LOCKED_INVENTORY)) { lockedInventory = UUID.fromString(aNBT.getString(NBT.LOCKED_INVENTORY)); @@ -255,27 +242,31 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity } @Override - public void writeMultiTileNBT(NBTTagCompound aNBT) { - if (allowedModes != NOTHING) aNBT.setInteger(NBT.ALLOWED_MODES, allowedModes); - if (mode != 0) aNBT.setInteger(NBT.MODE, mode); - if (targetPosition != null) { - aNBT.setBoolean(NBT.TARGET, true); - aNBT.setInteger(NBT.TARGET_X, targetPosition.posX); - aNBT.setShort(NBT.TARGET_Y, (short) targetPosition.posY); - aNBT.setInteger(NBT.TARGET_Z, targetPosition.posZ); + public void writeMultiTileNBT(NBTTagCompound nbt) { + if (allowedModes != NOTHING) nbt.setInteger(NBT.ALLOWED_MODES, allowedModes); + if (mode != 0) nbt.setInteger(NBT.MODE, mode); + + final ChunkCoordinates pos = controller.getPosition(); + if (pos.posY >= 0) { + // Valid position + nbt.setBoolean(NBT.TARGET, true); + nbt.setInteger(NBT.TARGET_X, pos.posX); + nbt.setShort(NBT.TARGET_Y, (short) pos.posY); + nbt.setInteger(NBT.TARGET_Z, pos.posZ); } + if (lockedInventory != null) { - aNBT.setString(NBT.LOCKED_INVENTORY, lockedInventory.toString()); + nbt.setString(NBT.LOCKED_INVENTORY, lockedInventory.toString()); } if (mLockedInventoryIndex != 0) { - aNBT.setInteger(NBT.LOCKED_INVENTORY_INDEX, mLockedInventoryIndex); + nbt.setInteger(NBT.LOCKED_INVENTORY_INDEX, mLockedInventoryIndex); } - configurationTank.writeToNBT(aNBT, NBT.LOCKED_FLUID); + configurationTank.writeToNBT(nbt, NBT.LOCKED_FLUID); } @Override - public void setLockedInventoryIndex(int aIndex) { - mLockedInventoryIndex = aIndex; + public void setLockedInventoryIndex(int index) { + mLockedInventoryIndex = index; } @Override @@ -284,15 +275,8 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity } @Override - public void setTargetPos(ChunkCoordinates aTargetPos) { - targetPosition = aTargetPos; - IMultiBlockController target = getTarget(false); - setTarget(target, allowedModes); - } - - @Override public ChunkCoordinates getTargetPos() { - return targetPosition; + return controller.getPosition(); } @Override diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/WallShareablePart.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/WallShareablePart.java index 7005e3a60a..238ce1eb2d 100644 --- a/src/main/java/gregtech/api/multitileentity/multiblock/base/WallShareablePart.java +++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/WallShareablePart.java @@ -8,32 +8,34 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ChunkCoordinates; import net.minecraftforge.common.util.ForgeDirection; +import gregtech.api.multitileentity.WeakTargetRef; import gregtech.api.multitileentity.interfaces.IMultiBlockController; public class WallShareablePart extends MultiBlockPart { - protected List<ChunkCoordinates> targetPositions = new ArrayList<>(); + protected List<WeakTargetRef<IMultiBlockController>> targets = new ArrayList<>(); @Override - public void setTarget(IMultiBlockController aTarget, int aAllowedModes) { - if (targetPositions.size() >= 1) { - allowedModes = 0; + public void setTarget(IMultiBlockController newController, int allowedModes) { + if (targets.size() >= 1) { + this.allowedModes = 0; setMode((byte) 0); - targetPosition = null; + controller.invalidate(); } else { - allowedModes = aAllowedModes; + this.allowedModes = allowedModes; + controller.setTarget(newController); } - if (aTarget == null) { + if (newController == null) { return; } - targetPositions.add(aTarget.getCoords()); + targets.add(new WeakTargetRef<IMultiBlockController>(IMultiBlockController.class, true)); } @Override public UUID getLockedInventory() { - if (targetPositions.size() > 1) { + if (targets.size() > 1) { return null; } return super.getLockedInventory(); @@ -41,11 +43,13 @@ public class WallShareablePart extends MultiBlockPart { @Override public IMultiBlockController getTarget(boolean aCheckValidity) { - if (targetPositions.size() != 1) { + if (targets.size() != 1) { return null; } - targetPosition = targetPositions.get(0); + controller.setTarget( + targets.get(0) + .get()); return super.getTarget(aCheckValidity); } @@ -56,8 +60,8 @@ public class WallShareablePart extends MultiBlockPart { @Override public boolean onBlockBroken() { - for (final ChunkCoordinates coordinates : targetPositions) { - IMultiBlockController target = getTarget(coordinates, false); + for (final WeakTargetRef<IMultiBlockController> tar : targets) { + IMultiBlockController target = getTarget(tar.getPosition(), false); if (target == null) { continue; } @@ -73,8 +77,8 @@ public class WallShareablePart extends MultiBlockPart { if (te instanceof MultiBlockPart part) { final IMultiBlockController tController = part.getTarget(false); if (tController != null) tController.onStructureChange(); - } else if (te instanceof IMultiBlockController controller) { - controller.onStructureChange(); + } else if (te instanceof IMultiBlockController tController) { + tController.onStructureChange(); } } } |