Added Energy Watcher API

Added Event to Recalculate Channel Requirements for a Node.
Level Emitter can now output redstone based on network energy levels.
Level Emitter's entry field can now hold longs ( text box supports up o trillions )
This commit is contained in:
AlgorithmX2
2014-02-21 00:10:38 -06:00
parent b23aab81e6
commit eb15bd3a68
11 changed files with 405 additions and 16 deletions
@@ -5,7 +5,11 @@ import java.io.IOException;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.InventoryPlayer;
import org.lwjgl.input.Mouse;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
@@ -14,6 +18,7 @@ import appeng.container.implementations.ContainerLevelEmitter;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketConfigButton;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.automation.PartLevelEmitter;
@@ -25,6 +30,8 @@ public class GuiLevelEmitter extends GuiUpgradeable
GuiButton plus1, plus10, plus100, plus1000;
GuiButton minus1, minus10, minus100, minus1000;
GuiImgButton levelMode;
public GuiLevelEmitter(InventoryPlayer inventoryPlayer, PartLevelEmitter te) {
super( new ContainerLevelEmitter( inventoryPlayer, te ) );
}
@@ -34,7 +41,7 @@ public class GuiLevelEmitter extends GuiUpgradeable
{
super.initGui();
level = new GuiTextField( fontRendererObj, this.guiLeft + 44, this.guiTop + 43, 59, fontRendererObj.FONT_HEIGHT );
level = new GuiTextField( fontRendererObj, this.guiLeft + 24, this.guiTop + 43, 79, fontRendererObj.FONT_HEIGHT );
level.setEnableBackgroundDrawing( false );
level.setMaxStringLength( 16 );
level.setTextColor( 0xFFFFFF );
@@ -46,8 +53,9 @@ public class GuiLevelEmitter extends GuiUpgradeable
@Override
protected void addButtons()
{
redstoneMode = new GuiImgButton( this.guiLeft - 18, guiTop + 8, Settings.REDSTONE_EMITTER, RedstoneMode.LOW_SIGNAL );
fuzzyMode = new GuiImgButton( this.guiLeft - 18, guiTop + 28, Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL );
levelMode = new GuiImgButton( this.guiLeft - 18, guiTop + 8, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL );
redstoneMode = new GuiImgButton( this.guiLeft - 18, guiTop + 28, Settings.REDSTONE_EMITTER, RedstoneMode.LOW_SIGNAL );
fuzzyMode = new GuiImgButton( this.guiLeft - 18, guiTop + 48, Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL );
buttonList.add( plus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 17, 22, 20, "+1" ) );
buttonList.add( plus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 17, 28, 20, "+10" ) );
@@ -59,6 +67,7 @@ public class GuiLevelEmitter extends GuiUpgradeable
buttonList.add( minus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 59, 32, 20, "-100" ) );
buttonList.add( minus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 59, 38, 20, "-1000" ) );
buttonList.add( levelMode );
buttonList.add( redstoneMode );
buttonList.add( fuzzyMode );
}
@@ -68,6 +77,18 @@ public class GuiLevelEmitter extends GuiUpgradeable
{
super.actionPerformed( btn );
boolean backwards = Mouse.isButtonDown( 1 );
try
{
if ( btn == levelMode )
NetworkHandler.instance.sendToServer( new PacketConfigButton( levelMode.getSetting(), backwards ) );
}
catch (IOException e)
{
AELog.error( e );
}
if ( btn == plus1 )
addQty( 1 );
if ( btn == plus10 )
@@ -86,7 +107,7 @@ public class GuiLevelEmitter extends GuiUpgradeable
addQty( -1000 );
}
private void addQty(int i)
private void addQty(long i)
{
try
{
@@ -163,6 +184,15 @@ public class GuiLevelEmitter extends GuiUpgradeable
}
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY)
{
super.drawFG( offsetX, offsetY, mouseX, mouseY );
if ( levelMode != null )
levelMode.set( ((ContainerLevelEmitter) cvb).lvType );
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY)
{
+4
View File
@@ -14,6 +14,7 @@ import appeng.api.config.ActionItems;
import appeng.api.config.CondenserOuput;
import appeng.api.config.FullnessMode;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.OperationMode;
import appeng.api.config.PowerUnits;
import appeng.api.config.RedstoneMode;
@@ -135,6 +136,9 @@ public class GuiImgButton extends GuiButton implements ITooltip
registerApp( 16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.NEI_AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_NEIAuto );
registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.NEI_MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_NEIStandard );
registerApp( 16 * 5 + 3, Settings.LEVEL_TYPE, LevelType.ENERGY_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Energy );
registerApp( 16 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Item );
registerApp( 64, Settings.SORT_BY, SortOrder.NAME, ButtonToolTips.SortBy, ButtonToolTips.ItemName );
registerApp( 65, Settings.SORT_BY, SortOrder.AMOUNT, ButtonToolTips.SortBy, ButtonToolTips.NumberOfItems );
// registerApp( 66, Settings.SORT_BY, SortOrder.PRIORITY,
@@ -9,6 +9,7 @@ import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
@@ -27,6 +28,7 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
{
PartLevelEmitter lvlEmitter;
long EmitterValue = -1;
@SideOnly(Side.CLIENT)
public GuiTextField textField;
@@ -56,18 +58,16 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
return false;
}
int EmitterValue = -1;
public void setLevel(int newValue, EntityPlayer player)
public void setLevel(long l, EntityPlayer player)
{
lvlEmitter.setReportingValue( newValue );
EmitterValue = newValue;
lvlEmitter.setReportingValue( l );
EmitterValue = l;
}
@Override
protected void setupConfig()
{
int x = 80 + 34;
int x = 80 + 44;
int y = 40;
IInventory upgrades = myte.getInventoryByName( "upgrades" );
@@ -84,6 +84,8 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
addSlotToContainer( new SlotFakeTypeOnly( inv, 0, x, y ) );
}
public LevelType lvType;
@Override
public void detectAndSendChanges()
{
@@ -105,11 +107,16 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
icrafting.sendProgressBarUpdate( this, 1, (int) this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE ).ordinal() );
}
if ( this.lvType != this.myte.getConfigManager().getSetting( Settings.LEVEL_TYPE ) )
{
icrafting.sendProgressBarUpdate( this, 2, (int) this.myte.getConfigManager().getSetting( Settings.LEVEL_TYPE ).ordinal() );
}
if ( this.EmitterValue != lvlEmitter.getReportingValue() )
{
try
{
NetworkHandler.instance.sendTo( new PacketProgressBar( 2, (int) lvlEmitter.getReportingValue() ), (EntityPlayerMP) icrafting );
NetworkHandler.instance.sendTo( new PacketProgressBar( 3, lvlEmitter.getReportingValue() ), (EntityPlayerMP) icrafting );
}
catch (IOException e)
{
@@ -119,7 +126,8 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
}
}
this.EmitterValue = (int) lvlEmitter.getReportingValue();
this.EmitterValue = lvlEmitter.getReportingValue();
this.lvType = (LevelType) this.myte.getConfigManager().getSetting( Settings.LEVEL_TYPE );
this.fzMode = (FuzzyMode) this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE );
this.rsMode = (RedstoneMode) this.myte.getConfigManager().getSetting( Settings.REDSTONE_EMITTER );
}
@@ -133,6 +141,17 @@ public class ContainerLevelEmitter extends ContainerUpgradeable
super.updateProgressBar( idx, value );
if ( idx == 2 )
{
lvType = LevelType.values()[value];
}
}
@Override
public void updateFullProgressBar(int idx, long value)
{
super.updateFullProgressBar( idx, value );
if ( idx == 3 )
{
EmitterValue = value;
if ( textField != null )
+3 -1
View File
@@ -30,7 +30,9 @@ public enum ButtonToolTips
MoveWhenEmpty, MoveWhenWorkIsDone, MoveWhenFull, Disabled, Enable,
Blocking, NonBlocking, Craft, DontCraft;
Blocking, NonBlocking, Craft, DontCraft,
LevelType, LevelType_Energy, LevelType_Item;
String root;
+1 -1
View File
@@ -55,7 +55,7 @@ public class PacketValueConfig extends AppEngPacket
else if ( Name.equals( "LevelEmitter.Value" ) && c instanceof ContainerLevelEmitter )
{
ContainerLevelEmitter lvc = (ContainerLevelEmitter) c;
lvc.setLevel( Integer.parseInt( Value ), player );
lvc.setLevel( Long.parseLong( Value ), player );
return;
}
else if ( Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench )
+47
View File
@@ -1,9 +1,11 @@
package appeng.me.cache;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
@@ -16,11 +18,17 @@ import appeng.api.networking.IGridStorage;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergyGridProvider;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerIdleChange;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.events.MENetworkPowerStorage;
import appeng.api.networking.storage.IStackWatcherHost;
import appeng.core.AELog;
import appeng.me.GridNode;
import appeng.me.energy.EnergyThreshold;
import appeng.me.energy.EnergyWatcher;
public class EnergyGridCache implements IEnergyGrid
{
@@ -67,6 +75,9 @@ public class EnergyGridCache implements IEnergyGrid
IAEPowerStorage lastRequestor;
Set<IAEPowerStorage> requesters = new LinkedHashSet();
public TreeSet<EnergyThreshold> interests = new TreeSet<EnergyThreshold>();
private HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<IGridNode, IEnergyWatcher>();
private double buffer()
{
return providers.isEmpty() ? 1000.0 : 0.0;
@@ -232,6 +243,14 @@ public class EnergyGridCache implements IEnergyGrid
}
}
if ( machine instanceof IEnergyWatcherHost )
{
IEnergyWatcherHost swh = (IEnergyWatcherHost) machine;
EnergyWatcher iw = new EnergyWatcher( this, (IEnergyWatcherHost) swh );
watchers.put( node, iw );
swh.updateWatcher( iw );
}
myGrid.postEventTo( node, new MENetworkPowerStatusChange() );
}
@@ -261,11 +280,39 @@ public class EnergyGridCache implements IEnergyGrid
providers.remove( machine );
requesters.remove( machine );
}
if ( machine instanceof IStackWatcherHost )
{
IEnergyWatcher myWatcher = watchers.get( machine );
if ( myWatcher != null )
{
myWatcher.clear();
watchers.remove( machine );
}
}
}
double lastStoredPower = -1;
@Override
public void onUpdateTick()
{
if ( !interests.isEmpty() )
{
double oldPower = lastStoredPower;
lastStoredPower = getStoredPower();
if ( Math.abs( oldPower - lastStoredPower ) > 1000 )
AELog.info( "Hi" );
EnergyThreshold low = new EnergyThreshold( Math.min( oldPower, lastStoredPower ), null );
EnergyThreshold high = new EnergyThreshold( Math.max( oldPower, lastStoredPower ), null );
for (EnergyThreshold th : interests.subSet( low, true, high, true ))
{
((EnergyWatcher) th.watcher).post( this );
}
}
avgDrainPerTick *= (AvgLength - 1) / AvgLength;
avgInjectionPerTick *= (AvgLength - 1) / AvgLength;
+15
View File
@@ -16,7 +16,9 @@ import appeng.api.networking.IGridMultiblock;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridStorage;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelChanged;
import appeng.api.networking.events.MENetworkControllerChange;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.pathing.ControllerState;
import appeng.api.networking.pathing.IPathingGrid;
import appeng.api.util.DimensionalCoord;
@@ -212,6 +214,19 @@ public class PathGridCache implements IPathingGrid
repath();
}
@MENetworkEventSubscribe
void updateNodReq(MENetworkChannelChanged ev)
{
IGridNode gridNode = ev.node;
if ( gridNode.getGridBlock().getFlags().contains( GridFlags.REQUIRE_CHANNEL ) )
requireChannels.add( gridNode );
else
requireChannels.remove( gridNode );
repath();
}
private void recalcController()
{
recalculateControllerNextTick = false;
+35
View File
@@ -0,0 +1,35 @@
package appeng.me.energy;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.util.ItemSorters;
public class EnergyThreshold implements Comparable<EnergyThreshold>
{
public final double Limit;
public final IEnergyWatcher watcher;
final int hash;
public EnergyThreshold(double lim, IEnergyWatcher wat) {
Limit = lim;
watcher = wat;
if ( watcher != null )
hash = watcher.hashCode() ^ ((Double) lim).hashCode();
else
hash = ((Double) lim).hashCode();
}
@Override
public int hashCode()
{
return hash;
}
@Override
public int compareTo(EnergyThreshold o)
{
return ItemSorters.comparDouble( Limit, o.Limit );
}
}
+178
View File
@@ -0,0 +1,178 @@
package appeng.me.energy;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
import appeng.me.cache.EnergyGridCache;
/**
* Maintain my interests, and a global watch list, they should always be fully synchronized.
*/
public class EnergyWatcher implements IEnergyWatcher
{
class EnergyWatcherIterator implements Iterator<Double>
{
final EnergyWatcher watcher;
final Iterator<EnergyThreshold> interestIterator;
EnergyThreshold myLast;
public EnergyWatcherIterator(EnergyWatcher parent, Iterator<EnergyThreshold> i) {
watcher = parent;
interestIterator = i;
}
@Override
public boolean hasNext()
{
return interestIterator.hasNext();
}
@Override
public Double next()
{
myLast = interestIterator.next();
return myLast.Limit;
}
@Override
public void remove()
{
gsc.interests.remove( myLast );
interestIterator.remove();
}
};
EnergyGridCache gsc;
IEnergyWatcherHost myObject;
HashSet<EnergyThreshold> myInterests = new HashSet();
public void post(EnergyGridCache energyGridCache)
{
myObject.onThreshholdPass( energyGridCache );
}
public EnergyWatcher(EnergyGridCache cache, IEnergyWatcherHost host) {
gsc = cache;
myObject = host;
}
public IEnergyWatcherHost getHost()
{
return myObject;
}
@Override
public boolean add(Double e)
{
if ( myInterests.contains( e ) )
return false;
EnergyThreshold eh = new EnergyThreshold( e, this );
return gsc.interests.add( eh ) && myInterests.add( eh );
}
@Override
public boolean addAll(Collection<? extends Double> c)
{
boolean didChange = false;
for (Double o : c)
didChange = add( o ) || didChange;
return didChange;
}
@Override
public void clear()
{
Iterator<EnergyThreshold> i = myInterests.iterator();
while (i.hasNext())
{
gsc.interests.remove( i.next() );
i.remove();
}
}
@Override
public boolean contains(Object o)
{
return myInterests.contains( o );
}
@Override
public boolean containsAll(Collection<?> c)
{
return myInterests.containsAll( c );
}
@Override
public boolean isEmpty()
{
return myInterests.isEmpty();
}
@Override
public Iterator<Double> iterator()
{
return new EnergyWatcherIterator( this, myInterests.iterator() );
}
@Override
public boolean remove(Object o)
{
EnergyThreshold eh = new EnergyThreshold( (Double) o, this );
return myInterests.remove( eh ) && gsc.interests.remove( eh );
}
@Override
public boolean removeAll(Collection<?> c)
{
boolean didSomething = false;
for (Object o : c)
didSomething = remove( o ) || didSomething;
return didSomething;
}
@Override
public boolean retainAll(Collection<?> c)
{
boolean changed = false;
Iterator<Double> i = iterator();
while (i.hasNext())
{
if ( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public int size()
{
return myInterests.size();
}
@Override
public Object[] toArray()
{
return myInterests.toArray();
}
@Override
public <T> T[] toArray(T[] a)
{
return myInterests.toArray( a );
}
}
+52 -2
View File
@@ -15,9 +15,13 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -43,7 +47,7 @@ import appeng.util.Platform;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>
public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherHost, IStackWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>
{
final int FLAG_ON = 4;
@@ -56,6 +60,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
long reportingValue = 0;
IStackWatcher myWatcher;
IEnergyWatcher myEnergyWatcher;
public long getReportingValue()
{
@@ -65,7 +70,10 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
public void setReportingValue(long v)
{
reportingValue = v;
updateState();
if ( getConfigManager().getSetting( Settings.LEVEL_TYPE ) == LevelType.ENERGY_LEVEL )
confgiureWatchers();
else
updateState();
}
@MENetworkEventSubscribe
@@ -134,6 +142,13 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
confgiureWatchers();
}
@Override
public void updateWatcher(IEnergyWatcher newWatcher)
{
myEnergyWatcher = newWatcher;
confgiureWatchers();
}
// update the system...
public void confgiureWatchers()
{
@@ -141,6 +156,32 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
if ( myWatcher != null )
myWatcher.clear();
if ( myEnergyWatcher != null )
myEnergyWatcher.clear();
if ( getConfigManager().getSetting( Settings.LEVEL_TYPE ) == LevelType.ENERGY_LEVEL )
{
if ( myEnergyWatcher != null )
myEnergyWatcher.add( (double) reportingValue );
try
{
// update to power...
lastReportedValue = (long) proxy.getEnergy().getStoredPower();
updateState();
// no more item stuf..
proxy.getStorage().getItemInventory().removeListener( this );
}
catch (GridAccessException e)
{
// :P
}
return;
}
try
{
if ( getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null )
@@ -236,6 +277,13 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
}
}
@Override
public void onThreshholdPass(IEnergyGrid energyGrid)
{
lastReportedValue = (long) energyGrid.getStoredPower();
updateState();
}
@Override
public void onStackChange(IItemList o, IAEStack fullStack, IAEStack diffStack, BaseActionSource src, StorageChannel chan)
{
@@ -250,6 +298,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
super( PartLevelEmitter.class, is );
getConfigManager().registerSetting( Settings.REDSTONE_EMITTER, RedstoneMode.HIGH_SIGNAL );
getConfigManager().registerSetting( Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL );
getConfigManager().registerSetting( Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL );
}
@Override
@@ -526,4 +575,5 @@ public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHo
return super.getInventoryByName( name );
}
}
+9
View File
@@ -28,6 +28,15 @@ public class ItemSorters
return 1;
}
public static int comparDouble(double a, double b)
{
if ( a == b )
return 0;
if ( a < b )
return -1;
return 1;
}
public static Comparator<IAEItemStack> ConfigBased_SortByName = new Comparator<IAEItemStack>() {
@Override