introduce new PipeEventBus, register pluggables in bus

This commit is contained in:
asiekierka 2014-12-15 23:25:36 +01:00
parent 778d76b136
commit 6ca2933490
11 changed files with 155 additions and 84 deletions

View file

@ -336,8 +336,8 @@ public class BlockGenericPipe extends BlockBuildCraft {
// pluggables
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
if (tileG.getPluggable(side) != null) {
AxisAlignedBB bb = tileG.getPluggable(side).getBoundingBox(side);
if (tileG.getPipePluggable(side) != null) {
AxisAlignedBB bb = tileG.getPipePluggable(side).getBoundingBox(side);
setBlockBounds(bb);
boxes[7 + side.ordinal()] = bb;
hits[7 + side.ordinal()] = super.collisionRayTrace(world, x, y, z, origin, direction);
@ -513,7 +513,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
switch (rayTraceResult.hitPart) {
case Pluggable: {
Pipe<?> pipe = getPipe(world, x, y, z);
IPipePluggable pluggable = pipe.container.getPluggable(rayTraceResult.sideHit);
IPipePluggable pluggable = pipe.container.getPipePluggable(rayTraceResult.sideHit);
if (pluggable instanceof FacadePluggable) {
ForgeDirection dir = ForgeDirection
.getOrientation(target.sideHit);
@ -677,7 +677,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
player);
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Pluggable
&& pipe.container.getPluggable(rayTraceResult.sideHit) instanceof RobotStationPluggable) {
&& pipe.container.getPipePluggable(rayTraceResult.sideHit) instanceof RobotStationPluggable) {
DockingStation station = pipe.container.getStation(rayTraceResult.sideHit);
if (!station.isTaken()) {
@ -721,7 +721,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
RaytraceResult rayTraceResult = doRayTrace(world, x, y, z, player);
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Pluggable
&& pipe.container.getPluggable(rayTraceResult.sideHit) instanceof GatePluggable) {
&& pipe.container.getPipePluggable(rayTraceResult.sideHit) instanceof GatePluggable) {
clickedGate = pipe.gates[rayTraceResult.sideHit.ordinal()];
}
@ -740,7 +740,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
RaytraceResult rayTraceResult = doRayTrace(world, x, y, z, player);
if (player.isSneaking()) {
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Pluggable
&& pipe.container.getPluggable(rayTraceResult.sideHit) instanceof GatePluggable) {
&& pipe.container.getPipePluggable(rayTraceResult.sideHit) instanceof GatePluggable) {
if (pipe.container.hasGate(rayTraceResult.sideHit)) {
return pipe.container.dropSideItems(rayTraceResult.sideHit);
}
@ -815,7 +815,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
RaytraceResult rayTraceResult = doRayTrace(world, x, y, z, player);
if (player.isSneaking()) {
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Pluggable
&& pipe.container.getPluggable(rayTraceResult.sideHit) instanceof FacadePluggable) {
&& pipe.container.getPipePluggable(rayTraceResult.sideHit) instanceof FacadePluggable) {
if (pipe.container.hasFacade(rayTraceResult.sideHit)) {
return pipe.container.dropSideItems(rayTraceResult.sideHit);
}
@ -844,7 +844,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
RaytraceResult rayTraceResult = doRayTrace(world, x, y, z, player);
if (player.isSneaking()) {
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Pluggable
&& pipe.container.getPluggable(rayTraceResult.sideHit) instanceof PlugPluggable) {
&& pipe.container.getPipePluggable(rayTraceResult.sideHit) instanceof PlugPluggable) {
if (pipe.container.dropSideItems(rayTraceResult.sideHit)) {
return true;
}
@ -862,7 +862,7 @@ public class BlockGenericPipe extends BlockBuildCraft {
RaytraceResult rayTraceResult = doRayTrace(world, x, y, z, player);
if (player.isSneaking()) {
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Pluggable
&& pipe.container.getPluggable(rayTraceResult.sideHit) instanceof RobotStationPluggable) {
&& pipe.container.getPipePluggable(rayTraceResult.sideHit) instanceof RobotStationPluggable) {
if (pipe.container.dropSideItems(rayTraceResult.sideHit)) {
return true;
}

View file

@ -40,6 +40,11 @@ public class FacadePluggable implements IPipePluggable {
return states == null ? null : new ItemStack[] { ItemFacade.getFacade(states) };
}
@Override
public void update(IPipeContainer pipe, ForgeDirection direction) {
}
@Override
public void onAttachedPipe(IPipeContainer pipe, ForgeDirection direction) {

View file

@ -56,7 +56,7 @@ public class ItemGateCopier extends ItemBuildCraft {
RaytraceResult rayTraceResult = ((BlockGenericPipe) block).doRayTrace(world, x, y, z, player);
if (rayTraceResult != null && rayTraceResult.boundingBox != null && rayTraceResult.hitPart == Part.Pluggable) {
IPipePluggable pluggable = ((TileGenericPipe) tile).getPluggable(rayTraceResult.sideHit);
IPipePluggable pluggable = ((TileGenericPipe) tile).getPipePluggable(rayTraceResult.sideHit);
if (pluggable instanceof GatePluggable) {
gate = ((TileGenericPipe) tile).pipe.gates[rayTraceResult.sideHit.ordinal()];
}

View file

@ -45,14 +45,13 @@ import buildcraft.transport.pipes.events.PipeEvent;
import buildcraft.transport.statements.ActionValve.ValveState;
public abstract class Pipe<T extends PipeTransport> implements IDropControlInventory, IPipe {
private static Map<Class<? extends Pipe>, Map<Class<? extends PipeEvent>, EventHandler>> eventHandlers = new HashMap<Class<? extends Pipe>, Map<Class<? extends PipeEvent>, EventHandler>>();
public int[] signalStrength = new int[]{0, 0, 0, 0};
public TileGenericPipe container;
public final T transport;
public final Item item;
public boolean[] wireSet = new boolean[]{false, false, false, false};
public final Gate[] gates = new Gate[ForgeDirection.VALID_DIRECTIONS.length];
public PipeEventBus eventBus = new PipeEventBus();
private boolean internalUpdateScheduled = false;
private boolean initialized = false;
@ -62,6 +61,8 @@ public abstract class Pipe<T extends PipeTransport> implements IDropControlInven
public Pipe(T transport, Item item) {
this.transport = transport;
this.item = item;
eventBus.registerHandler(this);
}
public void setTile(TileEntity tile) {
@ -77,60 +78,6 @@ public abstract class Pipe<T extends PipeTransport> implements IDropControlInven
}
}
// public final void handlePipeEvent(PipeEvent event) {
// try {
// Method method = getClass().getDeclaredMethod("eventHandler", event.getClass());
// method.invoke(this, event);
// } catch (Exception ex) {
// }
// }
private static class EventHandler {
public final Method method;
public EventHandler(Method method) {
this.method = method;
}
}
public final void handlePipeEvent(PipeEvent event) {
Map<Class<? extends PipeEvent>, EventHandler> handlerMap = eventHandlers.get(getClass());
if (handlerMap == null) {
handlerMap = new HashMap<Class<? extends PipeEvent>, EventHandler>();
eventHandlers.put(getClass(), handlerMap);
}
EventHandler handler = handlerMap.get(event.getClass());
if (handler == null) {
handler = makeEventHandler(event, handlerMap);
}
if (handler.method == null) {
return;
}
try {
handler.method.invoke(this, event);
} catch (Exception ex) {
}
}
private EventHandler makeEventHandler(PipeEvent event, Map<Class<? extends PipeEvent>, EventHandler> handlerMap) {
EventHandler handler;
try {
Method method = getClass().getDeclaredMethod("eventHandler", event.getClass());
handler = new EventHandler(method);
} catch (Exception ex) {
handler = new EventHandler(null);
}
handlerMap.put(event.getClass(), handler);
return handler;
}
public boolean blockActivated(EntityPlayer entityplayer) {
return false;
}
@ -495,8 +442,8 @@ public abstract class Pipe<T extends PipeTransport> implements IDropControlInven
}
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
if (container.hasPluggable(direction)) {
for (ItemStack stack : container.getPluggable(direction).getDropItems(container)) {
if (container.hasPipePluggable(direction)) {
for (ItemStack stack : container.getPipePluggable(direction).getDropItems(container)) {
result.add(stack);
}
}

View file

@ -0,0 +1,89 @@
package buildcraft.transport;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import buildcraft.transport.pipes.events.PipeEvent;
public class PipeEventBus {
private class EventHandler {
public Method method;
public Object owner;
public EventHandler(Method m, Object o) {
this.method = m;
this.owner = o;
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof EventHandler)) {
return false;
}
EventHandler e = (EventHandler) o;
return e.method.equals(method) && e.owner == owner;
}
}
private final HashSet<Object> registeredHandlers = new HashSet<Object>();
private final HashMap<Object, Map<Method, Class<? extends PipeEvent>>> handlerMethods = new HashMap<Object, Map<Method, Class<? extends PipeEvent>>>();
private final HashMap<Class<? extends PipeEvent>, List<EventHandler>> eventHandlers = new HashMap<Class<? extends PipeEvent>, List<EventHandler>>();
public PipeEventBus() {
}
private List<EventHandler> getHandlerList(Class<? extends PipeEvent> event) {
if (!eventHandlers.containsKey(event)) {
eventHandlers.put(event, new ArrayList<EventHandler>());
}
return eventHandlers.get(event);
}
public void registerHandler(Object handler) {
if (registeredHandlers.contains(handler)) {
return;
}
registeredHandlers.add(handler);
Map<Method, Class<? extends PipeEvent>> methods = new HashMap<Method, Class<? extends PipeEvent>>();
for (Method m: handler.getClass().getDeclaredMethods()) {
Class[] parameters = m.getParameterTypes();
if (parameters.length == 1 && PipeEvent.class.isAssignableFrom(parameters[0])) {
Class<? extends PipeEvent> eventType = (Class<? extends PipeEvent>) parameters[0];
List<EventHandler> eventHandlerList = getHandlerList(eventType);
eventHandlerList.add(new EventHandler(m, handler));
methods.put(m, eventType);
}
}
handlerMethods.put(handler, methods);
}
public void unregisterHandler(Object handler) {
if (!registeredHandlers.contains(handler)) {
return;
}
registeredHandlers.remove(handler);
Map<Method, Class<? extends PipeEvent>> methodMap = handlerMethods.get(handler);
for (Method m : methodMap.keySet()) {
getHandlerList(methodMap.get(m)).remove(new EventHandler(m, handler));
}
handlerMethods.remove(handler);
}
public void handleEvent(PipeEvent event) {
for (EventHandler eventHandler : getHandlerList(event.getClass())) {
try {
eventHandler.method.invoke(eventHandler.owner, event);
} catch (Exception e) {
}
}
}
}

View file

@ -52,7 +52,7 @@ public class PipeTransportItems extends PipeTransport {
public void readjustSpeed(TravelingItem item) {
PipeEventItem.AdjustSpeed event = new PipeEventItem.AdjustSpeed(item);
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
if (!event.handled) {
defaultReajustSpeed(item);
}
@ -103,7 +103,7 @@ public class PipeTransportItems extends PipeTransport {
}
PipeEventItem.Entered event = new PipeEventItem.Entered(item);
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
if (event.cancelled) {
return;
}
@ -166,7 +166,7 @@ public class PipeTransportItems extends PipeTransport {
}
PipeEventItem.Entered event = new PipeEventItem.Entered(item);
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
if (event.cancelled) {
return;
}
@ -207,7 +207,7 @@ public class PipeTransportItems extends PipeTransport {
}
PipeEventItem.FindDest event = new PipeEventItem.FindDest(item, result);
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
if (allowBouncing && result.isEmpty()) {
if (canReceivePipeObjects(item.input.getOpposite(), item)) {
@ -277,14 +277,14 @@ public class PipeTransportItems extends PipeTransport {
}
} else {
PipeEventItem.ReachedCenter event = new PipeEventItem.ReachedCenter(item);
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
}
} else if (!item.toCenter && endReached(item)) {
TileEntity tile = container.getTile(item.output);
PipeEventItem.ReachedEnd event = new PipeEventItem.ReachedEnd(item, tile);
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
boolean handleItem = !event.handled;
// If the item has not been scheduled to removal by the hook
@ -334,7 +334,7 @@ public class PipeTransportItems extends PipeTransport {
}
PipeEventItem.DropItem event = new PipeEventItem.DropItem(item, item.toEntityItem());
container.pipe.handlePipeEvent(event);
container.pipe.eventBus.handleEvent(event);
if (event.entity == null) {
return;

View file

@ -78,6 +78,11 @@ public class PlugPluggable implements IPipePluggable {
return new ItemStack[] { new ItemStack(BuildCraftTransport.plugItem) };
}
@Override
public void update(IPipeContainer pipe, ForgeDirection direction) {
}
@Override
public void onAttachedPipe(IPipeContainer pipe, ForgeDirection direction) {

View file

@ -165,6 +165,11 @@ public class RobotStationPluggable implements IPipePluggable {
return new ItemStack[] { new ItemStack(BuildCraftTransport.robotStationItem) };
}
@Override
public void update(IPipeContainer pipe, ForgeDirection direction) {
}
@Override
public void onAttachedPipe(IPipeContainer pipe, ForgeDirection direction) {
validate(pipe, direction);

View file

@ -375,6 +375,13 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler,
pipe.updateEntity();
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
IPipePluggable p = getPipePluggable(direction);
if (p != null) {
p.update(this, direction);
}
}
if (worldObj.isRemote) {
if (resyncGateExpansions) {
syncGateExpansions();
@ -765,7 +772,7 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler,
}
protected boolean hasBlockingPluggable(ForgeDirection side) {
IPipePluggable pluggable = getPluggable(side);
IPipePluggable pluggable = getPipePluggable(side);
return pluggable != null && pluggable.isBlocking(this, side);
}
@ -904,8 +911,16 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler,
if (worldObj != null && worldObj.isRemote || pluggable == null) {
return false;
}
sideProperties.dropItem(this, direction);
// Remove old pluggable
if (sideProperties.pluggables[direction.ordinal()] != null) {
sideProperties.dropItem(this, direction);
pipe.eventBus.unregisterHandler(sideProperties.pluggables[direction.ordinal()]);
}
sideProperties.pluggables[direction.ordinal()] = pluggable;
pipe.eventBus.registerHandler(pluggable);
pluggable.onAttachedPipe(this, direction);
notifyBlockChanged();
return true;
@ -993,7 +1008,7 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler,
}
case 2: {
for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) {
final IPipePluggable pluggable = getPluggable(ForgeDirection.getOrientation(i));
final IPipePluggable pluggable = getPipePluggable(ForgeDirection.getOrientation(i));
if (pluggable != null && pluggable instanceof GatePluggable) {
final GatePluggable gatePluggable = (GatePluggable) pluggable;
Gate gate = pipe.gates[i];
@ -1062,7 +1077,8 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler,
return false;
}
public IPipePluggable getPluggable(ForgeDirection side) {
@Override
public IPipePluggable getPipePluggable(ForgeDirection side) {
if (side == null || side == ForgeDirection.UNKNOWN) {
return null;
}
@ -1070,7 +1086,8 @@ public class TileGenericPipe extends TileEntity implements IFluidHandler,
return sideProperties.pluggables[side.ordinal()];
}
public boolean hasPluggable(ForgeDirection side) {
@Override
public boolean hasPipePluggable(ForgeDirection side) {
if (side == null || side == ForgeDirection.UNKNOWN) {
return false;
}

View file

@ -93,6 +93,11 @@ public class GatePluggable implements IPipePluggable {
return new ItemStack[] { gate };
}
@Override
public void update(IPipeContainer pipe, ForgeDirection direction) {
}
@Override
public void onAttachedPipe(IPipeContainer pipe, ForgeDirection direction) {
TileGenericPipe pipeReal = (TileGenericPipe) pipe;

View file

@ -15,14 +15,12 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.IIconProvider;
import buildcraft.api.core.render.ITextureStates;
import buildcraft.api.pipes.IPipePluggable;
import buildcraft.api.pipes.IPipePluggableRenderer;
import buildcraft.core.CoreConstants;
import buildcraft.core.utils.ColorUtils;
import buildcraft.core.utils.MatrixTranformations;
import buildcraft.transport.PipeIconProvider;
import buildcraft.transport.PipeRenderState;
import buildcraft.transport.TileGenericPipe;
@ -114,8 +112,8 @@ public class PipeRendererWorld implements ISimpleBlockRenderingHandler {
// Force other opaque renders into pass 0
if (renderPass == 0) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
if (tile.hasPluggable(dir)) {
IPipePluggable p = tile.getPluggable(dir);
if (tile.hasPipePluggable(dir)) {
IPipePluggable p = tile.getPipePluggable(dir);
IPipePluggableRenderer r = p.getRenderer();
if (r != null) {
r.renderPluggable(renderblocks, tile.getPipe(), dir, p, fakeBlock, x, y, z);