little bit of refactoring; added enderstorage driver; added reflection utility class

This commit is contained in:
Florian Nücke 2014-02-05 16:28:39 +01:00
parent f730b1eb6a
commit 9c4a637a69
9 changed files with 188 additions and 23 deletions

View File

@ -3,8 +3,10 @@ package li.cil.oc;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import li.cil.oc.driver.buildcraft.ComponentsBuildCraft;
import li.cil.oc.driver.vanilla.ComponentsVanilla;
import li.cil.oc.driver.IDriverBundle;
import li.cil.oc.driver.buildcraft.BundleBuildCraft;
import li.cil.oc.driver.enderstorage.BundleEnderStorage;
import li.cil.oc.driver.vanilla.BundleVanilla;
@Mod(modid = "OpenComputers|Components", name = "OpenComponents", version = "1.0.0", dependencies = "required-after:OpenComputers@[1.2.0,)")
public class OpenComponents {
@ -12,10 +14,15 @@ public class OpenComponents {
public static OpenComponents instance;
@Mod.EventHandler
public static void init(final FMLInitializationEvent e) {
ComponentsVanilla.register();
if (Loader.isModLoaded("BuildCraft|Core")) {
ComponentsBuildCraft.register();
public void init(final FMLInitializationEvent e) {
register(new BundleVanilla());
register(new BundleBuildCraft());
register(new BundleEnderStorage());
}
private void register(IDriverBundle bundle) {
if (bundle.getModId() == null || bundle.getModId().isEmpty() || Loader.isModLoaded(bundle.getModId())) {
bundle.initialize();
}
}
}

View File

@ -0,0 +1,7 @@
package li.cil.oc.driver;
public interface IDriverBundle {
String getModId();
void initialize();
}

View File

@ -3,7 +3,6 @@ package li.cil.oc.driver;
import li.cil.oc.api.Network;
import li.cil.oc.api.network.Visibility;
import li.cil.oc.api.prefab.ManagedEnvironment;
import net.minecraft.tileentity.TileEntity;
public class ManagedTileEntityEnvironment<T> extends ManagedEnvironment {
protected final T tileEntity;

View File

@ -0,0 +1,17 @@
package li.cil.oc.driver.buildcraft;
import li.cil.oc.api.Driver;
import li.cil.oc.driver.IDriverBundle;
public final class BundleBuildCraft implements IDriverBundle {
@Override
public String getModId() {
return "BuildCraft|Core";
}
@Override
public void initialize() {
Driver.add(new DriverPipe());
Driver.add(new DriverPowerReceptor());
}
}

View File

@ -1,13 +0,0 @@
package li.cil.oc.driver.buildcraft;
import li.cil.oc.api.Driver;
public final class ComponentsBuildCraft {
private ComponentsBuildCraft() {
}
public static void register() {
Driver.add(new DriverPipe());
Driver.add(new DriverPowerReceptor());
}
}

View File

@ -0,0 +1,16 @@
package li.cil.oc.driver.enderstorage;
import li.cil.oc.driver.IDriverBundle;
import li.cil.oc.api.Driver;
public final class BundleEnderStorage implements IDriverBundle {
@Override
public String getModId() {
return "EnderStorage";
}
@Override
public void initialize() {
Driver.add(new DriverFrequencyOwner());
}
}

View File

@ -0,0 +1,57 @@
package li.cil.oc.driver.enderstorage;
import li.cil.oc.api.network.Arguments;
import li.cil.oc.api.network.Callback;
import li.cil.oc.api.network.Context;
import li.cil.oc.api.network.ManagedEnvironment;
import li.cil.oc.driver.ManagedTileEntityEnvironment;
import li.cil.oc.driver.TileEntityDriver;
import li.cil.oc.util.Reflection;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class DriverFrequencyOwner extends TileEntityDriver {
// See https://bitbucket.org/ChickenBones/enderstorage/
private static final Class<?> TileFrequencyOwner = Reflection.getClass("codechicken.enderstorage.common.TileFrequencyOwner");
@Override
public Class<?> getFilterClass() {
return TileFrequencyOwner;
}
@Override
public ManagedEnvironment createEnvironment(final World world, final int x, final int y, final int z) {
return new Environment(world.getBlockTileEntity(x, y, z));
}
public static final class Environment extends ManagedTileEntityEnvironment<TileEntity> {
public Environment(final TileEntity tileEntity) {
super(tileEntity, "ender_storage");
}
@Callback
public Object[] getFrequency(final Context context, final Arguments args) {
return new Object[]{Reflection.get(tileEntity, "freq")};
}
@Callback
public Object[] setFrequency(final Context context, final Arguments args) {
final int frequency = args.checkInteger(0);
if ((frequency & 0xFFF) != frequency) {
throw new IllegalArgumentException("invalid frequency");
}
final String owner = (String) Reflection.get(tileEntity, "owner");
if (owner == null || owner.isEmpty() || "global".equals(owner)) {
Reflection.invoke(tileEntity, "setFreq", frequency);
} else {
return new Object[]{false, "cannot change frequency of owned storage"};
}
return null;
}
@Callback
public Object[] getOwner(final Context context, final Arguments args) {
return new Object[]{Reflection.get(tileEntity, "owner")};
}
}
}

View File

@ -1,12 +1,16 @@
package li.cil.oc.driver.vanilla;
import li.cil.oc.driver.IDriverBundle;
import li.cil.oc.api.Driver;
public final class ComponentsVanilla {
private ComponentsVanilla() {
public final class BundleVanilla implements IDriverBundle {
@Override
public String getModId() {
return null;
}
public static void register() {
@Override
public void initialize() {
Driver.add(new DriverBeacon());
Driver.add(new DriverBrewingStand());
Driver.add(new DriverComparator());

View File

@ -0,0 +1,71 @@
package li.cil.oc.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class Reflection {
private Reflection() {
}
public static Class<?> getClass(final String name) {
try {
return Class.forName(name);
} catch (final ClassNotFoundException ignored) {
return null;
}
}
public static Object get(final Object instance, final String fieldName) {
try {
final Field field = instance.getClass().getField(fieldName);
return field.get(instance);
} catch (final IllegalAccessException ignored) {
return null;
} catch (final NoSuchFieldException ignored) {
return null;
}
}
public static void set(final Object instance, final String fieldName, final Object value) {
try {
final Field field = instance.getClass().getField(fieldName);
field.set(instance, value);
} catch (final IllegalAccessException ignored) {
} catch (final NoSuchFieldException ignored) {
}
}
public static Object invoke(final Object instance, final String methodName, final Object... args) {
try {
outer:
for (Method method : instance.getClass().getMethods()) {
if (method.getName().equals(methodName) && method.getParameterTypes().length == args.length) {
Class<?>[] argTypes = method.getParameterTypes();
for (int i = 0; i < argTypes.length; ++i) {
Class<?> have = argTypes[i];
Class<?> given = args[i].getClass();
// Fail if not assignable and not assignable to primitive.
if (!have.isAssignableFrom(given) && (!have.isPrimitive()
|| (!(byte.class.equals(have) && Byte.class.equals(given))
&& !(short.class.equals(have) && Short.class.equals(given))
&& !(int.class.equals(have) && Integer.class.equals(given))
&& !(long.class.equals(have) && Long.class.equals(given))
&& !(float.class.equals(have) && Float.class.equals(given))
&& !(double.class.equals(have) && Double.class.equals(given))
&& !(boolean.class.equals(have) && Boolean.class.equals(given))
&& !(char.class.equals(have) && Character.class.equals(given))))) {
continue outer;
}
}
return method.invoke(instance, args);
}
}
return null;
} catch (InvocationTargetException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
}