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
+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 );
}
}