Do not allow recursive creation of multiblocks. (#4472)
This commit is contained in:
@@ -28,5 +28,11 @@ public interface IAECluster {
|
|||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if the cluster has been destroyed, but not yet removed from a
|
||||||
|
* tile entity. Usually true during destruction.
|
||||||
|
*/
|
||||||
|
boolean isDestroyed();
|
||||||
|
|
||||||
Iterator<IGridHost> getTiles();
|
Iterator<IGridHost> getTiles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package appeng.me.cluster;
|
package appeng.me.cluster;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -29,16 +31,39 @@ import appeng.util.Platform;
|
|||||||
|
|
||||||
public abstract class MBCalculator {
|
public abstract class MBCalculator {
|
||||||
|
|
||||||
|
private static WeakReference<IAECluster> modificationInProgress = new WeakReference<>(null);
|
||||||
|
|
||||||
private final IAEMultiBlock target;
|
private final IAEMultiBlock target;
|
||||||
|
|
||||||
public MBCalculator(final IAEMultiBlock t) {
|
public MBCalculator(final IAEMultiBlock t) {
|
||||||
this.target = t;
|
this.target = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void calculateMultiblock(final World world, final WorldCoord loc) {
|
public static void setModificationInProgress(IAECluster cluster) {
|
||||||
if (Platform.isClient()) {
|
IAECluster inProgress = modificationInProgress.get();
|
||||||
|
if (inProgress == cluster) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (inProgress != null && cluster != null) {
|
||||||
|
throw new IllegalStateException("A modification is already in-progress for: " + inProgress);
|
||||||
|
}
|
||||||
|
modificationInProgress = new WeakReference<>(cluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isModificationInProgress() {
|
||||||
|
return modificationInProgress.get() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateMultiblock(final World world, final WorldCoord loc) {
|
||||||
|
if (Platform.isClient() || isModificationInProgress()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IAECluster currentCluster = target.getCluster();
|
||||||
|
if (currentCluster != null && currentCluster.isDestroyed()) {
|
||||||
|
return; // If we're still part of a cluster that is in the process of being destroyed,
|
||||||
|
// don't recalc.
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final WorldCoord min = loc.copy();
|
final WorldCoord min = loc.copy();
|
||||||
@@ -67,6 +92,7 @@ public abstract class MBCalculator {
|
|||||||
if (this.checkMultiblockScale(min, max)) {
|
if (this.checkMultiblockScale(min, max)) {
|
||||||
if (this.verifyUnownedRegion(world, min, max)) {
|
if (this.verifyUnownedRegion(world, min, max)) {
|
||||||
IAECluster c = this.createCluster(world, min, max);
|
IAECluster c = this.createCluster(world, min, max);
|
||||||
|
setModificationInProgress(c);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!this.verifyInternalStructure(world, min, max)) {
|
if (!this.verifyInternalStructure(world, min, max)) {
|
||||||
@@ -94,6 +120,8 @@ public abstract class MBCalculator {
|
|||||||
}
|
}
|
||||||
} catch (final Throwable err) {
|
} catch (final Throwable err) {
|
||||||
AELog.debug(err);
|
AELog.debug(err);
|
||||||
|
} finally {
|
||||||
|
setModificationInProgress(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ import appeng.crafting.CraftingWatcher;
|
|||||||
import appeng.crafting.MECraftingInventory;
|
import appeng.crafting.MECraftingInventory;
|
||||||
import appeng.me.cache.CraftingGridCache;
|
import appeng.me.cache.CraftingGridCache;
|
||||||
import appeng.me.cluster.IAECluster;
|
import appeng.me.cluster.IAECluster;
|
||||||
|
import appeng.me.cluster.MBCalculator;
|
||||||
import appeng.me.helpers.MachineSource;
|
import appeng.me.helpers.MachineSource;
|
||||||
import appeng.tile.crafting.CraftingMonitorTileEntity;
|
import appeng.tile.crafting.CraftingMonitorTileEntity;
|
||||||
import appeng.tile.crafting.CraftingTileEntity;
|
import appeng.tile.crafting.CraftingTileEntity;
|
||||||
@@ -119,6 +120,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
|
|||||||
this.max = max;
|
this.max = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isDestroyed() {
|
public boolean isDestroyed() {
|
||||||
return this.isDestroyed;
|
return this.isDestroyed;
|
||||||
}
|
}
|
||||||
@@ -162,19 +164,24 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU {
|
|||||||
}
|
}
|
||||||
this.isDestroyed = true;
|
this.isDestroyed = true;
|
||||||
|
|
||||||
boolean posted = false;
|
MBCalculator.setModificationInProgress(this);
|
||||||
|
try {
|
||||||
|
boolean posted = false;
|
||||||
|
|
||||||
for (final CraftingTileEntity r : this.tiles) {
|
for (final CraftingTileEntity r : this.tiles) {
|
||||||
final IGridNode n = r.getActionableNode();
|
final IGridNode n = r.getActionableNode();
|
||||||
if (n != null && !posted) {
|
if (n != null && !posted) {
|
||||||
final IGrid g = n.getGrid();
|
final IGrid g = n.getGrid();
|
||||||
if (g != null) {
|
if (g != null) {
|
||||||
g.postEvent(new MENetworkCraftingCpuChange(n));
|
g.postEvent(new MENetworkCraftingCpuChange(n));
|
||||||
posted = true;
|
posted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
r.updateStatus(null);
|
r.updateStatus(null);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
MBCalculator.setModificationInProgress(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import appeng.core.AELog;
|
|||||||
import appeng.core.Api;
|
import appeng.core.Api;
|
||||||
import appeng.me.cache.helpers.ConnectionWrapper;
|
import appeng.me.cache.helpers.ConnectionWrapper;
|
||||||
import appeng.me.cluster.IAECluster;
|
import appeng.me.cluster.IAECluster;
|
||||||
|
import appeng.me.cluster.MBCalculator;
|
||||||
import appeng.tile.qnb.QuantumBridgeTileEntity;
|
import appeng.tile.qnb.QuantumBridgeTileEntity;
|
||||||
import appeng.util.iterators.ChainedIterator;
|
import appeng.util.iterators.ChainedIterator;
|
||||||
|
|
||||||
@@ -189,6 +190,11 @@ public class QuantumCluster implements ILocatable, IAECluster {
|
|||||||
return this.thisSide != 0;
|
return this.thisSide != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
return isDestroyed;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
if (this.isDestroyed) {
|
if (this.isDestroyed) {
|
||||||
@@ -196,24 +202,29 @@ public class QuantumCluster implements ILocatable, IAECluster {
|
|||||||
}
|
}
|
||||||
this.isDestroyed = true;
|
this.isDestroyed = true;
|
||||||
|
|
||||||
if (this.registered) {
|
MBCalculator.setModificationInProgress(this);
|
||||||
MinecraftForge.EVENT_BUS.unregister(this);
|
try {
|
||||||
this.registered = false;
|
if (this.registered) {
|
||||||
|
MinecraftForge.EVENT_BUS.unregister(this);
|
||||||
|
this.registered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.thisSide != 0) {
|
||||||
|
this.updateStatus(true);
|
||||||
|
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.center.updateStatus(null, (byte) -1, this.isUpdateStatus());
|
||||||
|
|
||||||
|
for (final QuantumBridgeTileEntity r : this.getRing()) {
|
||||||
|
r.updateStatus(null, (byte) -1, this.isUpdateStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.center = null;
|
||||||
|
this.setRing(new QuantumBridgeTileEntity[8]);
|
||||||
|
} finally {
|
||||||
|
MBCalculator.setModificationInProgress(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.thisSide != 0) {
|
|
||||||
this.updateStatus(true);
|
|
||||||
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.center.updateStatus(null, (byte) -1, this.isUpdateStatus());
|
|
||||||
|
|
||||||
for (final QuantumBridgeTileEntity r : this.getRing()) {
|
|
||||||
r.updateStatus(null, (byte) -1, this.isUpdateStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.center = null;
|
|
||||||
this.setRing(new QuantumBridgeTileEntity[8]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.List;
|
|||||||
import appeng.api.networking.IGridHost;
|
import appeng.api.networking.IGridHost;
|
||||||
import appeng.api.util.DimensionalCoord;
|
import appeng.api.util.DimensionalCoord;
|
||||||
import appeng.me.cluster.IAECluster;
|
import appeng.me.cluster.IAECluster;
|
||||||
|
import appeng.me.cluster.MBCalculator;
|
||||||
import appeng.tile.spatial.SpatialPylonTileEntity;
|
import appeng.tile.spatial.SpatialPylonTileEntity;
|
||||||
|
|
||||||
public class SpatialPylonCluster implements IAECluster {
|
public class SpatialPylonCluster implements IAECluster {
|
||||||
@@ -59,6 +60,11 @@ public class SpatialPylonCluster implements IAECluster {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
return isDestroyed;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|
||||||
@@ -67,8 +73,13 @@ public class SpatialPylonCluster implements IAECluster {
|
|||||||
}
|
}
|
||||||
this.isDestroyed = true;
|
this.isDestroyed = true;
|
||||||
|
|
||||||
for (final SpatialPylonTileEntity r : this.getLine()) {
|
MBCalculator.setModificationInProgress(this);
|
||||||
r.updateStatus(null);
|
try {
|
||||||
|
for (final SpatialPylonTileEntity r : this.getLine()) {
|
||||||
|
r.updateStatus(null);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
MBCalculator.setModificationInProgress(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user