diff --git a/src/main/java/appeng/core/AppEng.java b/src/main/java/appeng/core/AppEng.java index 1c5945134..aab74c841 100644 --- a/src/main/java/appeng/core/AppEng.java +++ b/src/main/java/appeng/core/AppEng.java @@ -115,7 +115,7 @@ public final class AppEng { ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC); - proxy = DistExecutor.runForDist(() -> ClientHelper::new, () -> ServerHelper::new); + proxy = DistExecutor.safeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new); CrashReportExtender.registerCrashCallable(new ModCrashEnhancement()); @@ -136,15 +136,14 @@ public final class AppEng { modEventBus.addGenericListener(ModDimension.class, registration::registerModDimension); modEventBus.addListener(Integrations::enqueueIMC); - modEventBus.addListener(this::commonSetup); // Register client-only events DistExecutor.runWhenOn(Dist.CLIENT, () -> registration::registerClientEvents); DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> modEventBus.addListener(this::clientSetup)); - MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::unloadWorld); - MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::onTick); + TickHandler.setup(MinecraftForge.EVENT_BUS); + MinecraftForge.EVENT_BUS.addListener(this::onServerAboutToStart); MinecraftForge.EVENT_BUS.addListener(this::serverStopped); MinecraftForge.EVENT_BUS.addListener(this::serverStopping); @@ -154,7 +153,6 @@ public final class AppEng { } private void commonSetup(FMLCommonSetupEvent event) { - ApiDefinitions definitions = Api.INSTANCE.definitions(); definitions.getRegistry().getBootstrapComponents(IInitComponent.class) .forEachRemaining(IInitComponent::initialize); @@ -300,7 +298,7 @@ public final class AppEng { private void serverStopped(final FMLServerStoppedEvent event) { WorldData.instance().onServerStoppped(); - TickHandler.INSTANCE.shutdown(); + TickHandler.instance().shutdown(); } } diff --git a/src/main/java/appeng/core/sync/packets/PaintedEntityPacket.java b/src/main/java/appeng/core/sync/packets/PaintedEntityPacket.java index a5dbeea92..4aa939e72 100644 --- a/src/main/java/appeng/core/sync/packets/PaintedEntityPacket.java +++ b/src/main/java/appeng/core/sync/packets/PaintedEntityPacket.java @@ -57,6 +57,6 @@ public class PaintedEntityPacket extends BasePacket { @Override public void clientPacketData(final INetworkInfo network, final PlayerEntity player) { final PlayerColor pc = new PlayerColor(this.entityId, this.myColor, this.ticks); - TickHandler.INSTANCE.getPlayerColors().put(this.entityId, pc); + TickHandler.instance().getPlayerColors().put(this.entityId, pc); } } diff --git a/src/main/java/appeng/crafting/CraftingJob.java b/src/main/java/appeng/crafting/CraftingJob.java index e6e8880cb..92bb0800b 100644 --- a/src/main/java/appeng/crafting/CraftingJob.java +++ b/src/main/java/appeng/crafting/CraftingJob.java @@ -125,7 +125,7 @@ public class CraftingJob implements Runnable, ICraftingJob { public void run() { try { try { - TickHandler.INSTANCE.registerCraftingSimulation(this.world, this); + TickHandler.instance().registerCraftingSimulation(this.world, this); this.handlePausing(); final Stopwatch timer = Stopwatch.createStarted(); diff --git a/src/main/java/appeng/debug/DebugCardItem.java b/src/main/java/appeng/debug/DebugCardItem.java index 287810531..87698cc8b 100644 --- a/src/main/java/appeng/debug/DebugCardItem.java +++ b/src/main/java/appeng/debug/DebugCardItem.java @@ -76,7 +76,7 @@ public class DebugCardItem extends AEBaseItem { int grids = 0; int totalNodes = 0; - for (final Grid g : TickHandler.INSTANCE.getGridList()) { + for (final Grid g : TickHandler.instance().getGridList()) { grids++; totalNodes += g.getNodes().size(); } diff --git a/src/main/java/appeng/hooks/TickHandler.java b/src/main/java/appeng/hooks/TickHandler.java index 4dec7cd21..cf8557375 100644 --- a/src/main/java/appeng/hooks/TickHandler.java +++ b/src/main/java/appeng/hooks/TickHandler.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.WeakHashMap; @@ -36,11 +37,15 @@ import com.google.common.collect.Multimap; import net.minecraft.world.IWorld; import net.minecraft.world.World; -import net.minecraftforge.event.TickEvent; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.Phase; -import net.minecraftforge.event.TickEvent.Type; +import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.TickEvent.WorldTickEvent; import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.DistExecutor.SafeRunnable; import appeng.api.networking.IGridNode; import appeng.api.parts.CableRenderMode; @@ -58,17 +63,39 @@ import appeng.util.Platform; public class TickHandler { - public static final TickHandler INSTANCE = new TickHandler(); + private static final TickHandler INSTANCE = new TickHandler(); private final Queue> serverQueue = new ArrayDeque<>(); private final Multimap craftingJobs = LinkedListMultimap.create(); - private final WeakHashMap>> callQueue = new WeakHashMap<>(); + private final Map>> callQueue = new WeakHashMap<>(); private final HandlerRep server = new HandlerRep(); private final HandlerRep client = new HandlerRep(); - private final HashMap cliPlayerColors = new HashMap<>(); - private final HashMap srvPlayerColors = new HashMap<>(); + private final Map cliPlayerColors = new HashMap<>(); + private final Map srvPlayerColors = new HashMap<>(); private CableRenderMode crm = CableRenderMode.STANDARD; - public HashMap getPlayerColors() { + public static TickHandler instance() { + return INSTANCE; + } + + public static void setup(IEventBus eventBus) { + eventBus.addListener(INSTANCE::onServerTick); + eventBus.addListener(INSTANCE::onWorldTick); + eventBus.addListener(INSTANCE::onUnloadWorld); + + // DistExecutor does not like functional interfaces + DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> new SafeRunnable() { + + private static final long serialVersionUID = 5221919736953944125L; + + @Override + public void run() { + eventBus.addListener(INSTANCE::onClientTick); + + } + }); + } + + public Map getPlayerColors() { if (Platform.isServer()) { return this.srvPlayerColors; } @@ -91,8 +118,8 @@ public class TickHandler { } public void addInit(final AEBaseTileEntity tile) { - if (Platform.isServer()) // for no there is no reason to care about this on the client... - { + // for no there is no reason to care about this on the client... + if (Platform.isServer()) { this.getRepo().tiles.add(tile); } } @@ -105,15 +132,15 @@ public class TickHandler { } public void addNetwork(final Grid grid) { - if (Platform.isServer()) // for no there is no reason to care about this on the client... - { + // for no there is no reason to care about this on the client... + if (Platform.isServer()) { this.getRepo().addNetwork(grid); } } public void removeNetwork(final Grid grid) { - if (Platform.isServer()) // for no there is no reason to care about this on the client... - { + // for no there is no reason to care about this on the client... + if (Platform.isServer()) { this.getRepo().removeNetwork(grid); } } @@ -126,9 +153,9 @@ public class TickHandler { this.getRepo().clear(); } - public void unloadWorld(final WorldEvent.Unload ev) { - if (Platform.isServer()) // for no there is no reason to care about this on the client... - { + public void onUnloadWorld(final WorldEvent.Unload ev) { + // for no there is no reason to care about this on the client... + if (Platform.isServer()) { final List toDestroy = new ArrayList<>(); this.getRepo().updateNetworks(); @@ -146,25 +173,36 @@ public class TickHandler { } } - public void onTick(final TickEvent ev) { - - if (ev.type == Type.CLIENT && ev.phase == Phase.START) { + public void onClientTick(final ClientTickEvent ev) { + if (ev.phase == Phase.START) { this.tickColors(this.cliPlayerColors); final CableRenderMode currentMode = Api.instance().partHelper().getCableRenderMode(); + if (currentMode != this.crm) { this.crm = currentMode; AppEng.proxy.triggerUpdates(); } } + } - if (ev.type == Type.WORLD && ev.phase == Phase.END) { - final WorldTickEvent wte = (WorldTickEvent) ev; + public void onWorldTick(final WorldTickEvent ev) { + if (ev.phase == Phase.START) { + final World world = ev.world; + final Queue> queue = this.callQueue.get(world); + this.processQueue(queue, world); + } + + if (ev.phase == Phase.END) { synchronized (this.craftingJobs) { - final Collection jobSet = this.craftingJobs.get(wte.world); + final Collection jobSet = this.craftingJobs.get(ev.world); + if (!jobSet.isEmpty()) { - final int simTime = Math.max(1, - AEConfig.instance().getCraftingCalculationTimePerTick() / jobSet.size()); + final int jobSize = jobSet.size(); + final int configTime = AEConfig.instance().getCraftingCalculationTimePerTick(); + final int simTime = Math.max(1, configTime / jobSize); + final Iterator i = jobSet.iterator(); + while (i.hasNext()) { final CraftingJob cj = i.next(); if (!cj.simulateFor(simTime)) { @@ -174,10 +212,12 @@ public class TickHandler { } } } + } - // for no there is no reason to care about this on the client... - else if (ev.type == Type.SERVER && ev.phase == Phase.END) { + public void onServerTick(final ServerTickEvent ev) { + if (ev.phase == Phase.END) { this.tickColors(this.srvPlayerColors); + // ready tiles. final HandlerRep repo = this.getRepo(); while (!repo.tiles.isEmpty()) { @@ -196,17 +236,17 @@ public class TickHandler { // cross world queue. this.processQueue(this.serverQueue, null); } + } - // world synced queue(s) - if (ev.type == Type.WORLD && ev.phase == Phase.START) { - final World world = ((WorldTickEvent) ev).world; - final Queue> queue = this.callQueue.get(world); - this.processQueue(queue, world); + public void registerCraftingSimulation(final World world, final CraftingJob craftingJob) { + synchronized (this.craftingJobs) { + this.craftingJobs.put(world, craftingJob); } } - private void tickColors(final HashMap playerSet) { + private void tickColors(final Map playerSet) { final Iterator i = playerSet.values().iterator(); + while (i.hasNext()) { final PlayerColor pc = i.next(); if (pc.ticksLeft <= 0) { @@ -235,16 +275,6 @@ public class TickHandler { AELog.debug(e); } } - - // long time = sw.elapsed( TimeUnit.MILLISECONDS ); - // if ( time > 0 ) - // AELog.info( "processQueue Time: " + time + "ms" ); - } - - public void registerCraftingSimulation(final World world, final CraftingJob craftingJob) { - synchronized (this.craftingJobs) { - this.craftingJobs.put(world, craftingJob); - } } private static class HandlerRep { diff --git a/src/main/java/appeng/items/tools/powered/MatterCannonItem.java b/src/main/java/appeng/items/tools/powered/MatterCannonItem.java index 6bcee53bb..7344c7f4b 100644 --- a/src/main/java/appeng/items/tools/powered/MatterCannonItem.java +++ b/src/main/java/appeng/items/tools/powered/MatterCannonItem.java @@ -244,7 +244,7 @@ public class MatterCannonItem extends AEBasePoweredItem implements IStorageCell< final int id = entityHit.getEntityId(); final PlayerColor marker = new PlayerColor(id, col, 20 * 30); - TickHandler.INSTANCE.getPlayerColors().put(id, marker); + TickHandler.instance().getPlayerColors().put(id, marker); if (entityHit instanceof SheepEntity) { final SheepEntity sh = (SheepEntity) entityHit; diff --git a/src/main/java/appeng/me/Grid.java b/src/main/java/appeng/me/Grid.java index 04d73e12f..98b22ccf7 100644 --- a/src/main/java/appeng/me/Grid.java +++ b/src/main/java/appeng/me/Grid.java @@ -64,7 +64,7 @@ public class Grid implements IGrid { this.postEvent(new MENetworkPostCacheConstruction()); - TickHandler.INSTANCE.addNetwork(this); + TickHandler.instance().addNetwork(this); center.setGrid(this); } @@ -112,7 +112,7 @@ public class Grid implements IGrid { this.pivot = (GridNode) n.next(); } else { this.pivot = null; - TickHandler.INSTANCE.removeNetwork(this); + TickHandler.instance().removeNetwork(this); this.myStorage.remove(); } } diff --git a/src/main/java/appeng/me/GridNode.java b/src/main/java/appeng/me/GridNode.java index 4c8a31c9c..8a9699a04 100644 --- a/src/main/java/appeng/me/GridNode.java +++ b/src/main/java/appeng/me/GridNode.java @@ -384,7 +384,7 @@ public class GridNode implements IGridNode, IPathItem { GridConnection.create(node, this, f.getOpposite()); } catch (SecurityConnectionException e) { AELog.debug(e); - TickHandler.INSTANCE.addCallable(node.getWorld(), new MachineSecurityBreak(this)); + TickHandler.instance().addCallable(node.getWorld(), new MachineSecurityBreak(this)); return; } catch (final FailedConnectionException e) { @@ -411,7 +411,7 @@ public class GridNode implements IGridNode, IPathItem { } catch (SecurityConnectionException e) { AELog.debug(e); - TickHandler.INSTANCE.addCallable(node.getWorld(), new MachineSecurityBreak(this)); + TickHandler.instance().addCallable(node.getWorld(), new MachineSecurityBreak(this)); return; } catch (final FailedConnectionException e) { diff --git a/src/main/java/appeng/me/helpers/AENetworkProxy.java b/src/main/java/appeng/me/helpers/AENetworkProxy.java index bc8dad360..57f7608a5 100644 --- a/src/main/java/appeng/me/helpers/AENetworkProxy.java +++ b/src/main/java/appeng/me/helpers/AENetworkProxy.java @@ -96,7 +96,7 @@ public class AENetworkProxy implements IGridBlock { public void validate() { if (this.gp instanceof AEBaseTileEntity) { - TickHandler.INSTANCE.addInit((AEBaseTileEntity) this.gp); + TickHandler.instance().addInit((AEBaseTileEntity) this.gp); } } diff --git a/src/main/java/appeng/parts/automation/AnnihilationPlanePart.java b/src/main/java/appeng/parts/automation/AnnihilationPlanePart.java index 0923fe811..bc843d9ed 100644 --- a/src/main/java/appeng/parts/automation/AnnihilationPlanePart.java +++ b/src/main/java/appeng/parts/automation/AnnihilationPlanePart.java @@ -408,7 +408,7 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab performBreakBlock(w, pos, blockState, energy, requiredPower, items); } else { this.breaking = true; - TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this); + TickHandler.instance().addCallable(this.getTile().getWorld(), this); } return TickRateModulation.URGENT; } diff --git a/src/main/java/appeng/parts/p2p/MEP2PTunnelPart.java b/src/main/java/appeng/parts/p2p/MEP2PTunnelPart.java index ca2c2f47b..c6fe6e5fb 100644 --- a/src/main/java/appeng/parts/p2p/MEP2PTunnelPart.java +++ b/src/main/java/appeng/parts/p2p/MEP2PTunnelPart.java @@ -138,14 +138,14 @@ public class MEP2PTunnelPart extends P2PTunnelPart implements I if (!this.getProxy().getPath().isNetworkBooting()) { if (!this.getProxy().getEnergy().isNetworkPowered()) { this.connection.markDestroy(); - TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this.connection); + TickHandler.instance().addCallable(this.getTile().getWorld(), this.connection); } else { if (this.getProxy().isActive()) { this.connection.markCreate(); - TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this.connection); + TickHandler.instance().addCallable(this.getTile().getWorld(), this.connection); } else { this.connection.markDestroy(); - TickHandler.INSTANCE.addCallable(this.getTile().getWorld(), this.connection); + TickHandler.instance().addCallable(this.getTile().getWorld(), this.connection); } } diff --git a/src/main/java/appeng/tile/AEBaseTileEntity.java b/src/main/java/appeng/tile/AEBaseTileEntity.java index 768d6b762..63a392f63 100644 --- a/src/main/java/appeng/tile/AEBaseTileEntity.java +++ b/src/main/java/appeng/tile/AEBaseTileEntity.java @@ -434,7 +434,7 @@ public class AEBaseTileEntity extends TileEntity implements IOrientable, ICommon if (this.world != null) { this.world.markChunkDirty(this.pos, this); if (!this.markDirtyQueued) { - TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick); + TickHandler.instance().addCallable(null, this::markDirtyAtEndOfTick); this.markDirtyQueued = true; } } diff --git a/src/main/java/appeng/tile/networking/CableBusTileEntity.java b/src/main/java/appeng/tile/networking/CableBusTileEntity.java index 22da703d4..09fd7fcca 100644 --- a/src/main/java/appeng/tile/networking/CableBusTileEntity.java +++ b/src/main/java/appeng/tile/networking/CableBusTileEntity.java @@ -124,7 +124,7 @@ public class CableBusTileEntity extends AEBaseTileEntity implements AEMultiTile @Override public void validate() { super.validate(); - TickHandler.INSTANCE.addInit(this); + TickHandler.instance().addInit(this); } @Override diff --git a/src/main/java/appeng/tile/spatial/SpatialIOPortTileEntity.java b/src/main/java/appeng/tile/spatial/SpatialIOPortTileEntity.java index b58658372..90398de0a 100644 --- a/src/main/java/appeng/tile/spatial/SpatialIOPortTileEntity.java +++ b/src/main/java/appeng/tile/spatial/SpatialIOPortTileEntity.java @@ -99,7 +99,7 @@ public class SpatialIOPortTileEntity extends AENetworkInvTileEntity implements I if (Platform.isServer()) { final ItemStack cell = this.inv.getStackInSlot(0); if (this.isSpatialCell(cell)) { - TickHandler.INSTANCE.addCallable(null, this);// this needs to be cross world synced. + TickHandler.instance().addCallable(null, this);// this needs to be cross world synced. } } } diff --git a/src/main/java/appeng/util/Platform.java b/src/main/java/appeng/util/Platform.java index 578f5cf93..12bfd17cd 100644 --- a/src/main/java/appeng/util/Platform.java +++ b/src/main/java/appeng/util/Platform.java @@ -1125,7 +1125,7 @@ public class Platform { public static void notifyBlocksOfNeighbors(final World world, final BlockPos pos) { if (!world.isRemote) { - TickHandler.INSTANCE.addCallable(world, new BlockUpdate(pos)); + TickHandler.instance().addCallable(world, new BlockUpdate(pos)); } }