1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Make monitors non-ticking

- Convert terminals from a polling-based system to a more event-driven
   one: they now accept an onChanged callback, which marks the parent as
   dirty.
 - Schedule ticks when monitors are marked as dirty.
 - Add several missing @Overrides. This has nothing to do with the rest
   of the changes, but I'm bad at good git practice.
This commit is contained in:
SquidDev 2019-01-20 15:35:48 +00:00
parent 8a7e651c99
commit 83b01d35eb
13 changed files with 137 additions and 102 deletions

View File

@ -16,6 +16,7 @@ public interface ILuaAPI extends dan200.computercraft.api.lua.ILuaAPI
{
void advance( double v );
@Override
default void update()
{
advance( 0.05 );

View File

@ -26,12 +26,14 @@ public ResourceQueue()
{
}
@Override
public synchronized void shutdown()
{
super.shutdown();
pending.clear();
}
@Override
public synchronized boolean queue( Supplier<T> resource )
{
if( !active ) return false;
@ -40,6 +42,7 @@ public synchronized boolean queue( Supplier<T> resource )
return true;
}
@Override
public synchronized void release( T resource )
{
super.release( resource );

View File

@ -239,6 +239,7 @@ void success( ILuaObject object )
if( tryClose() ) environment.queueEvent( SUCCESS_EVENT, new Object[] { address, object } );
}
@Override
protected void dispose()
{
super.dispose();

View File

@ -29,11 +29,18 @@ public class Terminal
private final Palette m_palette;
private boolean m_changed;
private final Runnable onChanged;
public Terminal( int width, int height )
{
this( width, height, null );
}
public Terminal( int width, int height, Runnable changedCallback )
{
m_width = width;
m_height = height;
this.onChanged = changedCallback;
m_cursorColour = 0;
m_cursorBackgroundColour = 15;
@ -65,7 +72,7 @@ public synchronized void reset()
m_cursorY = 0;
m_cursorBlink = false;
clear();
m_changed = true;
setChanged();
m_palette.resetColours();
}
@ -122,7 +129,7 @@ else if( m_width == oldWidth )
m_backgroundColour[i].write( oldBackgroundColour[i] );
}
}
m_changed = true;
setChanged();
}
public void setCursorPos( int x, int y )
@ -131,7 +138,7 @@ public void setCursorPos( int x, int y )
{
m_cursorX = x;
m_cursorY = y;
m_changed = true;
setChanged();
}
}
@ -140,7 +147,7 @@ public void setCursorBlink( boolean blink )
if( m_cursorBlink != blink )
{
m_cursorBlink = blink;
m_changed = true;
setChanged();
}
}
@ -149,7 +156,7 @@ public void setTextColour( int colour )
if( m_cursorColour != colour )
{
m_cursorColour = colour;
m_changed = true;
setChanged();
}
}
@ -158,7 +165,7 @@ public void setBackgroundColour( int colour )
if( m_cursorBackgroundColour != colour )
{
m_cursorBackgroundColour = colour;
m_changed = true;
setChanged();
}
}
@ -201,7 +208,7 @@ public synchronized void blit( String text, String textColour, String background
m_text[y].write( text, x );
m_textColour[y].write( textColour, x );
m_backgroundColour[y].write( backgroundColour, x );
m_changed = true;
setChanged();
}
}
@ -214,7 +221,7 @@ public synchronized void write( String text )
m_text[y].write( text, x );
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
m_changed = true;
setChanged();
}
}
@ -244,7 +251,7 @@ public synchronized void scroll( int yDiff )
m_text = newText;
m_textColour = newTextColour;
m_backgroundColour = newBackgroundColour;
m_changed = true;
setChanged();
}
}
@ -256,7 +263,7 @@ public synchronized void clear()
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
}
m_changed = true;
setChanged();
}
public synchronized void clearLine()
@ -267,7 +274,7 @@ public synchronized void clearLine()
m_text[y].fill( ' ' );
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
m_changed = true;
setChanged();
}
}
@ -285,7 +292,7 @@ public synchronized void setLine( int y, String text, String textColour, String
m_text[y].write( text );
m_textColour[y].write( textColour );
m_backgroundColour[y].write( backgroundColour );
m_changed = true;
setChanged();
}
public synchronized TextBuffer getTextColourLine( int y )
@ -306,17 +313,23 @@ public synchronized TextBuffer getBackgroundColourLine( int y )
return null;
}
public boolean getChanged()
/**
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead.
*/
@Deprecated
public final boolean getChanged()
{
return m_changed;
}
public void setChanged()
public final void setChanged()
{
m_changed = true;
if( onChanged != null ) onChanged.run();
}
public void clearChanged()
public final void clearChanged()
{
m_changed = false;
}
@ -371,6 +384,6 @@ public synchronized void readFromNBT( NBTTagCompound nbt )
{
m_palette.readFromNBT( nbt );
}
m_changed = true;
setChanged();
}
}

View File

