Remove part layer api in favor of capabilities (#355)
This commit is contained in:
@@ -35,32 +35,6 @@ import net.minecraft.world.World;
|
||||
|
||||
public interface IPartHelper
|
||||
{
|
||||
/**
|
||||
* Register a new layer with the part layer system, this allows you to write an in between between tile entities and
|
||||
* parts.
|
||||
*
|
||||
* AE By Default includes,
|
||||
*
|
||||
* 1. ISidedInventory ( and by extension IInventory. )
|
||||
*
|
||||
* 2. IFluidHandler Forge Fluids
|
||||
*
|
||||
* 3. IPowerEmitter BC Power output.
|
||||
*
|
||||
* 4. IPowerReceptor BC Power input.
|
||||
*
|
||||
* 5. IEnergySink IC2 Power input.
|
||||
*
|
||||
* 6. IEnergySource IC2 Power output.
|
||||
*
|
||||
* 7. IPipeConnection BC Pipe Connections
|
||||
*
|
||||
* As long as a valid layer is registered for a interface you can simply implement that interface on a part get
|
||||
* implement it.
|
||||
*
|
||||
* @return true on success, false on failure, usually a error will be logged as well.
|
||||
*/
|
||||
boolean registerNewLayer( String string, String layerInterface );
|
||||
|
||||
/**
|
||||
* use in use item, to try and place a IBusItem
|
||||
|
||||
@@ -151,7 +151,7 @@ public interface IPartHost extends ICustomCableConnection
|
||||
void markForSave();
|
||||
|
||||
/**
|
||||
* part of the {@link LayerBase}
|
||||
* called when parts are added or removed
|
||||
*/
|
||||
void partChanged();
|
||||
|
||||
@@ -169,11 +169,6 @@ public interface IPartHost extends ICustomCableConnection
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* @return a mutable list of flags you can adjust to track state.
|
||||
*/
|
||||
Set<LayerFlags> getLayerFlags();
|
||||
|
||||
/**
|
||||
* remove host from world...
|
||||
*/
|
||||
@@ -191,4 +186,4 @@ public interface IPartHost extends ICustomCableConnection
|
||||
*/
|
||||
boolean isInWorld();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013 AlgorithmX2
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package appeng.api.parts;
|
||||
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import appeng.api.util.AEPartLocation;
|
||||
|
||||
|
||||
/**
|
||||
* All Layers must extends this, this get part implementation is provided to interface with the parts, however a real
|
||||
* implementation will be used at runtime.
|
||||
*
|
||||
* TODO: Consider removing and replacing with capabilities.
|
||||
*/
|
||||
public abstract class LayerBase extends TileEntity // implements IPartHost
|
||||
{
|
||||
|
||||
/**
|
||||
* Grants access for the layer to the parts of the host.
|
||||
*
|
||||
* This Method looks silly, that is because its not used at runtime, a real implementation will be used instead.
|
||||
*
|
||||
* @param side side of part
|
||||
*
|
||||
* @return the part for the requested side.
|
||||
*/
|
||||
public IPart getPart( final AEPartLocation side )
|
||||
{
|
||||
return null; // place holder.
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants access for the layer to the parts of the host.
|
||||
*
|
||||
* This Method looks silly, that is because its not used at runtime, a real implementation will be used instead.
|
||||
*
|
||||
* @param side side of part
|
||||
*
|
||||
* @return the part for the requested side.
|
||||
*/
|
||||
public IPart getPart( final EnumFacing side )
|
||||
{
|
||||
return null; // place holder.
|
||||
}
|
||||
|
||||
/**
|
||||
* called when the parts change in the container, YOU MUST CALL super.PartChanged();
|
||||
*/
|
||||
public void notifyNeighbors()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* called when the parts change in the container, YOU MUST CALL super.PartChanged();
|
||||
*/
|
||||
public void partChanged()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a mutable list of flags you can adjust to track state.
|
||||
*/
|
||||
public Set<LayerFlags> getLayerFlags()
|
||||
{
|
||||
return null; // place holder.
|
||||
}
|
||||
|
||||
public void markForSave()
|
||||
{
|
||||
// something!
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013 AlgorithmX2
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package appeng.api.parts;
|
||||
|
||||
|
||||
/**
|
||||
* TODO: Consider removing and replacing with capabilities.
|
||||
*/
|
||||
public enum LayerFlags
|
||||
{
|
||||
|
||||
IC2_ENET
|
||||
|
||||
}
|
||||
@@ -29,7 +29,6 @@ import appeng.block.AEBaseTileBlock;
|
||||
import appeng.client.UnlistedProperty;
|
||||
import appeng.client.render.cablebus.CableBusBakedModel;
|
||||
import appeng.client.render.cablebus.CableBusRenderState;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketClick;
|
||||
@@ -91,10 +90,6 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
|
||||
|
||||
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
|
||||
|
||||
private static Class<? extends AEBaseTile> noTesrTile;
|
||||
|
||||
private static Class<? extends AEBaseTile> tesrTile;
|
||||
|
||||
public BlockCableBus() {
|
||||
super(AEGlassMaterial.INSTANCE);
|
||||
this.setLightOpacity(0);
|
||||
@@ -378,10 +373,9 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
|
||||
}
|
||||
|
||||
public void setupTile() {
|
||||
noTesrTile = Api.INSTANCE.partHelper().getCombinedInstance(TileCableBus.class);
|
||||
this.setTileEntity(noTesrTile);
|
||||
this.setTileEntity(TileCableBus.class);
|
||||
|
||||
GameRegistry.registerTileEntity(noTesrTile, AppEng.MOD_ID.toLowerCase() + ":" + "BlockCableBus");
|
||||
GameRegistry.registerTileEntity(TileCableBus.class, AppEng.MOD_ID.toLowerCase() + ":" + "BlockCableBus");
|
||||
|
||||
if (Platform.isClient()) {
|
||||
setupTesr();
|
||||
@@ -390,9 +384,8 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private static void setupTesr() {
|
||||
tesrTile = Api.INSTANCE.partHelper().getCombinedInstance(TileCableBusTESR.class);
|
||||
GameRegistry.registerTileEntity(tesrTile, AppEng.MOD_ID.toLowerCase() + ":" + "ClientOnly_TESR_CableBus");
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(BlockCableBus.getTesrTile(), new CableBusTESR());
|
||||
GameRegistry.registerTileEntity(TileCableBusTESR.class, AppEng.MOD_ID.toLowerCase() + ":" + "ClientOnly_TESR_CableBus");
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileCableBusTESR.class, new CableBusTESR());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -438,14 +431,6 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
|
||||
super.onEntityWalk(world, pos, entityIn);
|
||||
}
|
||||
|
||||
public static Class<? extends AEBaseTile> getNoTesrTile() {
|
||||
return noTesrTile;
|
||||
}
|
||||
|
||||
public static Class<? extends AEBaseTile> getTesrTile() {
|
||||
return tesrTile;
|
||||
}
|
||||
|
||||
// Helper to get access to the protected constructor
|
||||
@SideOnly(Side.CLIENT)
|
||||
private static class DestroyFX extends ParticleDigging {
|
||||
|
||||
@@ -21,258 +21,19 @@ package appeng.core.api;
|
||||
|
||||
import appeng.api.parts.CableRenderMode;
|
||||
import appeng.api.parts.IPartHelper;
|
||||
import appeng.api.parts.LayerBase;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.parts.PartPlacement;
|
||||
import appeng.tile.AEBaseTile;
|
||||
import appeng.tile.networking.TileCableBus;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.commons.ClassRemapper;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class ApiPart implements IPartHelper {
|
||||
|
||||
private final LoadingCache<CacheKey, Class<? extends AEBaseTile>> cache = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<CacheKey, Class<? extends AEBaseTile>>() {
|
||||
@Override
|
||||
public Class<? extends AEBaseTile> load(CacheKey key) throws Exception {
|
||||
return ApiPart.this.generateCombinedClass(key);
|
||||
}
|
||||
});
|
||||
|
||||
private final Map<Class<?>, String> interfaces2Layer = new HashMap<>();
|
||||
private final List<String> desc = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Conceptually this method will build a new class hierarchy that is rooted at the given base class, and includes a
|
||||
* chain of all registered layers.
|
||||
* <p/>
|
||||
* To accomplish this, it takes the first registered layer, replaces it's inheritance from LayerBase with an
|
||||
* inheritance from the given baseClass,
|
||||
* and uses the resulting class as the parent class for the next registered layer, for which it repeats this
|
||||
* process. This process is then repeated
|
||||
* until a class hierarchy of all layers is formed. While janking out the inheritance from LayerBase, it'll make
|
||||
* also sure that calls to that
|
||||
* classes method will instead be forwarded to the superclass that was inserted as part of the described process.
|
||||
* <p/>
|
||||
* Example: If layers A and B are registered, and TileCableBus is passed in as the baseClass, a synthetic class
|
||||
* A_B_TileCableBus should be returned,
|
||||
* which has A_B_TileCableBus -extends-> B_TileCableBus -extends-> TileCableBus as it's class hierarchy, where
|
||||
* A_B_TileCableBus has been generated
|
||||
* from A, and B_TileCableBus has been generated from B.
|
||||
*/
|
||||
public Class<? extends AEBaseTile> getCombinedInstance(final Class<? extends AEBaseTile> baseClass) {
|
||||
if (this.desc.isEmpty()) {
|
||||
// No layers registered...
|
||||
return baseClass;
|
||||
}
|
||||
|
||||
return this.cache.getUnchecked(new CacheKey(baseClass, this.desc));
|
||||
}
|
||||
|
||||
private Class<? extends AEBaseTile> generateCombinedClass(CacheKey cacheKey) {
|
||||
final Class<? extends AEBaseTile> parentClass;
|
||||
|
||||
// Get the list of interfaces that still need to be implemented beyond the current one
|
||||
List<String> remainingInterfaces = cacheKey.getInterfaces().subList(1, cacheKey.getInterfaces().size());
|
||||
|
||||
// We are not at the root of the class hierarchy yet
|
||||
if (!remainingInterfaces.isEmpty()) {
|
||||
CacheKey parentKey = new CacheKey(cacheKey.getBaseClass(), remainingInterfaces);
|
||||
parentClass = this.cache.getUnchecked(parentKey);
|
||||
} else {
|
||||
parentClass = cacheKey.getBaseClass();
|
||||
}
|
||||
|
||||
// Which interface should be implemented in this layer?
|
||||
String interfaceName = cacheKey.getInterfaces().get(0);
|
||||
|
||||
try {
|
||||
// This is the particular interface that this layer was registered for. Loading the class may fail if i.e.
|
||||
// an API is broken or not present
|
||||
// and in this case, the layer will be skipped!
|
||||
Class<?> interfaceClass = Class.forName(interfaceName);
|
||||
String layerImpl = this.interfaces2Layer.get(interfaceClass);
|
||||
|
||||
return this.getClassByDesc(parentClass, layerImpl);
|
||||
} catch (final Throwable t) {
|
||||
AELog.warn("Error loading " + interfaceName);
|
||||
AELog.debug(t);
|
||||
return parentClass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends AEBaseTile> getClassByDesc(Class<? extends AEBaseTile> baseClass, final String next) {
|
||||
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
final ClassNode n = this.getReader(next);
|
||||
final String originalName = n.name;
|
||||
|
||||
try {
|
||||
n.name = n.name + '_' + baseClass.getSimpleName();
|
||||
n.superName = baseClass.getName().replace('.', '/');
|
||||
} catch (final Throwable t) {
|
||||
AELog.debug(t);
|
||||
}
|
||||
|
||||
for (final MethodNode mn : n.methods) {
|
||||
final Iterator<AbstractInsnNode> i = mn.instructions.iterator();
|
||||
while (i.hasNext()) {
|
||||
this.processNode(i.next(), n.superName);
|
||||
}
|
||||
}
|
||||
|
||||
final DefaultPackageClassNameRemapper remapper = new DefaultPackageClassNameRemapper();
|
||||
remapper.inputOutput.put("appeng/api/parts/LayerBase", n.superName);
|
||||
remapper.inputOutput.put(originalName, n.name);
|
||||
n.accept(new ClassRemapper(cw, remapper));
|
||||
// n.accept( cw );
|
||||
|
||||
// n.accept( new TraceClassVisitor( new PrintWriter( System.out ) ) );
|
||||
final byte[] byteArray = cw.toByteArray();
|
||||
final int size = byteArray.length;
|
||||
final Class clazz = this.loadClass(n.name.replace("/", "."), byteArray);
|
||||
|
||||
try {
|
||||
final Object fish = clazz.newInstance();
|
||||
|
||||
boolean hasError = false;
|
||||
|
||||
if (!baseClass.isInstance(fish)) {
|
||||
hasError = true;
|
||||
AELog.error("Error, Expected layer to implement " + baseClass + " did not.");
|
||||
}
|
||||
|
||||
if (fish instanceof LayerBase) {
|
||||
hasError = true;
|
||||
AELog.error("Error, Expected layer to NOT implement LayerBase but it DID.");
|
||||
}
|
||||
|
||||
if (!(fish instanceof TileCableBus)) {
|
||||
hasError = true;
|
||||
AELog.error("Error, Expected layer to implement TileCableBus did not.");
|
||||
}
|
||||
|
||||
if (!(fish instanceof TileEntity)) {
|
||||
hasError = true;
|
||||
AELog.error("Error, Expected layer to implement TileEntity did not.");
|
||||
}
|
||||
|
||||
if (!hasError) {
|
||||
AELog.info("Layer: " + n.name + " loaded successfully - " + size + " bytes");
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
AELog.error("Layer: " + n.name + " Failed.");
|
||||
AELog.debug(t);
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private ClassNode getReader(final String name) {
|
||||
final String path = '/' + name.replace(".", "/") + ".class";
|
||||
final InputStream is = this.getClass().getResourceAsStream(path);
|
||||
try {
|
||||
final ClassReader cr = new ClassReader(is);
|
||||
|
||||
final ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
|
||||
return cn;
|
||||
} catch (final IOException e) {
|
||||
throw new IllegalStateException("Error loading " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processNode(final AbstractInsnNode next, final String nePar) {
|
||||
if (next instanceof MethodInsnNode) {
|
||||
final MethodInsnNode min = (MethodInsnNode) next;
|
||||
if (min.owner.equals("appeng/api/parts/LayerBase")) {
|
||||
min.owner = nePar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Class loadClass(final String name, byte[] b) {
|
||||
// override classDefine (as it is protected) and define the class.
|
||||
Class clazz = null;
|
||||
try {
|
||||
final ClassLoader loader = this.getClass().getClassLoader();// ClassLoader.getSystemClassLoader();
|
||||
final Class<ClassLoader> root = ClassLoader.class;
|
||||
final Class<? extends ClassLoader> cls = loader.getClass();
|
||||
final Method defineClassMethod = root.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
|
||||
final Method runTransformersMethod = cls.getDeclaredMethod("runTransformers", String.class, String.class, byte[].class);
|
||||
|
||||
runTransformersMethod.setAccessible(true);
|
||||
defineClassMethod.setAccessible(true);
|
||||
try {
|
||||
final Object[] argsA = {
|
||||
name,
|
||||
name,
|
||||
b
|
||||
};
|
||||
b = (byte[]) runTransformersMethod.invoke(loader, argsA);
|
||||
|
||||
final Object[] args = {
|
||||
name,
|
||||
b,
|
||||
0,
|
||||
b.length
|
||||
};
|
||||
clazz = (Class) defineClassMethod.invoke(loader, args);
|
||||
} finally {
|
||||
runTransformersMethod.setAccessible(false);
|
||||
defineClassMethod.setAccessible(false);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
AELog.debug(e);
|
||||
throw new IllegalStateException("Unable to manage part API.", e);
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerNewLayer(final String layer, final String layerInterface) {
|
||||
try {
|
||||
final Class<?> layerInterfaceClass = Class.forName(layerInterface);
|
||||
if (this.interfaces2Layer.get(layerInterfaceClass) == null) {
|
||||
this.interfaces2Layer.put(layerInterfaceClass, layer);
|
||||
this.desc.add(layerInterface);
|
||||
return true;
|
||||
} else {
|
||||
AELog.info("Layer " + layer + " not registered, " + layerInterface + " already has a layer.");
|
||||
}
|
||||
} catch (final Throwable ignored) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult placeBus(final ItemStack is, final BlockPos pos, final EnumFacing side, final EntityPlayer player, final EnumHand hand, final World w) {
|
||||
return PartPlacement.place(is, pos, side, player, hand, w, PartPlacement.PlaceType.PLACE_ITEM, 0);
|
||||
@@ -282,58 +43,4 @@ public class ApiPart implements IPartHelper {
|
||||
public CableRenderMode getCableRenderMode() {
|
||||
return AppEng.proxy.getRenderMode();
|
||||
}
|
||||
|
||||
private static class DefaultPackageClassNameRemapper extends Remapper {
|
||||
|
||||
private final HashMap<String, String> inputOutput = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String map(final String typeName) {
|
||||
final String o = this.inputOutput.get(typeName);
|
||||
if (o == null) {
|
||||
return typeName;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CacheKey {
|
||||
private final Class<? extends AEBaseTile> baseClass;
|
||||
|
||||
private final List<String> interfaces;
|
||||
|
||||
private CacheKey(Class<? extends AEBaseTile> baseClass, List<String> interfaces) {
|
||||
this.baseClass = baseClass;
|
||||
this.interfaces = ImmutableList.copyOf(interfaces);
|
||||
}
|
||||
|
||||
private Class<? extends AEBaseTile> getBaseClass() {
|
||||
return this.baseClass;
|
||||
}
|
||||
|
||||
private List<String> getInterfaces() {
|
||||
return this.interfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || this.getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CacheKey cacheKey = (CacheKey) o;
|
||||
|
||||
return this.baseClass.equals(cacheKey.baseClass) && this.interfaces.equals(cacheKey.interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.baseClass.hashCode();
|
||||
result = 31 * result + this.interfaces.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ import java.util.*;
|
||||
public class CableBusContainer extends CableBusStorage implements AEMultiTile, ICableBusContainer {
|
||||
|
||||
private static final ThreadLocal<Boolean> IS_LOADING = new ThreadLocal<>();
|
||||
private final EnumSet<LayerFlags> myLayerFlags = EnumSet.noneOf(LayerFlags.class);
|
||||
private YesNo hasRedstone = YesNo.UNDECIDED;
|
||||
private IPartHost tcb;
|
||||
// TODO 1.10.2-R - does somebody seriously want to make parts TESR??? Hope not.
|
||||
@@ -424,11 +423,6 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LayerFlags> getLayerFlags() {
|
||||
return this.myLayerFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
this.tcb.cleanup();
|
||||
|
||||
@@ -22,13 +22,11 @@ package appeng.tile.networking;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.parts.IFacadeContainer;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.api.parts.LayerFlags;
|
||||
import appeng.api.parts.SelectedPart;
|
||||
import appeng.api.util.AECableType;
|
||||
import appeng.api.util.AEColor;
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
import appeng.helpers.AEMultiTile;
|
||||
import appeng.helpers.ICustomCollision;
|
||||
import appeng.hooks.TickHandler;
|
||||
@@ -101,7 +99,7 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl
|
||||
protected void updateTileSetting() {
|
||||
if (this.getCableBus().isRequiresDynamicRender()) {
|
||||
try {
|
||||
final TileCableBus tcb = (TileCableBus) BlockCableBus.getTesrTile().newInstance();
|
||||
final TileCableBus tcb = TileCableBusTESR.class.newInstance();
|
||||
tcb.copyFrom(this);
|
||||
this.getWorld().setTileEntity(this.pos, tcb);
|
||||
} catch (final Throwable ignored) {
|
||||
@@ -283,11 +281,6 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl
|
||||
return this.getCableBus().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LayerFlags> getLayerFlags() {
|
||||
return this.getCableBus().getLayerFlags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
this.getWorld().setBlockToAir(this.pos);
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
package appeng.tile.networking;
|
||||
|
||||
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
|
||||
|
||||
public class TileCableBusTESR extends TileCableBus {
|
||||
|
||||
/**
|
||||
@@ -31,7 +28,7 @@ public class TileCableBusTESR extends TileCableBus {
|
||||
protected void updateTileSetting() {
|
||||
if (!this.getCableBus().isRequiresDynamicRender()) {
|
||||
try {
|
||||
final TileCableBus tcb = (TileCableBus) BlockCableBus.getNoTesrTile().newInstance();
|
||||
final TileCableBus tcb = TileCableBus.class.newInstance();
|
||||
tcb.copyFrom(this);
|
||||
this.getWorld().setTileEntity(this.pos, tcb);
|
||||
} catch (final Throwable ignored) {
|
||||
|
||||
Reference in New Issue
Block a user