Ticks, Player events, keybindings, all migrated to the new event driven system.

This commit is contained in:
Christian committed 2013-12-16 23:18:00 -05:00
1 parent 0b419ac79c
commit 32561265fc
19 files changed
+261 -677

No files matched your search

@@ -40,7 +40,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.DuplicateModsFoundException;
@@ -240,7 +239,6 @@ public class FMLClientHandler implements IFMLSidedHandler
// client.func_110436_a();
RenderingRegistry.instance().loadEntityRenderers((Map<Class<? extends Entity>, Render>)RenderManager.field_78727_a.field_78729_o);
loading = false;
KeyBindingRegistry.instance().uploadKeyBindingsToGame(client.field_71474_y);
}
@SuppressWarnings("unused")
@@ -12,9 +12,13 @@
package cpw.mods.fml.client.registry;
import org.apache.commons.lang3.ArrayUtils;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.tileentity.TileEntity;
public class ClientRegistry
@@ -39,4 +43,9 @@ public class ClientRegistry
TileEntityRendererDispatcher.field_147556_a.field_147559_m.put(tileEntityClass, specialRenderer);
specialRenderer.func_147497_a(TileEntityRendererDispatcher.field_147556_a);
}
public static void registerKeyBinding(KeyBinding key)
{
Minecraft.func_71410_x().field_71474_y.field_151456_ac = ArrayUtils.add(Minecraft.func_71410_x().field_71474_y.field_151456_ac, key);
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -18,11 +18,11 @@ import net.minecraft.world.IBlockAccess;
public interface ISimpleBlockRenderingHandler
{
public abstract void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer);
public abstract void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer);
public abstract boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer);
public abstract boolean shouldRender3DInInventory();
public abstract boolean shouldRender3DInInventory(int modelId);
public abstract int getRenderId();
}
@@ -1,203 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.registry;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Set;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.relauncher.Side;
public class KeyBindingRegistry
{
/**
* Register a KeyHandler to the game. This handler will be called on certain tick events
* if any of its key is inactive or has recently changed state
*
* @param handler
*/
public static void registerKeyBinding(KeyHandler handler) {
instance().keyHandlers.add(handler);
if (!handler.isDummy)
{
TickRegistry.registerTickHandler(handler, Side.CLIENT);
}
}
/**
* Extend this class to register a KeyBinding and recieve callback
* when the key binding is triggered
*
* @author cpw
*
*/
public static abstract class KeyHandler implements ITickHandler
{
protected KeyBinding[] keyBindings;
protected boolean[] keyDown;
protected boolean[] repeatings;
private boolean isDummy;
/**
* Pass an array of keybindings and a repeat flag for each one
*
* @param keyBindings
* @param repeatings
*/
public KeyHandler(KeyBinding[] keyBindings, boolean[] repeatings)
{
assert keyBindings.length == repeatings.length : "You need to pass two arrays of identical length";
this.keyBindings = keyBindings;
this.repeatings = repeatings;
this.keyDown = new boolean[keyBindings.length];
}
/**
* Register the keys into the system. You will do your own keyboard management elsewhere. No events will fire
* if you use this method
*
* @param keyBindings
*/
public KeyHandler(KeyBinding[] keyBindings)
{
this.keyBindings = keyBindings;
this.isDummy = true;
}
public KeyBinding[] getKeyBindings()
{
return this.keyBindings;
}
/**
* Not to be overridden - KeyBindings are tickhandlers under the covers
*/
@Override
public final void tickStart(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, false);
}
/**
* Not to be overridden - KeyBindings are tickhandlers under the covers
*/
@Override
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, true);
}
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
{
for (int i = 0; i < keyBindings.length; i++)
{
KeyBinding keyBinding = keyBindings[i];
int keyCode = keyBinding.func_151463_i();
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state != keyDown[i] || (state && repeatings[i]))
{
if (state)
{
keyDown(type, keyBinding, tickEnd, state!=keyDown[i]);
}
else
{
keyUp(type, keyBinding, tickEnd);
}
if (tickEnd)
{
keyDown[i] = state;
}
}
}
}
/**
* Called when the key is first in the down position on any tick from the {@link #ticks()}
* set. Will be called subsequently with isRepeat set to true
*
* @see #keyUp(EnumSet, KeyBinding, boolean)
*
* @param types the type(s) of tick that fired when this key was first down
* @param tickEnd was it an end or start tick which fired the key
* @param isRepeat is it a repeat key event
*/
public abstract void keyDown(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd, boolean isRepeat);
/**
* Fired once when the key changes state from down to up
*
* @see #keyDown(EnumSet, KeyBinding, boolean, boolean)
*
* @param types the type(s) of tick that fired when this key was first down
* @param tickEnd was it an end or start tick which fired the key
*/
public abstract void keyUp(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd);
/**
* This is the list of ticks for which the key binding should trigger. The only
* valid ticks are client side ticks, obviously.
*
* @see cpw.mods.fml.common.ITickHandler#ticks()
*/
public abstract EnumSet<TickType> ticks();
}
private static final KeyBindingRegistry INSTANCE = new KeyBindingRegistry();
private Set<KeyHandler> keyHandlers = Sets.newLinkedHashSet();
/**
* Deprecated as it should not be used by client code
* @return
*/
@Deprecated
public static KeyBindingRegistry instance()
{
return INSTANCE;
}
public void uploadKeyBindingsToGame(GameSettings settings)
{
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
for (KeyHandler key : keyHandlers)
{
for (KeyBinding kb : key.keyBindings)
{
harvestedBindings.add(kb);
}
}
KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]);
KeyBinding[] allKeys = new KeyBinding[settings.field_74324_K.length + modKeyBindings.length];
System.arraycopy(settings.field_74324_K, 0, allKeys, 0, settings.field_74324_K.length);
System.arraycopy(modKeyBindings, 0, allKeys, settings.field_74324_K.length, modKeyBindings.length);
settings.field_74324_K = allKeys;
settings.func_74300_a();
}
}
@@ -128,7 +128,7 @@ public class RenderingRegistry
public boolean renderItemAsFull3DBlock(int modelId)
{
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
return bri != null && bri.shouldRender3DInInventory();
return bri != null && bri.shouldRender3DInInventory(modelId);
}
public void loadEntityRenderers(Map<Class<? extends Entity>, Render> rendererMap)
@@ -12,17 +12,13 @@
package cpw.mods.fml.common;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
@@ -31,8 +27,10 @@ import net.minecraft.world.World;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
@@ -41,7 +39,11 @@ import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.common.eventhandler.EventBus;
import cpw.mods.fml.common.gameevent.InputEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.server.FMLServerHandler;
@@ -70,16 +72,23 @@ public class FMLCommonHandler
*/
private IFMLSidedHandler sidedDelegate;
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
private Class<?> forge;
private boolean noForge;
private List<String> brandings;
private List<String> brandingsNoMC;
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
private EventBus eventBus = new EventBus();
/**
* The FML event bus. Subscribe here for FML related events
*
* @return the event bus
*/
public EventBus bus()
{
return eventBus;
}
public void beginLoading(IFMLSidedHandler handler)
{
@@ -90,48 +99,6 @@ public class FMLCommonHandler
FMLLog.log("MinecraftForge", Level.INFO, "Completed early MinecraftForge initialization");
}
public void rescheduleTicks(Side side)
{
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
}
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
{
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
if (scheduledTicks.size()==0)
{
return;
}
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
ticksToRun.retainAll(ticks);
if (!ticksToRun.isEmpty())
{
ticker.tickStart(ticksToRun, data);
}
}
}
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
{
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
if (scheduledTicks.size()==0)
{
return;
}
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
ticksToRun.retainAll(ticks);
if (!ticksToRun.isEmpty())
{
ticker.tickEnd(ticksToRun, data);
}
}
}
/**
* @return the instance
*/
@@ -261,37 +228,28 @@ public class FMLCommonHandler
public void onPostServerTick()
{
tickEnd(EnumSet.of(TickType.SERVER), Side.SERVER);
bus().post(new TickEvent.ServerTickEvent(Phase.END));
}
/**
* Every tick just after world and other ticks occur
*/
public void onPostWorldTick(Object world)
public void onPostWorldTick(World world)
{
tickEnd(EnumSet.of(TickType.WORLD), Side.SERVER, world);
bus().post(new TickEvent.WorldTickEvent(Side.SERVER, Phase.END, world));
}
public void onPreServerTick()
{
tickStart(EnumSet.of(TickType.SERVER), Side.SERVER);
bus().post(new TickEvent.ServerTickEvent(Phase.START));
}
/**
* Every tick just before world and other ticks occur
*/
public void onPreWorldTick(Object world)
public void onPreWorldTick(World world)
{
tickStart(EnumSet.of(TickType.WORLD), Side.SERVER, world);
}
public void onWorldLoadTick(World[] worlds)
{
rescheduleTicks(Side.SERVER);
for (World w : worlds)
{
tickStart(EnumSet.of(TickType.WORLDLOAD), Side.SERVER, w);
}
bus().post(new TickEvent.WorldTickEvent(Side.SERVER, Phase.START, world));
}
public boolean handleServerAboutToStart(MinecraftServer server)
@@ -338,35 +296,32 @@ public class FMLCommonHandler
public void onPreClientTick()
{
tickStart(EnumSet.of(TickType.CLIENT), Side.CLIENT);
bus().post(new TickEvent.ClientTickEvent(Phase.START));
}
public void onPostClientTick()
{
tickEnd(EnumSet.of(TickType.CLIENT), Side.CLIENT);
bus().post(new TickEvent.ClientTickEvent(Phase.END));
}
public void onRenderTickStart(float timer)
{
tickStart(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
bus().post(new TickEvent.RenderTickEvent(Phase.START, timer));
}
public void onRenderTickEnd(float timer)
{
tickEnd(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
bus().post(new TickEvent.RenderTickEvent(Phase.END, timer));
}
public void onPlayerPreTick(EntityPlayer player)
{
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
tickStart(EnumSet.of(TickType.PLAYER), side, player);
bus().post(new TickEvent.PlayerTickEvent(Phase.START, player));
}
public void onPlayerPostTick(EntityPlayer player)
{
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
tickEnd(EnumSet.of(TickType.PLAYER), side, player);
bus().post(new TickEvent.PlayerTickEvent(Phase.START, player));
}
public void registerCrashCallable(ICrashCallable callable)
@@ -482,4 +437,34 @@ public class FMLCommonHandler
{
return sidedDelegate.getClientToServerNetworkManager();
}
public void fireMouseInput()
{
bus().post(new InputEvent.MouseInputEvent());
}
public void fireKeyInput()
{
bus().post(new InputEvent.KeyInputEvent());
}
public void firePlayerChangedDimensionEvent(EntityPlayer player, int fromDim, int toDim)
{
bus().post(new PlayerEvent.PlayerChangedDimensionEvent(player, fromDim, toDim));
}
public void firePlayerLoggedIn(EntityPlayer player)
{
bus().post(new PlayerEvent.PlayerLoggedInEvent(player));
}
public void firePlayerLoggedOut(EntityPlayer player)
{
bus().post(new PlayerEvent.PlayerLoggedOutEvent(player));
}
public void firePlayerRespawnEvent(EntityPlayer player)
{
bus().post(new PlayerEvent.PlayerRespawnEvent(player));
}
}
@@ -1,26 +0,0 @@
/*
* 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;
/**
* @author cpw
*
*/
public interface INetworkHandler
{
boolean onChat(Object... data);
void onPacket250Packet(Object... data);
void onServerLogin(Object handler);
}
@@ -1,30 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import net.minecraft.entity.player.EntityPlayer;
/**
* @author cpw
*
*/
public interface IPlayerTracker
{
void onPlayerLogin(EntityPlayer player);
void onPlayerLogout(EntityPlayer player);
void onPlayerChangedDimension(EntityPlayer player);
void onPlayerRespawn(EntityPlayer player);
}
@@ -1,24 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
public interface IScheduledTickHandler extends ITickHandler
{
/**
* Return the number of actual ticks that will pass
* before your next tick will fire. This will be called
* just after your last tick fired to compute the next delay.
* @return Time until next tick
*/
public int nextTickSpacing();
}
@@ -1,59 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
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
*
* Multiple ticks may fire simultaneously- you will only be called once with all the firing ticks
*
* @param type
* @param tickData
*/
public void tickStart(EnumSet<TickType> type, Object... tickData);
/**
* Called at the "end" phase of a tick
*
* Multiple ticks may fire simultaneously- you will only be called once with all the firing ticks
*
* @param type
* @param tickData
*/
public void tickEnd(EnumSet<TickType> type, Object... tickData);
/**
* Returns the list of ticks this tick handler is interested in receiving at the minute
*/
public EnumSet<TickType> ticks();
/**
* A profiling label for this tick handler
*/
public String getLabel();
}
@@ -1,55 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.EnumSet;
public class SingleIntervalHandler implements IScheduledTickHandler
{
private ITickHandler wrapped;
public SingleIntervalHandler(ITickHandler handler)
{
this.wrapped=handler;
}
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData)
{
wrapped.tickStart(type, tickData);
}
@Override
public void tickEnd(EnumSet<TickType> type, Object... tickData)
{
wrapped.tickEnd(type, tickData);
}
@Override
public EnumSet<TickType> ticks()
{
return wrapped.ticks();
}
@Override
public String getLabel()
{
return wrapped.getLabel();
}
@Override
public int nextTickSpacing()
{
return 1;
}
}
@@ -1,64 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.EnumSet;
public enum TickType {
/**
* Fired during the world evaluation loop
* server and client side
*
* arg 0 : The world that is ticking
*/
WORLD,
/**
* client side
* Fired during the render processing phase
* arg 0 : float "partial render time"
*/
RENDER,
/**
* server side
* Fired once as the world loads from disk
*/
WORLDLOAD,
/**
* client side only
* Fired once per client tick loop.
*/
CLIENT,
/**
* client and server side.
* Fired whenever the players update loop runs.
* arg 0 : the player
* arg 1 : the world the player is in
*/
PLAYER,
/**
* server side only.
* This is the server game tick.
* Fired once per tick loop on the server.
*/
SERVER;
/**
* Partner ticks that are also cancelled by returning false from onTickInGame
*/
public EnumSet<TickType> partnerTicks()
{
if (this==CLIENT) return EnumSet.of(RENDER);
if (this==RENDER) return EnumSet.of(CLIENT);
return EnumSet.noneOf(TickType.class);
}
}
@@ -0,0 +1,8 @@
package cpw.mods.fml.common.gameevent;
import cpw.mods.fml.common.eventhandler.Event;
public class InputEvent extends Event {
public static class MouseInputEvent extends InputEvent {}
public static class KeyInputEvent extends InputEvent {}
}
@@ -0,0 +1,44 @@
package cpw.mods.fml.common.gameevent;
import net.minecraft.entity.player.EntityPlayer;
import cpw.mods.fml.common.eventhandler.Event;
public class PlayerEvent extends Event {
public final EntityPlayer player;
private PlayerEvent(EntityPlayer player)
{
this.player = player;
}
public static class PlayerLoggedInEvent extends PlayerEvent {
public PlayerLoggedInEvent(EntityPlayer player)
{
super(player);
}
}
public static class PlayerLoggedOutEvent extends PlayerEvent {
public PlayerLoggedOutEvent(EntityPlayer player)
{
super(player);
}
}
public static class PlayerRespawnEvent extends PlayerEvent {
public PlayerRespawnEvent(EntityPlayer player)
{
super(player);
}
}
public static class PlayerChangedDimensionEvent extends PlayerEvent {
public final int fromDim;
public final int toDim;
public PlayerChangedDimensionEvent(EntityPlayer player, int fromDim, int toDim)
{
super(player);
this.fromDim = fromDim;
this.toDim = toDim;
}
}
}
@@ -0,0 +1,67 @@
package cpw.mods.fml.common.gameevent;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.relauncher.Side;
public class TickEvent extends Event {
private static enum Type {
WORLD, PLAYER, CLIENT, SERVER, RENDER;
}
public enum Phase {
START, END;
}
public final Type type;
public final Side side;
public final Phase phase;
public TickEvent(Type type, Side side, Phase phase)
{
this.type = type;
this.side = side;
this.phase = phase;
}
public static class ServerTickEvent extends TickEvent {
public ServerTickEvent(Phase phase)
{
super(Type.SERVER, Side.SERVER, phase);
}
}
public static class ClientTickEvent extends TickEvent {
public ClientTickEvent(Phase phase)
{
super(Type.CLIENT, Side.CLIENT, phase);
}
}
public static class WorldTickEvent extends TickEvent {
public final World world;
public WorldTickEvent(Side side, Phase phase, World world)
{
super(Type.WORLD, side, phase);
this.world = world;
}
}
public static class PlayerTickEvent extends TickEvent {
public final EntityPlayer player;
public PlayerTickEvent(Phase phase, EntityPlayer player)
{
super(Type.PLAYER, player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT, phase);
this.player = player;
}
}
public static class RenderTickEvent extends TickEvent {
public final float renderTickTime;
public RenderTickEvent(Phase phase, float renderTickTime)
{
super(Type.RENDER, Side.CLIENT, phase);
this.renderTickTime = renderTickTime;
}
}
}
@@ -1,112 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.registry;
import java.util.List;
import java.util.PriorityQueue;
import java.util.concurrent.atomic.AtomicLong;
import com.google.common.collect.Queues;
import cpw.mods.fml.common.IScheduledTickHandler;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.SingleIntervalHandler;
import cpw.mods.fml.relauncher.Side;
public class TickRegistry
{
/**
* We register our delegate here
* @param handler
*/
public static class TickQueueElement implements Comparable<TickQueueElement>
{
public TickQueueElement(IScheduledTickHandler ticker, long tickCounter)
{
this.ticker = ticker;
update(tickCounter);
}
@Override
public int compareTo(TickQueueElement o)
{
return (int)(next - o.next);
}
public void update(long tickCounter)
{
next = tickCounter + Math.max(ticker.nextTickSpacing(),1);
}
private long next;
public IScheduledTickHandler ticker;
public boolean scheduledNow(long tickCounter)
{
return tickCounter >= next;
}
}
private static PriorityQueue<TickQueueElement> clientTickHandlers = Queues.newPriorityQueue();
private static PriorityQueue<TickQueueElement> serverTickHandlers = Queues.newPriorityQueue();
private static AtomicLong clientTickCounter = new AtomicLong();
private static AtomicLong serverTickCounter = new AtomicLong();
public static void registerScheduledTickHandler(IScheduledTickHandler handler, Side side)
{
getQueue(side).add(new TickQueueElement(handler, getCounter(side).get()));
}
/**
* @param side the side to get the tick queue for
* @return the queue for the effective side
*/
private static PriorityQueue<TickQueueElement> getQueue(Side side)
{
return side.isClient() ? clientTickHandlers : serverTickHandlers;
}
private static AtomicLong getCounter(Side side)
{
return side.isClient() ? clientTickCounter : serverTickCounter;
}
public static void registerTickHandler(ITickHandler handler, Side side)
{
registerScheduledTickHandler(new SingleIntervalHandler(handler), side);
}
public static void updateTickQueue(List<IScheduledTickHandler> ticks, Side side)
{
synchronized (ticks)
{
ticks.clear();
long tick = getCounter(side).incrementAndGet();
PriorityQueue<TickQueueElement> tickHandlers = getQueue(side);
while (true)
{
if (tickHandlers.size()==0 || !tickHandlers.peek().scheduledNow(tick))
{
break;
}
TickRegistry.TickQueueElement tickQueueElement = tickHandlers.poll();
tickQueueElement.update(tick);
tickHandlers.offer(tickQueueElement);
ticks.add(tickQueueElement.ticker);
}
}
}
}