@ -22,19 +22,14 @@ public ClientTerminal( boolean colour )
m_terminalChanged = false;
}
public void update()
{
if( m_terminal != null )
{
m_terminalChanged |= m_terminal.getChanged();
m_terminal.clearChanged();
}
}
public boolean pollTerminalChanged()
{
boolean changed = m_terminalChanged;
m_terminalChanged = false;
Terminal terminal = m_terminal;
if( terminal != null ) terminal.clearChanged();
return changed;
}
@ -71,7 +66,7 @@ private void resizeTerminal( int width, int height )
{
if( m_terminal == null )
{
m_terminal = new Terminal( width, height );
m_terminal = new Terminal( width, height, () -> m_terminalChanged = true );
m_terminalChanged = true;
}
else

View File

@ -9,35 +9,33 @@
import dan200.computercraft.core.terminal.Terminal;
import net.minecraft.nbt.NBTTagCompound;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerTerminal implements ITerminal
{
private final boolean m_colour;
private Terminal m_terminal;
private boolean m_terminalChanged;
private boolean m_terminalChangedLastFrame;
private final AtomicBoolean m_terminalChanged = new AtomicBoolean( false );
private boolean m_terminalChangedLastFrame = false;
public ServerTerminal( boolean colour )
{
m_colour = colour;
m_terminal = null;
m_terminalChanged = false;
m_terminalChangedLastFrame = false;
}
public ServerTerminal( boolean colour, int terminalWidth, int terminalHeight )
{
m_colour = colour;
m_terminal = new Terminal( terminalWidth, terminalHeight );
m_terminalChanged = false;
m_terminalChangedLastFrame = false;
m_terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
}
public void resize( int width, int height )
protected void resize( int width, int height )
{
if( m_terminal == null )
{
m_terminal = new Terminal( width, height );
m_terminalChanged = true;
m_terminal = new Terminal( width, height, this::markTerminalChanged );
markTerminalChanged();
}
else
{
@ -50,23 +48,21 @@ public void delete()
if( m_terminal != null )
{
m_terminal = null;
m_terminalChanged = true;
markTerminalChanged();
}
}
protected void markTerminalChanged()
{
m_terminalChanged = true;
m_terminalChanged.set( true );
}
public void update()
{
m_terminalChangedLastFrame = m_terminalChanged || (m_terminal != null && m_terminal.getChanged());
if( m_terminal != null )
{
m_terminal.clearChanged();
}
m_terminalChanged = false;
Terminal terminal = m_terminal;
if( terminal != null ) terminal.clearChanged();
m_terminalChangedLastFrame = m_terminalChanged.getAndSet( false );
}
public boolean hasTerminalChanged()

View File

@ -32,10 +32,8 @@ public ClientComputer( int instanceID )
m_instanceID = instanceID;
}
@Override
public void update()
{
super.update();
m_changedLastFrame = m_changed;
m_changed = false;
}

View File

@ -7,7 +7,7 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.common.BlockDirectional;
import dan200.computercraft.shared.common.BlockGeneric;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
@ -39,7 +39,7 @@
import javax.annotation.Nonnull;
public class BlockPeripheral extends BlockDirectional
public class BlockPeripheral extends BlockGeneric
{
public static class Properties
{
@ -466,11 +466,12 @@ public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, Entit
case DiskDrive:
case Printer:
{
if( stack.hasDisplayName() && tile instanceof ITilePeripheral )
EnumFacing dir = DirectionUtil.fromEntityRot( player );
if( stack.hasDisplayName() && tile instanceof TilePeripheralBase )
{
ITilePeripheral peripheral = (ITilePeripheral) tile;
TilePeripheralBase peripheral = (TilePeripheralBase) tile;
peripheral.setLabel( stack.getDisplayName() );
peripheral.setDirection( DirectionUtil.fromEntityRot( player ) );
peripheral.setDirection( dir );
}
break;
}
@ -558,14 +559,18 @@ public int getLightOpacity( IBlockState state )
@Override
@Deprecated
@Nonnull
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess source, BlockPos pos )
public AxisAlignedBB getBoundingBox( IBlockState state, IBlockAccess world, BlockPos pos )
{
if( getPeripheralType( state ) == PeripheralType.WirelessModem )
{
return ModemBounds.getBounds( getDirection( source, pos ) );
TileEntity tile = world.getTileEntity( pos );
if( tile instanceof TileWirelessModem )
{
return ModemBounds.getBounds( ((TileWirelessModem) tile).getDirection() );
}
}
return super.getBoundingBox( state, source, pos );
return super.getBoundingBox( state, world, pos );
}
@Override

View File

@ -6,13 +6,12 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.shared.common.IDirectionalTile;
import dan200.computercraft.shared.peripheral.PeripheralType;
/**
* The tile for {@link BlockPeripheral}.
*/
public interface ITilePeripheral extends IDirectionalTile
public interface ITilePeripheral
{
PeripheralType getPeripheralType();

View File

@ -73,6 +73,7 @@ public String getLabel()
return null;
}
@Override
public void setLabel( String label )
{
m_label = label;

View File

@ -8,12 +8,16 @@
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.util.TickScheduler;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerMonitor extends ServerTerminal
{
private final TileMonitor origin;
private int textScale = 2;
private boolean resized;
private final AtomicBoolean resized = new AtomicBoolean( false );
private final AtomicBoolean changed = new AtomicBoolean( false );
public ServerMonitor( boolean colour, TileMonitor origin )
{
@ -41,10 +45,28 @@ public synchronized void rebuild()
if( oldWidth != termWidth || oldHeight != termHeight )
{
getTerminal().clear();
resized = true;
resized.set( true );
markChanged();
}
}
@Override
protected void markTerminalChanged()
{
super.markTerminalChanged();
markChanged();
}
private void markChanged()
{
if( !changed.getAndSet( true ) ) TickScheduler.schedule( origin );
}
protected void clearChanged()
{
changed.set( false );
}
public int getTextScale()
{
return textScale;
@ -57,14 +79,14 @@ public synchronized void setTextScale( int textScale )
rebuild();
}
public synchronized boolean pollResized()
public boolean pollResized()
{
if( resized )
{
resized = false;
return true;
}
return resized.getAndSet( false );
}
return false;
public boolean pollTerminalChanged()
{
update();
return hasTerminalChanged();
}
}

View File

@ -11,15 +11,20 @@
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.common.ServerTerminal;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.common.ITilePeripheral;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -28,7 +33,7 @@
import java.util.HashSet;
import java.util.Set;
public class TileMonitor extends TilePeripheralBase
public class TileMonitor extends TileGeneric implements ITilePeripheral, IPeripheralTile
{
// Statics
@ -78,6 +83,7 @@ public void onLoad()
super.onLoad();
m_advanced = getBlockState().getValue( BlockPeripheral.Properties.VARIANT )
.getPeripheralType() == PeripheralType.AdvancedMonitor;
world.scheduleUpdate( getPos(), getBlockType(), 0 );
}
@Override
@ -146,44 +152,32 @@ public void readFromNBT( NBTTagCompound nbt )
}
@Override
public void update()
public void updateTick()
{
super.update();
if( m_xIndex != 0 || m_yIndex != 0 || m_serverMonitor == null ) return;
if( !getWorld().isRemote )
m_serverMonitor.clearChanged();
if( m_serverMonitor.pollResized() )
{
if( m_xIndex == 0 && m_yIndex == 0 && m_serverMonitor != null )
for( int x = 0; x < m_width; x++ )
{
if( m_serverMonitor.pollResized() )
for( int y = 0; y < m_height; y++ )
{
for( int x = 0; x < m_width; x++ )
{
for( int y = 0; y < m_height; y++ )
{
TileMonitor monitor = getNeighbour( x, y );
if( monitor == null ) continue;
TileMonitor monitor = getNeighbour( x, y );
if( monitor == null ) continue;
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
} );
}
}
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
} );
}
}
}
}
m_serverMonitor.update();
if( m_serverMonitor.hasTerminalChanged() ) updateBlock();
}
}
else
{
if( m_xIndex == 0 && m_yIndex == 0 && m_clientMonitor != null )
{
m_clientMonitor.update();
}
}
if( m_serverMonitor.pollTerminalChanged() ) updateBlock();
}
// IPeripheralTile implementation
@ -197,6 +191,12 @@ public IPeripheral getPeripheral( EnumFacing side )
return m_peripheral;
}
@Override
public PeripheralType getPeripheralType()
{
return m_advanced ? PeripheralType.AdvancedMonitor : PeripheralType.Monitor;
}
public ServerMonitor getCachedServerMonitor()
{
return m_serverMonitor;
@ -319,7 +319,6 @@ public final void readDescription( @Nonnull NBTTagCompound nbt )
}
// Sizing and placement stuff
@Override
public EnumFacing getDirection()
{
int dir = getDir() % 6;
@ -444,7 +443,7 @@ private TileMonitor getNeighbour( int x, int y )
return getSimilarMonitorAt( pos.offset( right, xOffset ).offset( down, yOffset ) );
}
public TileMonitor getOrigin()
private TileMonitor getOrigin()
{
return getNeighbour( 0, 0 );
}
@ -752,15 +751,16 @@ public boolean shouldRefresh( World world, BlockPos pos, @Nonnull IBlockState ol
{
case Monitor:
case AdvancedMonitor:
{
return false;
}
default:
{
return true;
}
}
}
}
@Override
public void getDroppedItems( @Nonnull NonNullList<ItemStack> drops, boolean creative )
{
if( !creative ) drops.add( PeripheralItemFactory.create( this ) );
}
}

View File

@ -177,6 +177,7 @@ public synchronized void updateValues( Entity entity, @Nonnull ItemStack stack,
}
}
@Override
public void broadcastState( boolean force )
{
super.broadcastState( force );