package dev.lumareth.improvedAerodynamics.flight; import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.server.ServerStoppedEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Set; /** * Hands what the server thread collected during a tick over to the physics thread in one piece, at the end of the * tick. Warium pushes its forces while the physics thread is already consuming them, so without this a tick's * forces can end up split over several substeps or merged with the next tick's. */ public final class PhysicsBridge { /** Something that collects data on the server thread and hands it to the physics thread at the end of each tick. */ public interface Publishable { void publish(long tick); } private static final Set TOUCHED = Collections.newSetFromMap(new IdentityHashMap<>()); private static long tick; private static volatile long publishedTick; private PhysicsBridge() { } /** Marks a collector as having data for this tick. */ public static synchronized void touch(Publishable publishable) { TOUCHED.add(publishable); } /** * Tick number of the latest handover. Data published at an older tick is outdated: its ship received nothing in * the latest tick, so nothing should be applied anymore. */ public static long publishedTick() { return publishedTick; } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase != TickEvent.Phase.END) { return; } synchronized (PhysicsBridge.class) { tick++; for (Publishable publishable : TOUCHED) { publishable.publish(tick); } TOUCHED.clear(); publishedTick = tick; } } @SubscribeEvent public static void onServerStopped(ServerStoppedEvent event) { synchronized (PhysicsBridge.class) { TOUCHED.clear(); } } }