Slight clean up for the PartType enumeration. Extracted reflection logic for finding part models into a separate class. Removed unnecessary fields and clarified constructor argument.
This commit is contained in:
parent
1d0606947b
commit
7cdbe431e5
138
src/main/java/appeng/items/parts/PartModelsHelper.java
Normal file
138
src/main/java/appeng/items/parts/PartModelsHelper.java
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
package appeng.items.parts;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
import appeng.core.AELog;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with the reflection magic needed to gather all models for AE2 cable bus parts.
|
||||||
|
*/
|
||||||
|
class PartModelsHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
static List<ResourceLocation> createModels( Class<?> clazz )
|
||||||
|
{
|
||||||
|
List<ResourceLocation> locations = new ArrayList<>( );
|
||||||
|
|
||||||
|
// Check all static fields for used models
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
for( Field field : fields )
|
||||||
|
{
|
||||||
|
if( field.getAnnotation( PartModels.class ) == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( !Modifier.isStatic( field.getModifiers() ) )
|
||||||
|
{
|
||||||
|
AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + field );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
field.setAccessible( true );
|
||||||
|
value = field.get( null );
|
||||||
|
}
|
||||||
|
catch( IllegalAccessException e )
|
||||||
|
{
|
||||||
|
AELog.error( e, "Cannot access field annotated with @PartModels: " + field );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertAndAddLocation( field, value, locations );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all static methods for the annotation
|
||||||
|
for( Method method : clazz.getDeclaredMethods() )
|
||||||
|
{
|
||||||
|
if( method.getAnnotation( PartModels.class ) == null )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Modifier.isStatic( method.getModifiers() ) )
|
||||||
|
{
|
||||||
|
AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + method );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for parameter count
|
||||||
|
if( method.getParameters().length != 0 )
|
||||||
|
{
|
||||||
|
AELog.error( "The @PartModels annotation can only be used on static methods without parameters. Was seen on: " + method );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we can handle the return type
|
||||||
|
Class<?> returnType = method.getReturnType();
|
||||||
|
if( !ResourceLocation.class.isAssignableFrom( returnType ) && !Collection.class.isAssignableFrom( returnType ) )
|
||||||
|
{
|
||||||
|
AELog.error( "The @PartModels annotation can only be used on static methods that return a ResourceLocation or Collection of "
|
||||||
|
+ "ResourceLocations. Was seen on: " + method );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
method.setAccessible( true );
|
||||||
|
value = method.invoke( null );
|
||||||
|
}
|
||||||
|
catch( IllegalAccessException | InvocationTargetException e )
|
||||||
|
{
|
||||||
|
AELog.error( e, "Failed to invoke the @PartModels annotated method " + method );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertAndAddLocation( method, value, locations );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( clazz.getSuperclass() != null )
|
||||||
|
{
|
||||||
|
locations.addAll( createModels( clazz.getSuperclass() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void convertAndAddLocation( Object source, Object value, List<ResourceLocation> locations )
|
||||||
|
{
|
||||||
|
if( value == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( value instanceof ResourceLocation )
|
||||||
|
{
|
||||||
|
locations.add( (ResourceLocation) value );
|
||||||
|
}
|
||||||
|
else if( value instanceof Collection )
|
||||||
|
{
|
||||||
|
// Check that each object is a ResourceLocation
|
||||||
|
Collection values = (Collection) value;
|
||||||
|
for( Object candidate : values )
|
||||||
|
{
|
||||||
|
if ( !( candidate instanceof ResourceLocation )) {
|
||||||
|
AELog.error( "List of locations obtained from {} contains a non resource location: {}", source, candidate );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
locations.add( (ResourceLocation) candidate );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,13 +20,7 @@ package appeng.items.parts;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -41,7 +35,6 @@ import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
import appeng.api.parts.IPart;
|
import appeng.api.parts.IPart;
|
||||||
import appeng.api.util.AEColor;
|
import appeng.api.util.AEColor;
|
||||||
import appeng.core.AELog;
|
|
||||||
import appeng.core.AppEng;
|
import appeng.core.AppEng;
|
||||||
import appeng.core.features.AEFeature;
|
import appeng.core.features.AEFeature;
|
||||||
import appeng.core.localization.GuiText;
|
import appeng.core.localization.GuiText;
|
||||||
|
@ -215,7 +208,6 @@ public enum PartType
|
||||||
InterfaceTerminal( 480, "interface_terminal" , EnumSet.of( AEFeature.InterfaceTerminal ), EnumSet.noneOf( IntegrationType.class ), PartInterfaceTerminal.class );
|
InterfaceTerminal( 480, "interface_terminal" , EnumSet.of( AEFeature.InterfaceTerminal ), EnumSet.noneOf( IntegrationType.class ), PartInterfaceTerminal.class );
|
||||||
|
|
||||||
private final int baseDamage;
|
private final int baseDamage;
|
||||||
private final ResourceLocation name;
|
|
||||||
private final Set<AEFeature> features;
|
private final Set<AEFeature> features;
|
||||||
private final Set<IntegrationType> integrations;
|
private final Set<IntegrationType> integrations;
|
||||||
private final Class<? extends IPart> myPart;
|
private final Class<? extends IPart> myPart;
|
||||||
|
@ -224,23 +216,22 @@ public enum PartType
|
||||||
private final Set<ResourceLocation> models;
|
private final Set<ResourceLocation> models;
|
||||||
private Constructor<? extends IPart> constructor;
|
private Constructor<? extends IPart> constructor;
|
||||||
|
|
||||||
PartType( final int baseMetaValue, final String name, final Set<AEFeature> features, final Set<IntegrationType> integrations, final Class<? extends IPart> c )
|
PartType( final int baseMetaValue, final String itemModel, final Set<AEFeature> features, final Set<IntegrationType> integrations, final Class<? extends IPart> c )
|
||||||
{
|
{
|
||||||
this( baseMetaValue, name, features, integrations, c, null );
|
this( baseMetaValue, itemModel, features, integrations, c, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
PartType( final int baseMetaValue, final String name, final Set<AEFeature> features, final Set<IntegrationType> integrations, final Class<? extends IPart> c, final GuiText en )
|
PartType( final int baseMetaValue, final String itemModel, final Set<AEFeature> features, final Set<IntegrationType> integrations, final Class<? extends IPart> c, final GuiText en )
|
||||||
{
|
{
|
||||||
this.baseDamage = baseMetaValue;
|
this.baseDamage = baseMetaValue;
|
||||||
this.name = new ResourceLocation( AppEng.MOD_ID, name );
|
|
||||||
this.features = Collections.unmodifiableSet( features );
|
this.features = Collections.unmodifiableSet( features );
|
||||||
this.integrations = Collections.unmodifiableSet( integrations );
|
this.integrations = Collections.unmodifiableSet( integrations );
|
||||||
this.myPart = c;
|
this.myPart = c;
|
||||||
this.extraName = en;
|
this.extraName = en;
|
||||||
this.itemModels = createItemModels( name );
|
this.itemModels = createItemModels( itemModel );
|
||||||
if( c != null )
|
if( c != null )
|
||||||
{
|
{
|
||||||
this.models = new HashSet<>( createModels( c ) );
|
this.models = new HashSet<>( PartModelsHelper.createModels( c ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -263,16 +254,6 @@ public enum PartType
|
||||||
return this.baseDamage;
|
return this.baseDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceLocation getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceLocation getModel()
|
|
||||||
{
|
|
||||||
return new ResourceLocation( name.getResourceDomain(), "part/" + name.getResourcePath() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCable()
|
public boolean isCable()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -318,119 +299,5 @@ public enum PartType
|
||||||
return models;
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ResourceLocation> createModels( Class<?> clazz )
|
|
||||||
{
|
|
||||||
List<ResourceLocation> locations = new ArrayList<>( );
|
|
||||||
|
|
||||||
// Check all static fields for used models
|
|
||||||
Field[] fields = clazz.getDeclaredFields();
|
|
||||||
for( Field field : fields )
|
|
||||||
{
|
|
||||||
if( field.getAnnotation( PartModels.class ) == null )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( !Modifier.isStatic( field.getModifiers() ) )
|
|
||||||
{
|
|
||||||
AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + field );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object value;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
field.setAccessible( true );
|
|
||||||
value = field.get( null );
|
|
||||||
}
|
|
||||||
catch( IllegalAccessException e )
|
|
||||||
{
|
|
||||||
AELog.error( e, "Cannot access field annotated with @PartModels: " + field );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
convertAndAddLocation( field, value, locations );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check all static methods for the annotation
|
|
||||||
for( Method method : clazz.getDeclaredMethods() )
|
|
||||||
{
|
|
||||||
if( method.getAnnotation( PartModels.class ) == null )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !Modifier.isStatic( method.getModifiers() ) )
|
|
||||||
{
|
|
||||||
AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + method );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for parameter count
|
|
||||||
if( method.getParameters().length != 0 )
|
|
||||||
{
|
|
||||||
AELog.error( "The @PartModels annotation can only be used on static methods without parameters. Was seen on: " + method );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we can handle the return type
|
|
||||||
Class<?> returnType = method.getReturnType();
|
|
||||||
if( !ResourceLocation.class.isAssignableFrom( returnType ) && !Collection.class.isAssignableFrom( returnType ) )
|
|
||||||
{
|
|
||||||
AELog.error( "The @PartModels annotation can only be used on static methods that return a ResourceLocation or Collection of "
|
|
||||||
+ "ResourceLocations. Was seen on: " + method );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object value = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
method.setAccessible( true );
|
|
||||||
value = method.invoke( null );
|
|
||||||
}
|
|
||||||
catch( IllegalAccessException | InvocationTargetException e )
|
|
||||||
{
|
|
||||||
AELog.error( e, "Failed to invoke the @PartModels annotated method " + method );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
convertAndAddLocation( method, value, locations );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( clazz.getSuperclass() != null )
|
|
||||||
{
|
|
||||||
locations.addAll( createModels( clazz.getSuperclass() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void convertAndAddLocation( Object source, Object value, List<ResourceLocation> locations )
|
|
||||||
{
|
|
||||||
if( value == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( value instanceof ResourceLocation )
|
|
||||||
{
|
|
||||||
locations.add( (ResourceLocation) value );
|
|
||||||
}
|
|
||||||
else if( value instanceof Collection )
|
|
||||||
{
|
|
||||||
// Check that each object is a ResourceLocation
|
|
||||||
Collection values = (Collection) value;
|
|
||||||
for( Object candidate : values )
|
|
||||||
{
|
|
||||||
if ( !( candidate instanceof ResourceLocation )) {
|
|
||||||
AELog.error( "List of locations obtained from {} contains a non resource location: {}", source, candidate );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
locations.add( (ResourceLocation) candidate );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -106,11 +105,6 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
|
||||||
return ItemMultiPart.instance.getTypeByStack( is );
|
return ItemMultiPart.instance.getTypeByStack( is );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceLocation getDefaultModelLocation()
|
|
||||||
{
|
|
||||||
return getType().getModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGridNode getGridNode( final AEPartLocation dir )
|
public IGridNode getGridNode( final AEPartLocation dir )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue