Fix issues related to ticking events

This commit is contained in:
DBotThePony 2021-09-10 12:19:31 +07:00
parent 65ee43fd11
commit 249cd46957
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 50 additions and 39 deletions

View File

@ -5,6 +5,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.InterModComms; import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
@ -14,7 +15,9 @@ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fmlserverevents.FMLServerAboutToStartEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartedEvent; import net.minecraftforge.fmlserverevents.FMLServerStartedEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartingEvent;
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent; import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -52,52 +55,46 @@ public class OverdriveThatMatters {
public static CreativeModeTab CREATIVE_TAB; public static CreativeModeTab CREATIVE_TAB;
private static final WeakHashMap<Level, Set<Supplier<Boolean>>> tick_until = new WeakHashMap<>(); // why no LinkedList?
// because you can't get nodes directly, which is vital in getting this thing working faster.
private static final WeakHashMap<Level, ArrayList<Supplier<Boolean>>> tick_until = new WeakHashMap<>();
private static final WeakHashMap<Level, ArrayList<Consumer<Level>>> tick_once = new WeakHashMap<>(); private static final WeakHashMap<Level, ArrayList<Consumer<Level>>> tick_once = new WeakHashMap<>();
@SubscribeEvent @SubscribeEvent(priority = EventPriority.HIGHEST)
public void onServerStarting(FMLServerStartedEvent event) { public void onServerStarting(FMLServerAboutToStartEvent event) {
tick_until.clear(); tick_until.clear();
} }
@SubscribeEvent @SubscribeEvent(priority = EventPriority.HIGHEST)
public void onServerStopping(FMLServerStoppingEvent event) { public void onServerStopping(FMLServerStoppingEvent event) {
tick_until.clear(); tick_until.clear();
} }
@SubscribeEvent @SubscribeEvent(priority = EventPriority.LOWEST)
public void onPreTick(TickEvent.WorldTickEvent event) { public void onPreTick(TickEvent.WorldTickEvent event) {
if (event.phase != TickEvent.Phase.START || event.side != LogicalSide.SERVER) if (event.phase != TickEvent.Phase.START || event.side != LogicalSide.SERVER)
return; return;
var set = tick_until.get(event.world); final var until = tick_until.get(event.world);
if (set != null) { if (until != null) {
ArrayList<Supplier<Boolean>> invalid = new ArrayList<>(); for (int i = until.size() - 1; i >= 0; i--) {
if (until.get(i).get()) {
for (var ticker : set) { until.remove(i);
if (ticker.get()) {
invalid.add(ticker);
} }
} }
if (invalid.size() != 0) { if (until.size() == 0) {
for (Supplier<Boolean> cell : invalid) {
set.remove(cell);
}
}
if (set.size() == 0) {
tick_until.remove(event.world); tick_until.remove(event.world);
} }
} }
var list = tick_once.get(event.world); final var once = tick_once.get(event.world);
if (list != null) { if (once != null) {
ArrayList<Supplier<Boolean>> invalid = new ArrayList<>(); ArrayList<Supplier<Boolean>> invalid = new ArrayList<>();
for (var ticker : list) { for (var ticker : once) {
ticker.accept(event.world); ticker.accept(event.world);
} }
@ -106,7 +103,7 @@ public class OverdriveThatMatters {
} }
public static void tickUntil(Level level, Supplier<Boolean> ticker) { public static void tickUntil(Level level, Supplier<Boolean> ticker) {
tick_until.computeIfAbsent(level, (k) -> new HashSet<>()).add(ticker); tick_until.computeIfAbsent(level, (k) -> new ArrayList<>()).add(ticker);
} }
public static void tickOnce(Level level, Consumer<Level> ticker) { public static void tickOnce(Level level, Consumer<Level> ticker) {

View File

@ -8,8 +8,10 @@ import net.minecraft.nbt.NbtIo;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartedEvent; import net.minecraftforge.fmlserverevents.FMLServerStartedEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartingEvent;
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent; import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -138,7 +140,7 @@ public class DrivePool {
} }
} }
@SubscribeEvent @SubscribeEvent(priority = EventPriority.LOWEST)
public static void onServerPostTick(TickEvent.ServerTickEvent event) { public static void onServerPostTick(TickEvent.ServerTickEvent event) {
if (event.phase == TickEvent.Phase.END) { if (event.phase == TickEvent.Phase.END) {
if (exception != null) { if (exception != null) {
@ -147,8 +149,8 @@ public class DrivePool {
} }
} }
@SubscribeEvent @SubscribeEvent(priority = EventPriority.HIGHEST)
public static void serverStartEvent(FMLServerStartedEvent event) { public static void serverStartEvent(FMLServerStartingEvent event) {
if (thread != null && thread.isAlive()) { if (thread != null && thread.isAlive()) {
LOGGER.error("FMLServerStartedEvent fired twice."); LOGGER.error("FMLServerStartedEvent fired twice.");
LOGGER.error("Attempting to start another DrivePool I/O thread when already running one!"); LOGGER.error("Attempting to start another DrivePool I/O thread when already running one!");
@ -166,7 +168,7 @@ public class DrivePool {
thread.start(); thread.start();
} }
@SubscribeEvent @SubscribeEvent(priority = EventPriority.HIGHEST)
public static void serverStopEvent(FMLServerStoppingEvent event) { public static void serverStopEvent(FMLServerStoppingEvent event) {
if (thread != null && thread.isAlive()) { if (thread != null && thread.isAlive()) {
stopping = true; stopping = true;

View File

@ -7,6 +7,7 @@ import net.minecraft.core.SectionPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterGrid;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -68,19 +69,25 @@ public interface IMatterGridCell extends IMatterGridListener {
BlockEntity get_entity = get_chunk.getBlockEntity(offset); BlockEntity get_entity = get_chunk.getBlockEntity(offset);
if (get_entity != this && get_entity instanceof IMatterGridCell cell) { if (get_entity != null) {
MatterGrid grid = cell.getMatterGrid(); final var cap = get_entity.getCapability(MatteryCapability.MATTER_CELL).resolve();
if (grid != null && grid != getMatterGrid()) { if (cap.isPresent()) {
if (getMatterGrid() == null) { final var cell = cap.get();
grid.track(this);
} else { MatterGrid grid = cell.getMatterGrid();
grid.mergeWith(getMatterGrid());
if (grid != null && grid != getMatterGrid()) {
if (getMatterGrid() == null) {
grid.track(this);
} else {
grid.mergeWith(getMatterGrid());
}
} }
}
if (cell.isValidMatterCell()) if (cell.isValidMatterCell())
onNeighbourMatterCell(pos, level, direction, cell); onNeighbourMatterCell(pos, level, direction, cell);
}
} }
} }

View File

@ -1,17 +1,22 @@
package ru.dbotthepony.mc.otm.matter; package ru.dbotthepony.mc.otm.matter;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.capability.matter.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.function.Predicate; import java.util.function.Predicate;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class MatterGrid implements IMatterGridListener { public class MatterGrid implements IMatterGridListener {
public static final Set<MatterGrid> NETWORKS = new HashSet<>(); public static final Set<MatterGrid> NETWORKS = new HashSet<>();
@ -19,7 +24,8 @@ public class MatterGrid implements IMatterGridListener {
private final Set<IMatterGridListener> listeners = new HashSet<>(); private final Set<IMatterGridListener> listeners = new HashSet<>();
public static void scheduleDiscoverNeighbours(IMatterGridCell cell, BlockPos pos, Level level) { public static void scheduleDiscoverNeighbours(IMatterGridCell cell, BlockPos pos, Level level) {
OverdriveThatMatters.tickUntil(level, () -> !cell.isValidMatterCell() || cell.connectOrCreateMatterGrid(pos, level, true)); if (level instanceof ServerLevel)
OverdriveThatMatters.tickUntil(level, () -> !cell.isValidMatterCell() || cell.connectOrCreateMatterGrid(pos, level, true));
} }
public MatterGrid() { public MatterGrid() {
@ -314,7 +320,6 @@ public class MatterGrid implements IMatterGridListener {
return null; return null;
} }
@Nullable
public boolean notifyTaskCompletion(MatterTask task) { public boolean notifyTaskCompletion(MatterTask task) {
validate(); validate();