diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 25966e2526..7dcba72e6b 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -6,6 +6,8 @@ import gregtech.api.block.machines.BlockMachine; import gregtech.api.cover.CoverBehavior; import gregtech.api.gui.IUIHolder; +import gregtech.api.util.FirstTickScheduler; +import gregtech.api.util.FirstTickTask; import gregtech.api.util.GTControlledRegistry; import gregtech.api.util.GTLog; import net.minecraft.block.state.IBlockState; @@ -25,7 +27,7 @@ import java.util.List; import java.util.stream.Collectors; -public class MetaTileEntityHolder extends TickableTileEntityBase implements IUIHolder { +public class MetaTileEntityHolder extends TickableTileEntityBase implements IUIHolder, FirstTickTask { private MetaTileEntity metaTileEntity; private boolean needToUpdateLightning = false; @@ -215,8 +217,15 @@ public void markAsDirty() { @Override public void onLoad() { super.onLoad(); - if (metaTileEntity != null) { - metaTileEntity.onLoad(); + if (this.metaTileEntity != null) { + FirstTickScheduler.addTask(this); + } + } + + @Override + public void handleFirstTick() { + if (this.metaTileEntity != null) { + this.metaTileEntity.onLoad(); } } diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index bf125b603c..3810ae7dd6 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -8,6 +8,8 @@ import gregtech.api.pipenet.WorldPipeNet; import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.pipenet.block.IPipeType; +import gregtech.api.util.FirstTickScheduler; +import gregtech.api.util.FirstTickTask; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; @@ -23,7 +25,7 @@ import javax.annotation.Nullable; import java.util.function.Consumer; -public abstract class TileEntityPipeBase & IPipeType, NodeDataType> extends SyncedTileEntityBase implements IPipeTile { +public abstract class TileEntityPipeBase & IPipeType, NodeDataType> extends SyncedTileEntityBase implements IPipeTile, FirstTickTask { private TIntIntMap blockedConnectionsMap = new TIntIntHashMap(); private int blockedConnections = 0; @@ -283,6 +285,11 @@ public void readFromNBT(NBTTagCompound compound) { @Override public void onLoad() { super.onLoad(); + FirstTickScheduler.addTask(this); + } + + @Override + public void handleFirstTick() { this.coverableImplementation.onLoad(); } diff --git a/src/main/java/gregtech/api/util/FirstTickScheduler.java b/src/main/java/gregtech/api/util/FirstTickScheduler.java new file mode 100755 index 0000000000..bbebc42c93 --- /dev/null +++ b/src/main/java/gregtech/api/util/FirstTickScheduler.java @@ -0,0 +1,52 @@ +package gregtech.api.util; + +import java.util.Map; +import java.util.Queue; + +import com.google.common.collect.Maps; +import com.google.common.collect.Queues; + +import gregtech.api.GTValues; +import net.minecraft.world.World; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +@EventBusSubscriber(modid = GTValues.MODID) +public class FirstTickScheduler { + + private static Map> tasksByWorld = Maps.newConcurrentMap(); + + public static void addTask(final FirstTickTask task) { + final World world = task.getWorld(); + if (!world.isRemote) { + final Queue tasks = tasksByWorld.computeIfAbsent(world, k -> Queues.newConcurrentLinkedQueue()); + tasks.add(task); + } else { + task.handleFirstTick(); + } + } + + @SubscribeEvent + public static void onWorldUnload(final WorldEvent.Unload event) { + tasksByWorld.remove(event.getWorld()); + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public static void onWorldTick(TickEvent.WorldTickEvent event) { + if (event.phase == TickEvent.Phase.START) { + final Queue tasks = tasksByWorld.get(event.world); + if (tasks == null) { + return; + } + + FirstTickTask task = tasks.poll(); + while (task != null) { + task.handleFirstTick(); + task = tasks.poll(); + } + } + } +} diff --git a/src/main/java/gregtech/api/util/FirstTickTask.java b/src/main/java/gregtech/api/util/FirstTickTask.java new file mode 100755 index 0000000000..918cf8bf87 --- /dev/null +++ b/src/main/java/gregtech/api/util/FirstTickTask.java @@ -0,0 +1,10 @@ +package gregtech.api.util; + +import net.minecraft.world.World; + +public interface FirstTickTask { + + void handleFirstTick(); + + World getWorld(); +} \ No newline at end of file