From 11652d597fb7b5393367bf0881772db7538fa7f8 Mon Sep 17 00:00:00 2001 From: Christian Weeks Date: Thu, 7 Jun 2012 11:12:51 -0400 Subject: [PATCH] Expose a "clean" ticking interface and fix server tick loop for world ticks --- .../cpw/mods/fml/client/FMLClientHandler.java | 6 +- client/net/minecraft/src/BaseMod.java | 2 +- client/net/minecraft/src/ModLoader.java | 1 - .../cpw/mods/fml/common/FMLCommonHandler.java | 33 +++++++-- common/cpw/mods/fml/common/ITickHandler.java | 52 +++++++++++++ common/cpw/mods/fml/common/ModContainer.java | 19 ----- common/cpw/mods/fml/common/TickType.java | 74 +++++++++++++++++++ .../mods/fml/common/modloader/BaseMod.java | 2 +- .../fml/common/modloader/ModLoaderHelper.java | 2 +- .../modloader/ModLoaderModContainer.java | 2 +- .../server/MinecraftServer.java.patch | 31 ++++---- .../cpw/mods/fml/server/FMLServerHandler.java | 8 +- server/net/minecraft/src/BaseMod.java | 2 +- server/net/minecraft/src/ModLoader.java | 1 - 14 files changed, 179 insertions(+), 56 deletions(-) create mode 100644 common/cpw/mods/fml/common/ITickHandler.java create mode 100644 common/cpw/mods/fml/common/TickType.java diff --git a/client/cpw/mods/fml/client/FMLClientHandler.java b/client/cpw/mods/fml/client/FMLClientHandler.java index 38b2010ac9..16d78f2404 100644 --- a/client/cpw/mods/fml/client/FMLClientHandler.java +++ b/client/cpw/mods/fml/client/FMLClientHandler.java @@ -84,11 +84,11 @@ import cpw.mods.fml.common.IFMLSidedHandler; import cpw.mods.fml.common.IKeyHandler; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.ModContainer.TickType; import cpw.mods.fml.common.ModMetadata; import cpw.mods.fml.common.ProxyInjector; import cpw.mods.fml.common.ReflectionHelper; import cpw.mods.fml.common.Side; +import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.modloader.ModLoaderHelper; import cpw.mods.fml.common.modloader.ModLoaderModContainer; import cpw.mods.fml.common.modloader.ModProperty; @@ -266,7 +266,7 @@ public class FMLClientHandler implements IFMLSidedHandler public void onPreWorldTick() { if (client.field_6324_e != null) { - FMLCommonHandler.instance().worldTickStart(); + FMLCommonHandler.instance().worldTickStart(client.field_6324_e); FMLCommonHandler.instance().tickStart(TickType.WORLDGUI, 0.0f, client.field_6313_p); } } @@ -277,7 +277,7 @@ public class FMLClientHandler implements IFMLSidedHandler public void onPostWorldTick() { if (client.field_6324_e != null) { - FMLCommonHandler.instance().worldTickEnd(); + FMLCommonHandler.instance().worldTickEnd(client.field_6324_e); FMLCommonHandler.instance().tickEnd(TickType.WORLDGUI, 0.0f, client.field_6313_p); } for (IKeyHandler entry : keyHandlers) diff --git a/client/net/minecraft/src/BaseMod.java b/client/net/minecraft/src/BaseMod.java index f45fcf5860..cf60b1382e 100644 --- a/client/net/minecraft/src/BaseMod.java +++ b/client/net/minecraft/src/BaseMod.java @@ -24,7 +24,7 @@ import cpw.mods.fml.common.INetworkHandler; import cpw.mods.fml.common.IPickupNotifier; import cpw.mods.fml.common.IPlayerTracker; import cpw.mods.fml.common.IWorldGenerator; -import cpw.mods.fml.common.ModContainer.TickType; +import cpw.mods.fml.common.TickType; public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod { diff --git a/client/net/minecraft/src/ModLoader.java b/client/net/minecraft/src/ModLoader.java index 4b25c9d6d7..76e83a180f 100644 --- a/client/net/minecraft/src/ModLoader.java +++ b/client/net/minecraft/src/ModLoader.java @@ -26,7 +26,6 @@ import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.client.SpriteHelper; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer.TickType; import cpw.mods.fml.common.ReflectionHelper; import cpw.mods.fml.common.modloader.ModLoaderHelper; import cpw.mods.fml.common.modloader.ModLoaderModContainer; diff --git a/common/cpw/mods/fml/common/FMLCommonHandler.java b/common/cpw/mods/fml/common/FMLCommonHandler.java index 108cc12a4b..23e7ecc7f8 100644 --- a/common/cpw/mods/fml/common/FMLCommonHandler.java +++ b/common/cpw/mods/fml/common/FMLCommonHandler.java @@ -35,7 +35,6 @@ import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import cpw.mods.fml.common.ModContainer.SourceType; -import cpw.mods.fml.common.ModContainer.TickType; /** * The main class for non-obfuscated hook handling code @@ -79,6 +78,8 @@ public class FMLCommonHandler private List auxilliaryContainers = new ArrayList(); private Map modLanguageData=new HashMap(); + + private SettickHandlers = new HashSet(); /** * We register our delegate here * @param handler @@ -91,17 +92,17 @@ public class FMLCommonHandler /** * Pre-tick the mods */ - public void worldTickStart() + public void worldTickStart(Object world) { - tickStart(ModContainer.TickType.WORLD,0.0f); + tickStart(TickType.WORLD,0.0f, world); } /** * Post-tick the mods */ - public void worldTickEnd() + public void worldTickEnd(Object world) { - tickEnd(ModContainer.TickType.WORLD,0.0f); + tickEnd(TickType.WORLD,0.0f); } public void tickStart(TickType type, Object ... data) @@ -120,6 +121,15 @@ public class FMLCommonHandler mod.tickStart(type, data); sidedDelegate.profileEnd(); } + for (ITickHandler ticker : tickHandlers) + { + if (ticker.ticks().contains(type)) + { + sidedDelegate.profileStart(ticker.getClass().getSimpleName()); + ticker.tickStart(type, data); + sidedDelegate.profileEnd(); + } + } sidedDelegate.profileEnd(); sidedDelegate.profileEnd(); } @@ -140,6 +150,15 @@ public class FMLCommonHandler mod.tickEnd(type, data); sidedDelegate.profileEnd(); } + for (ITickHandler ticker : tickHandlers) + { + if (ticker.ticks().contains(type)) + { + sidedDelegate.profileStart(ticker.getClass().getSimpleName()); + ticker.tickEnd(type, data); + sidedDelegate.profileEnd(); + } + } sidedDelegate.profileEnd(); sidedDelegate.profileEnd(); } @@ -515,4 +534,8 @@ public class FMLCommonHandler } } + public void registerTickHandler(ITickHandler handler) + { + tickHandlers.add(handler); + } } diff --git a/common/cpw/mods/fml/common/ITickHandler.java b/common/cpw/mods/fml/common/ITickHandler.java new file mode 100644 index 0000000000..51deb7fe5f --- /dev/null +++ b/common/cpw/mods/fml/common/ITickHandler.java @@ -0,0 +1,52 @@ +/* + * The FML Forge Mod Loader suite. + * Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package cpw.mods.fml.common; + +import java.util.EnumSet; + + +/** + * + * Tick handler for mods to implement and register through the TickRegistry + * + * The data available to each tick is documented in the TickType + * + * @author cpw + * + */ +public interface ITickHandler +{ + + /** + * Called at the "start" phase of a tick + * @param type + * @param tickData + */ + public void tickStart(TickType type, Object... tickData); + + /** + * Called at the "end" phase of a tick + * @param type + * @param tickData + */ + public void tickEnd(TickType type, Object... tickData); + + /** + * Returns the list of ticks this tick handler is interested in receiving at the minute + * + * @return + */ + public EnumSet ticks(); +} diff --git a/common/cpw/mods/fml/common/ModContainer.java b/common/cpw/mods/fml/common/ModContainer.java index 9c95b7f8fc..a5fe1d3fb1 100644 --- a/common/cpw/mods/fml/common/ModContainer.java +++ b/common/cpw/mods/fml/common/ModContainer.java @@ -14,7 +14,6 @@ package cpw.mods.fml.common; import java.io.File; -import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -203,24 +202,6 @@ public interface ModContainer IPlayerTracker getPlayerTracker(); - public enum TickType { - WORLD, RENDER, GUI, WORLDGUI,WORLDLOADTICK, GUILOADTICK; - - /** - * @return - */ - public EnumSet partnerTicks() - { - if (this==WORLD) return EnumSet.of(RENDER,WORLDLOADTICK); - if (this==RENDER) return EnumSet.of(WORLD, WORLDLOADTICK); - if (this==GUI) return EnumSet.of(WORLDGUI, GUILOADTICK); - if (this==WORLDGUI) return EnumSet.of(GUI, GUILOADTICK); - if (this==WORLDLOADTICK) return EnumSet.of(WORLD, RENDER); - if (this==GUILOADTICK) return EnumSet.of(GUI, WORLDGUI); - return null; - } - } - List getKeys(); SourceType getSourceType(); diff --git a/common/cpw/mods/fml/common/TickType.java b/common/cpw/mods/fml/common/TickType.java new file mode 100644 index 0000000000..ea3280b0fd --- /dev/null +++ b/common/cpw/mods/fml/common/TickType.java @@ -0,0 +1,74 @@ +/* + * The FML Forge Mod Loader suite. + * Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package cpw.mods.fml.common; + +import java.util.EnumSet; + +public enum TickType { + /** + * Fired during the world evaluation loop + * server and client side + * + * arg 0 : a float zero (the "render time") + * arg 1 : The world that is ticking + */ + WORLD, + /** + * client side + * Fired during the render processing phase + * arg 0 : float "partial render time" + */ + RENDER, + /** + * client side + * Fired during the render processing phase if a GUI is open + * arg 0 : float "partial render time" + * arg 1 : the open gui + */ + GUI, + /** + * client side + * Fired during the world evaluation loop if a gui is open + * arg 0 : The open gui + */ + WORLDGUI, + /** + * client side + * Fired once as the world loads from disk + */ + WORLDLOADTICK, + /** + * client side + * Fired once as the world loads from disk + * arg 0 : the open gui + */ + GUILOADTICK; + + /** + * Partner ticks that are also cancelled by returning false from onTickInGame + * + * @return + */ + public EnumSet partnerTicks() + { + if (this==WORLD) return EnumSet.of(RENDER,WORLDLOADTICK); + if (this==RENDER) return EnumSet.of(WORLD, WORLDLOADTICK); + if (this==GUI) return EnumSet.of(WORLDGUI, GUILOADTICK); + if (this==WORLDGUI) return EnumSet.of(GUI, GUILOADTICK); + if (this==WORLDLOADTICK) return EnumSet.of(WORLD, RENDER); + if (this==GUILOADTICK) return EnumSet.of(GUI, WORLDGUI); + return null; + } +} \ No newline at end of file diff --git a/common/cpw/mods/fml/common/modloader/BaseMod.java b/common/cpw/mods/fml/common/modloader/BaseMod.java index 247f584ddd..8ab4e107e3 100644 --- a/common/cpw/mods/fml/common/modloader/BaseMod.java +++ b/common/cpw/mods/fml/common/modloader/BaseMod.java @@ -23,7 +23,7 @@ import cpw.mods.fml.common.INetworkHandler; import cpw.mods.fml.common.IPickupNotifier; import cpw.mods.fml.common.IPlayerTracker; import cpw.mods.fml.common.IWorldGenerator; -import cpw.mods.fml.common.ModContainer.TickType; +import cpw.mods.fml.common.TickType; /** * diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java b/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java index 26006b5f10..14b2641a5f 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java @@ -19,7 +19,7 @@ import java.util.HashMap; import java.util.Map; import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.ModContainer.TickType; +import cpw.mods.fml.common.TickType; /** * @author cpw diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java index e291829d8b..5403ae2f80 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java @@ -45,9 +45,9 @@ import cpw.mods.fml.common.LoaderException; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModContainer.ModState; import cpw.mods.fml.common.ModContainer.SourceType; -import cpw.mods.fml.common.ModContainer.TickType; import cpw.mods.fml.common.ModMetadata; import cpw.mods.fml.common.ProxyInjector; +import cpw.mods.fml.common.TickType; public class ModLoaderModContainer implements ModContainer { diff --git a/patches/minecraft_server/net/minecraft/server/MinecraftServer.java.patch b/patches/minecraft_server/net/minecraft/server/MinecraftServer.java.patch index b398c901be..f7864feed1 100644 --- a/patches/minecraft_server/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/minecraft_server/net/minecraft/server/MinecraftServer.java.patch @@ -1,15 +1,16 @@ --- ../src-base/minecraft_server/net/minecraft/server/MinecraftServer.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src-work/minecraft_server/net/minecraft/server/MinecraftServer.java 0000-00-00 00:00:00.000000000 -0000 -@@ -13,6 +13,8 @@ +@@ -13,6 +13,9 @@ import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; + ++import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.server.FMLServerHandler; import net.minecraft.src.AnvilSaveConverter; import net.minecraft.src.AnvilSaveHandler; import net.minecraft.src.AxisAlignedBB; -@@ -100,6 +102,7 @@ +@@ -100,6 +103,7 @@ var1.start(); ConsoleLogManager.func_641_a(); field_6038_a.info("Starting minecraft server version 1.2.5"); @@ -17,7 +18,7 @@ if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { -@@ -146,6 +149,7 @@ +@@ -146,6 +150,7 @@ field_6038_a.warning("To change this, set \"online-mode\" to \"true\" in the server.settings file."); } @@ -25,19 +26,13 @@ this.field_6033_f = new ServerConfigurationManager(this); this.field_6028_k[0] = new EntityTracker(this, 0); this.field_6028_k[1] = new EntityTracker(this, -1); -@@ -370,6 +374,7 @@ - var7 = 0L; - } - -+ FMLServerHandler.instance().onPreTick(); - var3 += var7; - var1 = var5; - -@@ -386,6 +391,7 @@ - this.func_6018_h(); - } - } -+ FMLServerHandler.instance().onPostTick(); +@@ -487,7 +492,9 @@ + this.field_6033_f.func_28169_a(new Packet4UpdateTime(var7.func_22080_k()), var7.field_4272_q.field_6165_g); } - } - else + ++ FMLServerHandler.instance().onPreWorldTick(var7); + var7.func_22077_g(); ++ FMLServerHandler.instance().onPostWorldTick(var7); + + while (true) + { diff --git a/server/cpw/mods/fml/server/FMLServerHandler.java b/server/cpw/mods/fml/server/FMLServerHandler.java index b85741871a..acdcda3315 100644 --- a/server/cpw/mods/fml/server/FMLServerHandler.java +++ b/server/cpw/mods/fml/server/FMLServerHandler.java @@ -148,17 +148,17 @@ public class FMLServerHandler implements IFMLSidedHandler /** * Every tick just before world and other ticks occur */ - public void onPreTick() + public void onPreWorldTick(World world) { - FMLCommonHandler.instance().worldTickStart(); + FMLCommonHandler.instance().worldTickStart(world); } /** * Every tick just after world and other ticks occur */ - public void onPostTick() + public void onPostWorldTick(World world) { - FMLCommonHandler.instance().worldTickEnd(); + FMLCommonHandler.instance().worldTickEnd(world); } /** diff --git a/server/net/minecraft/src/BaseMod.java b/server/net/minecraft/src/BaseMod.java index 9b3bac08ef..f330d2f48d 100644 --- a/server/net/minecraft/src/BaseMod.java +++ b/server/net/minecraft/src/BaseMod.java @@ -23,7 +23,7 @@ import cpw.mods.fml.common.INetworkHandler; import cpw.mods.fml.common.IPickupNotifier; import cpw.mods.fml.common.IPlayerTracker; import cpw.mods.fml.common.IWorldGenerator; -import cpw.mods.fml.common.ModContainer.TickType; +import cpw.mods.fml.common.TickType; public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod { diff --git a/server/net/minecraft/src/ModLoader.java b/server/net/minecraft/src/ModLoader.java index 9190e9407a..81e95e51f0 100644 --- a/server/net/minecraft/src/ModLoader.java +++ b/server/net/minecraft/src/ModLoader.java @@ -20,7 +20,6 @@ import java.util.logging.Logger; import net.minecraft.server.MinecraftServer; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer.TickType; import cpw.mods.fml.common.ReflectionHelper; import cpw.mods.fml.common.modloader.ModLoaderHelper; import cpw.mods.fml.common.modloader.ModLoaderModContainer;