Applied-Energistics-2-tiler.../src/main/java/appeng/me/cache/TickManagerCache.java

245 lines
5.7 KiB
Java
Raw Normal View History

2014-11-14 12:02:52 +01:00
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
2014-09-24 02:26:27 +02:00
package appeng.me.cache;
import java.util.HashMap;
import java.util.PriorityQueue;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ReportedException;
2014-12-29 21:59:05 +01:00
2014-09-24 02:26:27 +02:00
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridStorage;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.ITickManager;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.me.cache.helpers.TickTracker;
public class TickManagerCache implements ITickManager
{
private long currentTick = 0;
final IGrid myGrid;
public TickManagerCache(IGrid g) {
2014-12-29 15:13:47 +01:00
this.myGrid = g;
2014-09-24 02:26:27 +02:00
}
final HashMap<IGridNode, TickTracker> alertable = new HashMap<IGridNode, TickTracker>();
final HashMap<IGridNode, TickTracker> sleeping = new HashMap<IGridNode, TickTracker>();
final HashMap<IGridNode, TickTracker> awake = new HashMap<IGridNode, TickTracker>();
final PriorityQueue<TickTracker> upcomingTicks = new PriorityQueue<TickTracker>();
public long getCurrentTick()
{
2014-12-29 15:13:47 +01:00
return this.currentTick;
2014-09-24 02:26:27 +02:00
}
public long getAvgNanoTime(IGridNode node)
{
2014-12-29 15:13:47 +01:00
TickTracker tt = this.awake.get( node );
2014-09-24 02:26:27 +02:00
if ( tt == null )
2014-12-29 15:13:47 +01:00
tt = this.sleeping.get( node );
2014-09-24 02:26:27 +02:00
if ( tt == null )
return -1;
return tt.getAvgNanos();
}
@Override
public void onUpdateTick()
{
TickTracker tt = null;
try
{
2014-12-29 15:13:47 +01:00
this.currentTick++;
while (!this.upcomingTicks.isEmpty())
2014-09-24 02:26:27 +02:00
{
2014-12-29 15:13:47 +01:00
tt = this.upcomingTicks.peek();
int diff = (int) (this.currentTick - tt.lastTick);
2014-09-24 02:26:27 +02:00
if ( diff >= tt.current_rate )
{
// remove tt..
2014-12-29 15:13:47 +01:00
this.upcomingTicks.poll();
2014-09-24 02:26:27 +02:00
TickRateModulation mod = tt.gt.tickingRequest( tt.node, diff );
2015-02-03 12:04:13 +01:00
2014-09-24 02:26:27 +02:00
switch (mod)
{
case FASTER:
tt.setRate( tt.current_rate - 2 );
break;
case IDLE:
tt.setRate( tt.request.maxTickRate );
break;
case SAME:
break;
case SLEEP:
2014-12-29 15:13:47 +01:00
this.sleepDevice( tt.node );
2014-09-24 02:26:27 +02:00
break;
case SLOWER:
tt.setRate( tt.current_rate + 1 );
break;
case URGENT:
tt.setRate( 0 );
break;
default:
break;
}
2015-02-03 12:04:13 +01:00
2014-12-29 15:13:47 +01:00
if ( this.awake.containsKey( tt.node ) )
this.addToQueue( tt );
2014-09-24 02:26:27 +02:00
}
else
return; // done!
}
}
catch( Throwable t )
{
CrashReport crashreport = CrashReport.makeCrashReport(t, "Ticking GridNode");
CrashReportCategory crashreportcategory = crashreport.makeCategory( tt.gt.getClass().getSimpleName() + " being ticked." );
tt.addEntityCrashInfo(crashreportcategory);
throw new ReportedException(crashreport);
}
}
private void addToQueue(TickTracker tt)
{
2014-12-29 15:13:47 +01:00
tt.lastTick = this.currentTick;
this.upcomingTicks.add( tt );
2014-09-24 02:26:27 +02:00
}
@Override
public boolean alertDevice(IGridNode node)
{
2014-12-29 15:13:47 +01:00
TickTracker tt = this.alertable.get( node );
2014-09-24 02:26:27 +02:00
if ( tt == null )
return false;
// throw new RuntimeException(
// "Invalid alerted device, this node is not marked as alertable, or part of this grid." );
// set to awake, this is for sanity.
2014-12-29 15:13:47 +01:00
this.sleeping.remove( node );
this.awake.put( node, tt );
2014-09-24 02:26:27 +02:00
// configure sort.
tt.lastTick = tt.lastTick - tt.request.maxTickRate;
tt.current_rate = tt.request.minTickRate;
// prevent dupes and tick build up.
2014-12-29 15:13:47 +01:00
this.upcomingTicks.remove( tt );
this.upcomingTicks.add( tt );
2014-09-24 02:26:27 +02:00
return true;
}
@Override
public boolean sleepDevice(IGridNode node)
{
2014-12-29 15:13:47 +01:00
if ( this.awake.containsKey( node ) )
2014-09-24 02:26:27 +02:00
{
2014-12-29 15:13:47 +01:00
TickTracker gt = this.awake.get( node );
this.awake.remove( node );
this.sleeping.put( node, gt );
2014-09-24 02:26:27 +02:00
return true;
}
return false;
}
@Override
public boolean wakeDevice(IGridNode node)
{
2014-12-29 15:13:47 +01:00
if ( this.sleeping.containsKey( node ) )
2014-09-24 02:26:27 +02:00
{
2014-12-29 15:13:47 +01:00
TickTracker gt = this.sleeping.get( node );
this.sleeping.remove( node );
this.awake.put( node, gt );
this.addToQueue( gt );
2014-09-24 02:26:27 +02:00
return true;
}
return false;
}
@Override
public void removeNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof IGridTickable )
{
2014-12-29 15:13:47 +01:00
this.alertable.remove( gridNode );
this.sleeping.remove( gridNode );
this.awake.remove( gridNode );
2014-09-24 02:26:27 +02:00
}
}
@Override
public void addNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof IGridTickable )
{
TickingRequest tr = ((IGridTickable) machine).getTickingRequest( gridNode );
if ( tr != null )
{
2014-12-29 15:13:47 +01:00
TickTracker tt = new TickTracker( tr, gridNode, (IGridTickable) machine, this.currentTick, this );
2014-09-24 02:26:27 +02:00
if ( tr.canBeAlerted )
2014-12-29 15:13:47 +01:00
this.alertable.put( gridNode, tt );
2014-09-24 02:26:27 +02:00
if ( tr.isSleeping )
2014-12-29 15:13:47 +01:00
this.sleeping.put( gridNode, tt );
2014-09-24 02:26:27 +02:00
else
{
2014-12-29 15:13:47 +01:00
this.awake.put( gridNode, tt );
this.addToQueue( tt );
2014-09-24 02:26:27 +02:00
}
}
}
}
@Override
public void onSplit(IGridStorage storageB)
{
}
@Override
public void onJoin(IGridStorage storageB)
{
}
@Override
public void populateGridStorage(IGridStorage storage)
{
}
}