Update MjAPI (implementation and docs)

This commit is contained in:
Prototik 2014-05-08 17:56:15 +08:00
parent 771f42977c
commit 246375c5ac
3 changed files with 108 additions and 53 deletions

View file

@ -14,39 +14,71 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import buildcraft.api.core.JavaTools; import buildcraft.api.core.JavaTools;
import buildcraft.api.power.PowerHandler;
public final class MjAPI { public final class MjAPI {
private static Map<Class, BatteryField> MjBatteries = new HashMap<Class, BatteryField>();
static Map<Class, BatteryField> MjBatteries = new HashMap<Class, BatteryField>();
private enum BatteryKind { private enum BatteryKind {
Value, Container Value, Container
} }
private static class BatteryField { private static class BatteryField {
public Field field; Field field;
public MjBattery battery; MjBattery battery;
public BatteryKind kind; BatteryKind kind;
}
public interface IBatteryProvider {
BatteryObject getMjBattery();
} }
public static class BatteryObject { public static class BatteryObject {
Field f; private Field f;
Object o; private Object o;
MjBattery b; private MjBattery b;
/**
* @return Current energy requirement for keeping machine state
*/
public double getEnergyRequested() { public double getEnergyRequested() {
try { try {
double contained = f.getDouble(o); double contained = f.getDouble(o);
double max = b.maxCapacity();
return Math.max(Math.min(max - contained, b.maxReceivedPerCycle()), b.minimumConsumption());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return 0;
}
double left = contained + b.maxReceivedPerCycle() > b /**
.maxCapacity() ? b.maxCapacity() - contained : b * Add energy to this battery
.maxReceivedPerCycle(); *
* @param mj Energy amount
* @return Used energy
*/
public double addEnergy(double mj) {
return addEnergy(mj, false);
}
if (left > 0) { /**
return left; * Add energy to this battery
} else { *
return b.minimumConsumption(); * @param mj Energy amount
* @param ignoreCycleLimit Force add all energy even if "maxReceivedPerCycle" limit is reached
* @return Used energy
*/
public double addEnergy(double mj, boolean ignoreCycleLimit) {
try {
double contained = f.getDouble(o);
double maxAccepted = b.maxCapacity() - contained + b.minimumConsumption();
if (!ignoreCycleLimit && maxAccepted > b.maxReceivedPerCycle()) {
maxAccepted = b.maxReceivedPerCycle();
}
double used = Math.min(maxAccepted, mj);
if (used > 0) {
f.setDouble(o, Math.min(contained + used, b.maxCapacity()));
return used;
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
@ -55,23 +87,9 @@ public final class MjAPI {
return 0; return 0;
} }
public double addEnergy(double watts) { /**
try { * @return Current stored energy amount in this battery
double e = f.getDouble(o); */
double max = b.maxCapacity();
double used = e + watts <= max ? watts : max - e;
f.setDouble(o, e + used);
return used;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return 0;
}
public double getEnergyStored() { public double getEnergyStored() {
try { try {
return f.getDouble(o); return f.getDouble(o);
@ -81,26 +99,56 @@ public final class MjAPI {
} }
} }
public void setEnergyStored(double watts) { /**
* Set current stored energy amount.
* Doesn't use it for your machines! Decrease your battery field directly.
*
* @param mj New energy amount
*/
public void setEnergyStored(double mj) {
try { try {
f.setDouble(o, watts); f.setDouble(o, mj);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/**
* Can be overrided via {@link #reconfigure(double, double, double)}
*
* @return Maximal energy amount for this battery.
*/
public double maxCapacity() { public double maxCapacity() {
return b.maxCapacity(); return b.maxCapacity();
} }
/**
* Can be overrided via {@link #reconfigure(double, double, double)}
*
* @return Minimal energy amount for keep your machine in active state
*/
public double minimumConsumption() { public double minimumConsumption() {
return b.minimumConsumption(); return b.minimumConsumption();
} }
/**
* Can be overrided via {@link #reconfigure(double, double, double)}
*
* @return Maximal energy received per one tick
*/
public double maxReceivedPerCycle() { public double maxReceivedPerCycle() {
return b.maxReceivedPerCycle(); return b.maxReceivedPerCycle();
} }
/**
* Allow to dynamically reconfigure your battery.
* Usually it's not very good change battery parameters for already present machines, but if you want...
*
* @param maxCapacity {@link #maxCapacity()}
* @param maxReceivedPerCycle {@link #maxReceivedPerCycle()}
* @param minimumConsumption {@link #minimumConsumption()}
* @return Current battery object instance
*/
public BatteryObject reconfigure(final double maxCapacity, final double maxReceivedPerCycle, final double minimumConsumption) { public BatteryObject reconfigure(final double maxCapacity, final double maxReceivedPerCycle, final double minimumConsumption) {
b = new MjBattery() { b = new MjBattery() {
@Override @Override
@ -138,11 +186,14 @@ public final class MjAPI {
return null; return null;
} }
if (o.getClass() == PowerHandler.class) { if (o instanceof IBatteryProvider) {
return ((PowerHandler) o).getMjBattery(); BatteryObject battery = ((IBatteryProvider) o).getMjBattery();
if (battery != null) {
return battery;
}
} }
BatteryField f = getMjBattery(o.getClass()); BatteryField f = getMjBatteryField(o.getClass());
if (f == null) { if (f == null) {
return null; return null;
@ -151,7 +202,6 @@ public final class MjAPI {
obj.o = o; obj.o = o;
obj.f = f.field; obj.f = f.field;
obj.b = f.battery; obj.b = f.battery;
return obj; return obj;
} else { } else {
try { try {
@ -163,14 +213,15 @@ public final class MjAPI {
} }
} }
private static BatteryField getMjBattery(Class c) { private static BatteryField getMjBatteryField(Class c) {
if (!MjBatteries.containsKey(c)) { BatteryField bField = MjBatteries.get(c);
if (bField == null) {
for (Field f : JavaTools.getAllFields(c)) { for (Field f : JavaTools.getAllFields(c)) {
MjBattery battery = f.getAnnotation(MjBattery.class); MjBattery battery = f.getAnnotation(MjBattery.class);
if (battery != null) { if (battery != null) {
f.setAccessible(true); f.setAccessible(true);
BatteryField bField = new BatteryField(); bField = new BatteryField();
bField.field = f; bField.field = f;
bField.battery = battery; bField.battery = battery;
@ -188,13 +239,9 @@ public final class MjAPI {
return bField; return bField;
} }
} }
MjBatteries.put(c, null); MjBatteries.put(c, null);
return null;
} else {
return MjBatteries.get(c);
} }
return bField;
} }
} }

View file

@ -17,12 +17,12 @@ import java.lang.annotation.Target;
/** /**
* This annotation is used for tiles that need to interface with BuildCraft * This annotation is used for tiles that need to interface with BuildCraft
* energy framework, a.k.a MinecraftJoule or MJ. In order to receive power, * energy framework, a.k.a MinecraftJoule or MJ. In order to receive power,
* tiles, need to declare a *public* double field, with the annotation * tiles, need to declare a double field, with the annotation
* MjBattery. BuildCraft machines able to provide power will then connect to * MjBattery. BuildCraft machines able to provide power will then connect to
* these tiles, and feed energy up to max capacity. It's the responsibilty * these tiles, and feed energy up to max capacity. It's the responsibility
* of the implementer to manually decrease the value of the energy, as he * of the implementer to manually decrease the value of the energy, as he
* simulates energy consumption. On each cycle, per power input, machines can * simulates energy consumption. On each cycle, per power input, machines can
* receive up to "maxReceivedPerCyle" units of energy. As an optional behavior, * receive up to "maxReceivedPerCycle" units of energy. As an optional behavior,
* the system can have a minimum amount of energy consumed even if the system * the system can have a minimum amount of energy consumed even if the system
* is at max capacity, modelized by the "minimumConsumption" value. * is at max capacity, modelized by the "minimumConsumption" value.
* *
@ -34,11 +34,18 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Inherited @Inherited
public @interface MjBattery { public @interface MjBattery {
/**
* @return Max energy capacity of battery
*/
double maxCapacity() default 100.0; double maxCapacity() default 100.0;
/**
* @return Max energy received per one tick
*/
double maxReceivedPerCycle() default 10.0; double maxReceivedPerCycle() default 10.0;
/**
* @return Minimal energy for keep machine is active
*/
double minimumConsumption() default 0.1; double minimumConsumption() default 0.1;
} }

View file

@ -32,7 +32,7 @@ import buildcraft.api.mj.MjBattery;
* @see IPowerReceptor * @see IPowerReceptor
* @see IPowerEmitter * @see IPowerEmitter
*/ */
public final class PowerHandler { public final class PowerHandler implements MjAPI.IBatteryProvider {
public static enum Type { public static enum Type {
@ -181,6 +181,7 @@ public final class PowerHandler {
return battery.getEnergyStored(); return battery.getEnergyStored();
} }
@Override
public MjAPI.BatteryObject getMjBattery() { public MjAPI.BatteryObject getMjBattery() {
return battery; return battery;
} }