Skip to content

Commit

Permalink
Fix potential missed updates in the level emitter. (#173)
Browse files Browse the repository at this point in the history
* Fix potential missed updates in the level emitter.

This makes the emitter tickable, but sleeping most of the time so the performance impact should be minimal.
If an update is ignored due to the configured delay, ticking is scheduled to make sure that the update happens if no further network updates happen until the next delay period.

* Attempt #2: Delay the first tick of the level emitter on load

* Revert "NetworkMonitor optimization - do not rebuild cache more than once per tick"

This reverts commit 09b2531.

* spaces->tabs to match existing code
  • Loading branch information
eigenraven authored Sep 1, 2022
1 parent 1a1c9f8 commit 08d0ef6
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 9 deletions.
5 changes: 1 addition & 4 deletions src/main/java/appeng/me/cache/NetworkMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>

private boolean sendEvent = false;
private boolean hasChanged = false;
private boolean ticked = true;
@Nonnegative
private int localDepthSemaphore = 0;

Expand Down Expand Up @@ -134,10 +133,9 @@ public int getSlot()
@Override
public IItemList<T> getStorageList()
{
if( hasChanged && ticked )
if( this.hasChanged )
{
this.hasChanged = false;
ticked = false;
this.cachedList.resetStatus();
return this.getAvailableItems( this.cachedList );
}
Expand Down Expand Up @@ -331,7 +329,6 @@ void forceUpdate()

void onTick()
{
ticked = true;
if( this.sendEvent )
{
this.sendEvent = false;
Expand Down
64 changes: 59 additions & 5 deletions src/main/java/appeng/parts/automation/PartLevelEmitter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@


import appeng.api.config.*;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.*;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergyWatcher;
Expand All @@ -32,6 +33,9 @@
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStackWatcher;
import appeng.api.networking.storage.IStackWatcherHost;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartRenderHelper;
import appeng.api.storage.IMEMonitor;
Expand All @@ -44,6 +48,7 @@
import appeng.api.util.IConfigManager;
import appeng.client.texture.CableBusTextures;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.sync.GuiBridge;
import appeng.helpers.Reflected;
import appeng.me.GridAccessException;
Expand Down Expand Up @@ -71,7 +76,7 @@


public class PartLevelEmitter extends PartUpgradeable
implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>, ICraftingProvider
implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>, ICraftingProvider, IGridTickable
{

private static final int FLAG_ON = 8;
Expand All @@ -91,6 +96,7 @@ public class PartLevelEmitter extends PartUpgradeable
private double centerZ;

private int lastWorkingTick = 0;
private boolean delayedUpdatesQueued = false;

@Reflected
public PartLevelEmitter( final ItemStack is )
Expand All @@ -101,6 +107,10 @@ public PartLevelEmitter( final ItemStack is )
this.getConfigManager().registerSetting( Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL );
this.getConfigManager().registerSetting( Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL );
this.getConfigManager().registerSetting( Settings.CRAFT_VIA_REDSTONE, YesNo.NO );

// Workaround the emitter randomly breaking on world load
delayedUpdatesQueued = true;
lastWorkingTick = MinecraftServer.getServer().getTickCounter();
}

public long getReportingValue()
Expand Down Expand Up @@ -371,13 +381,57 @@ public boolean isValid( final Object effectiveGrid )
}

@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final BaseActionSource actionSource )
public TickingRequest getTickingRequest( IGridNode node )
{
return new TickingRequest( AEConfig.instance.levelEmitterDelay / 2, AEConfig.instance.levelEmitterDelay, !delayedUpdatesQueued, true );
}

private boolean canDoWork()
{
int currentTick = MinecraftServer.getServer().getTickCounter();
if (currentTick - lastWorkingTick > AEConfig.instance.levelEmitterDelay)
return ( currentTick - lastWorkingTick ) > AEConfig.instance.levelEmitterDelay;
}

@Override
public TickRateModulation tickingRequest( IGridNode node, int TicksSinceLastCall )
{
if( delayedUpdatesQueued && canDoWork() )
{
delayedUpdatesQueued = false;
lastWorkingTick = MinecraftServer.getServer().getTickCounter();
this.onListUpdate();
}
return delayedUpdatesQueued ? TickRateModulation.IDLE : TickRateModulation.SLEEP;
}

@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final BaseActionSource actionSource )
{
if( canDoWork() )
{
this.updateReportingValue((IMEMonitor<IAEItemStack>) monitor);
lastWorkingTick = currentTick;
if ( delayedUpdatesQueued )
{
delayedUpdatesQueued = false;
try
{
this.getProxy().getTick().sleepDevice( this.getProxy().getNode() );
} catch( GridAccessException e )
{
AELog.error( e, "Couldn't put level emitter to sleep after cancelling delayed updates" );
}
}
lastWorkingTick = MinecraftServer.getServer().getTickCounter();
this.updateReportingValue( (IMEMonitor<IAEItemStack>) monitor );
} else if( !delayedUpdatesQueued )
{
delayedUpdatesQueued = true;
try
{
this.getProxy().getTick().alertDevice( this.getProxy().getNode() );
} catch( GridAccessException e )
{
AELog.error( e, "Couldn't wake up level emitter for delayed updates" );
}
}
}

Expand Down

0 comments on commit 08d0ef6

Please sign in to comment.