mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-15 03:35:42 +00:00
Use a separate object for tracking TickScheduler state
This allows us to use non-TileGeneric block entities. This is a clever trick which will help us later!
This commit is contained in:
parent
562f224c01
commit
1f910ee2ba
@ -19,17 +19,9 @@ import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public abstract class TileGeneric extends TileEntity
|
||||
{
|
||||
/**
|
||||
* Is this block enqueued to be updated next tick? This should only be read/written by the tick scheduler.
|
||||
*
|
||||
* @see dan200.computercraft.shared.util.TickScheduler
|
||||
*/
|
||||
public final AtomicBoolean scheduled = new AtomicBoolean();
|
||||
|
||||
public TileGeneric( TileEntityType<? extends TileGeneric> type )
|
||||
{
|
||||
super( type );
|
||||
|
@ -89,8 +89,9 @@ public class TileCable extends TileGeneric
|
||||
private final WiredModemElement cable = new CableElement();
|
||||
private LazyOptional<IWiredElement> elementCap;
|
||||
private final IWiredNode node = cable.getNode();
|
||||
private final TickScheduler.Token tickToken = new TickScheduler.Token( this );
|
||||
private final WiredModemPeripheral modem = new WiredModemPeripheral(
|
||||
new ModemState( () -> TickScheduler.schedule( this ) ),
|
||||
new ModemState( () -> TickScheduler.schedule( tickToken ) ),
|
||||
cable
|
||||
)
|
||||
{
|
||||
@ -170,7 +171,7 @@ public class TileCable extends TileGeneric
|
||||
public void onLoad()
|
||||
{
|
||||
super.onLoad();
|
||||
TickScheduler.schedule( this );
|
||||
TickScheduler.schedule( tickToken );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,7 +247,7 @@ public class TileCable extends TileGeneric
|
||||
{
|
||||
if( invalidPeripheral ) return;
|
||||
invalidPeripheral = true;
|
||||
TickScheduler.schedule( this );
|
||||
TickScheduler.schedule( tickToken );
|
||||
}
|
||||
|
||||
private void refreshPeripheral()
|
||||
|
@ -100,7 +100,8 @@ public class TileWiredModemFull extends TileGeneric
|
||||
private boolean destroyed = false;
|
||||
private boolean connectionsFormed = false;
|
||||
|
||||
private final ModemState modemState = new ModemState( () -> TickScheduler.schedule( this ) );
|
||||
private final TickScheduler.Token tickToken = new TickScheduler.Token( this );
|
||||
private final ModemState modemState = new ModemState( () -> TickScheduler.schedule( tickToken ) );
|
||||
private final WiredModemElement element = new FullElement( this );
|
||||
private LazyOptional<IWiredElement> elementCap;
|
||||
private final IWiredNode node = element.getNode();
|
||||
@ -181,7 +182,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
|
||||
private void queueRefreshPeripheral( @Nonnull Direction facing )
|
||||
{
|
||||
if( invalidSides == 0 ) TickScheduler.schedule( this );
|
||||
if( invalidSides == 0 ) TickScheduler.schedule( tickToken );
|
||||
invalidSides |= 1 << facing.ordinal();
|
||||
}
|
||||
|
||||
@ -263,7 +264,7 @@ public class TileWiredModemFull extends TileGeneric
|
||||
public void onLoad()
|
||||
{
|
||||
super.onLoad();
|
||||
TickScheduler.schedule( this );
|
||||
TickScheduler.schedule( tickToken );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,7 +32,7 @@ public class TileWirelessModem extends TileGeneric
|
||||
|
||||
Peripheral( TileWirelessModem entity )
|
||||
{
|
||||
super( new ModemState( () -> TickScheduler.schedule( entity ) ), entity.advanced );
|
||||
super( new ModemState( () -> TickScheduler.schedule( entity.tickToken ) ), entity.advanced );
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ public class TileWirelessModem extends TileGeneric
|
||||
private final ModemPeripheral modem;
|
||||
private boolean destroyed = false;
|
||||
private LazyOptional<IPeripheral> modemCap;
|
||||
private final TickScheduler.Token tickToken = new TickScheduler.Token( this );
|
||||
|
||||
public TileWirelessModem( TileEntityType<? extends TileWirelessModem> type, boolean advanced )
|
||||
{
|
||||
@ -83,7 +84,7 @@ public class TileWirelessModem extends TileGeneric
|
||||
public void onLoad()
|
||||
{
|
||||
super.onLoad();
|
||||
TickScheduler.schedule( this );
|
||||
TickScheduler.schedule( tickToken );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +64,7 @@ public class ServerMonitor
|
||||
|
||||
private void markChanged()
|
||||
{
|
||||
if( !changed.getAndSet( true ) ) TickScheduler.schedule( origin );
|
||||
if( !changed.getAndSet( true ) ) TickScheduler.schedule( origin.tickToken );
|
||||
}
|
||||
|
||||
int getTextScale()
|
||||
|
@ -75,6 +75,8 @@ public class TileMonitor extends TileGeneric
|
||||
private int bbX, bbY, bbWidth, bbHeight;
|
||||
private AxisAlignedBB boundingBox;
|
||||
|
||||
TickScheduler.Token tickToken = new TickScheduler.Token( this );
|
||||
|
||||
public TileMonitor( TileEntityType<? extends TileMonitor> type, boolean advanced )
|
||||
{
|
||||
super( type );
|
||||
@ -86,7 +88,7 @@ public class TileMonitor extends TileGeneric
|
||||
{
|
||||
super.onLoad();
|
||||
needsValidating = true; // Same, tbh
|
||||
TickScheduler.schedule( this );
|
||||
TickScheduler.schedule( tickToken );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,7 +6,7 @@
|
||||
package dan200.computercraft.shared.util;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.ITickList;
|
||||
import net.minecraft.world.World;
|
||||
@ -16,6 +16,7 @@ import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* A thread-safe version of {@link ITickList#scheduleTick(BlockPos, Object, int)}.
|
||||
@ -29,12 +30,12 @@ public final class TickScheduler
|
||||
{
|
||||
}
|
||||
|
||||
private static final Queue<TileGeneric> toTick = new ConcurrentLinkedDeque<>();
|
||||
private static final Queue<Token> toTick = new ConcurrentLinkedDeque<>();
|
||||
|
||||
public static void schedule( TileGeneric tile )
|
||||
public static void schedule( Token token )
|
||||
{
|
||||
World world = tile.getLevel();
|
||||
if( world != null && !world.isClientSide && !tile.scheduled.getAndSet( true ) ) toTick.add( tile );
|
||||
World world = token.owner.getLevel();
|
||||
if( world != null && !world.isClientSide && !token.scheduled.getAndSet( true ) ) toTick.add( token );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@ -42,19 +43,37 @@ public final class TickScheduler
|
||||
{
|
||||
if( event.phase != TickEvent.Phase.START ) return;
|
||||
|
||||
TileGeneric tile;
|
||||
while( (tile = toTick.poll()) != null )
|
||||
Token token;
|
||||
while( (token = toTick.poll()) != null )
|
||||
{
|
||||
tile.scheduled.set( false );
|
||||
if( tile.isRemoved() ) continue;
|
||||
token.scheduled.set( false );
|
||||
TileEntity blockEntity = token.owner;
|
||||
if( blockEntity.isRemoved() ) continue;
|
||||
|
||||
World world = tile.getLevel();
|
||||
BlockPos pos = tile.getBlockPos();
|
||||
World world = blockEntity.getLevel();
|
||||
BlockPos pos = blockEntity.getBlockPos();
|
||||
|
||||
if( world != null && pos != null && world.isAreaLoaded( pos, 0 ) && world.getBlockEntity( pos ) == tile )
|
||||
if( world != null && world.isAreaLoaded( pos, 0 ) && world.getBlockEntity( pos ) == blockEntity )
|
||||
{
|
||||
world.getBlockTicks().scheduleTick( pos, tile.getBlockState().getBlock(), 0 );
|
||||
world.getBlockTicks().scheduleTick( pos, blockEntity.getBlockState().getBlock(), 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An item which can be scheduled for future ticking.
|
||||
* <p>
|
||||
* This tracks whether the {@link TileEntity} is queued or not, as this is more efficient than maintaining a set.
|
||||
* As such, it should be unique per {@link TileEntity} instance to avoid it being queued multiple times.
|
||||
*/
|
||||
public static class Token
|
||||
{
|
||||
final TileEntity owner;
|
||||
final AtomicBoolean scheduled = new AtomicBoolean();
|
||||
|
||||
public Token( TileEntity owner )
|
||||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user