diff --git a/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java b/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java index 0b3111355..ea15ee39f 100644 --- a/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java @@ -10,7 +10,7 @@ import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.TextBuffer; -import dan200.computercraft.shared.common.ClientTerminal; +import dan200.computercraft.shared.peripheral.monitor.ClientMonitor; import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.DirectionUtil; @@ -43,24 +43,22 @@ public class TileEntityMonitorRenderer extends TileEntitySpecialRenderer m_computers; - public long m_lastRenderFrame = -1; // For rendering use only - public int m_renderDisplayList = -1; // For rendering use only - private boolean m_destroyed; private boolean m_ignoreMe; - private boolean m_changed; - private int m_textScale; private int m_width; private int m_height; private int m_xIndex; private int m_yIndex; private int m_dir; - private boolean m_sizeChangedQueued; + + private boolean m_advanced; public TileMonitor() { @@ -69,17 +62,23 @@ public class TileMonitor extends TilePeripheralBase m_destroyed = false; m_ignoreMe = false; - m_textScale = 2; m_width = 1; m_height = 1; m_xIndex = 0; m_yIndex = 0; - m_changed = false; m_dir = 2; } + @Override + public void onLoad() + { + super.onLoad(); + m_advanced = getBlockState().getValue( BlockPeripheral.Properties.VARIANT ) + .getPeripheralType() == PeripheralType.AdvancedMonitor; + } + @Override public void destroy() { @@ -91,11 +90,20 @@ public class TileMonitor extends TilePeripheralBase contractNeighbours(); } } - if( m_renderDisplayList >= 0 ) - { - ComputerCraft.deleteDisplayLists( m_renderDisplayList, 3 ); - m_renderDisplayList = -1; - } + } + + @Override + public void invalidate() + { + super.invalidate(); + if( m_clientMonitor != null && m_xIndex == 0 && m_yIndex == 0 ) m_clientMonitor.destroy(); + } + + @Override + public void onChunkUnload() + { + super.onChunkUnload(); + if( m_clientMonitor != null && m_xIndex == 0 && m_yIndex == 0 ) m_clientMonitor.destroy(); } @Override @@ -143,41 +151,38 @@ public class TileMonitor extends TilePeripheralBase if( !getWorld().isRemote ) { - if( m_sizeChangedQueued ) + if( m_xIndex == 0 && m_yIndex == 0 && m_serverMonitor != null ) { - for( IComputerAccess computer : m_computers ) + if( m_serverMonitor.pollResized() ) { - computer.queueEvent( "monitor_resize", new Object[] { - computer.getAttachmentName() - } ); - } - m_sizeChangedQueued = false; - } + 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; - if( m_serverTerminal != null ) - { - m_serverTerminal.update(); - if( m_serverTerminal.hasTerminalChanged() ) - { - updateBlock(); + for( IComputerAccess computer : monitor.m_computers ) + { + computer.queueEvent( "monitor_resize", new Object[] { + computer.getAttachmentName() + } ); + } + } + } } - } - if( m_clientTerminal != null ) - { - m_clientTerminal.update(); + m_serverMonitor.update(); + if( m_serverMonitor.hasTerminalChanged() ) updateBlock(); } } - } - - public boolean pollChanged() - { - if( m_changed ) + else { - m_changed = false; - return true; + if( m_xIndex == 0 && m_yIndex == 0 && m_clientMonitor != null ) + { + m_clientMonitor.update(); + } } - return false; } // IPeripheralTile implementation @@ -185,24 +190,71 @@ public class TileMonitor extends TilePeripheralBase @Override public IPeripheral getPeripheral( EnumFacing side ) { + hasPeripheral = true; + createServerMonitor(); // Ensure the monitor is created before doing anything else. return new MonitorPeripheral( this ); } - public void setTextScale( int scale ) + public ServerMonitor getCachedServerMonitor() { + return m_serverMonitor; + } + + private ServerMonitor getServerMonitor() + { + if( m_serverMonitor != null ) return m_serverMonitor; + TileMonitor origin = getOrigin(); - if( origin != null ) + if( origin == null ) return null; + + return m_serverMonitor = origin.m_serverMonitor; + } + + private ServerMonitor createServerMonitor() + { + if( m_serverMonitor != null ) { - synchronized( origin ) + return m_serverMonitor; + } + else if( m_xIndex == 0 && m_yIndex == 0 ) + { + // If we're the origin, set up the new monitor + m_serverMonitor = new ServerMonitor( m_advanced, this ); + m_serverMonitor.rebuild(); + + // And propagate it to child monitors + for( int x = 0; x < m_width; x++ ) { - if( origin.m_textScale != scale ) + for( int y = 0; y < m_height; y++ ) { - origin.m_textScale = scale; - origin.rebuildTerminal(); - origin.updateBlock(); + TileMonitor monitor = getNeighbour( x, y ); + if( monitor != null ) monitor.m_serverMonitor = m_serverMonitor; } } + + return m_serverMonitor; } + else + { + // Otherwise fetch the origin and attempt to get its monitor + // Note this may load chunks, but we don't really have a choice here. + BlockPos pos = getPos(); + TileEntity te = world.getTileEntity( pos.offset( getRight(), -m_xIndex ).offset( getDown(), -m_yIndex ) ); + if( !(te instanceof TileMonitor) ) return null; + + return m_serverMonitor = ((TileMonitor) te).createServerMonitor(); + } + } + + public ClientMonitor getClientMonitor() + { + if( m_clientMonitor != null ) return m_clientMonitor; + + BlockPos pos = getPos(); + TileEntity te = world.getTileEntity( pos.offset( getRight(), -m_xIndex ).offset( getDown(), -m_yIndex ) ); + if( !(te instanceof TileMonitor) ) return null; + + return m_clientMonitor = ((TileMonitor) te).m_clientMonitor; } // Networking stuff @@ -215,9 +267,12 @@ public class TileMonitor extends TilePeripheralBase nbttagcompound.setInteger( "yIndex", m_yIndex ); nbttagcompound.setInteger( "width", m_width ); nbttagcompound.setInteger( "height", m_height ); - nbttagcompound.setInteger( "textScale", m_textScale ); nbttagcompound.setInteger( "monitorDir", m_dir ); - ((ServerTerminal)getLocalTerminal()).writeDescription( nbttagcompound ); + + if( m_xIndex == 0 && m_yIndex == 0 && m_serverMonitor != null ) + { + m_serverMonitor.writeDescription( nbttagcompound ); + } } @Override @@ -229,110 +284,40 @@ public class TileMonitor extends TilePeripheralBase int oldYIndex = m_yIndex; int oldWidth = m_width; int oldHeight = m_height; - int oldTextScale = m_textScale; int oldDir = m_dir; m_xIndex = nbttagcompound.getInteger( "xIndex" ); m_yIndex = nbttagcompound.getInteger( "yIndex" ); m_width = nbttagcompound.getInteger( "width" ); m_height = nbttagcompound.getInteger( "height" ); - m_textScale = nbttagcompound.getInteger( "textScale" ); m_dir = nbttagcompound.getInteger( "monitorDir" ); - ((ClientTerminal)getLocalTerminal()).readDescription( nbttagcompound ); - m_changed = true; + + if( oldXIndex != m_xIndex || oldYIndex != m_yIndex ) + { + // If our index has changed then it's possible the origin monitor has changed. Thus + // we'll clear our cache. If we're the origin then we'll need to remove the glList as well. + if( oldXIndex == 0 && oldYIndex == 0 && m_clientMonitor != null ) m_clientMonitor.destroy(); + m_clientMonitor = null; + } + + if( m_xIndex == 0 && m_yIndex == 0 ) + { + // If we're the origin terminal then read the description + if( m_clientMonitor == null ) m_clientMonitor = new ClientMonitor( m_advanced, this ); + m_clientMonitor.readDescription( nbttagcompound ); + } if( oldXIndex != m_xIndex || oldYIndex != m_yIndex || oldWidth != m_width || oldHeight != m_height || - oldTextScale != m_textScale || oldDir != m_dir ) + oldDir != m_dir ) { + // One of our properties has changed, so ensure we redraw the block updateBlock(); } } - // ITerminalTile implementation - - @Override - public ITerminal getTerminal() - { - TileMonitor origin = getOrigin(); - if( origin != null ) - { - return origin.getLocalTerminal(); - } - return null; - } - - private ITerminal getLocalTerminal() - { - if( !getWorld().isRemote ) - { - if( m_serverTerminal == null ) - { - m_serverTerminal = new ServerTerminal( - getPeripheralType() == PeripheralType.AdvancedMonitor - ); - } - return m_serverTerminal; - } - else - { - if( m_clientTerminal == null ) - { - m_clientTerminal = new ClientTerminal( - getPeripheralType() == PeripheralType.AdvancedMonitor - ); - } - return m_clientTerminal; - } - } - // Sizing and placement stuff - public double getTextScale() - { - TileMonitor origin = getOrigin(); - return (origin == null ? m_textScale : origin.m_textScale) * 0.5; - } - - private void rebuildTerminal() - { - Terminal oldTerm = getTerminal().getTerminal(); - int oldWidth = (oldTerm != null) ? oldTerm.getWidth() : -1; - int oldHeight = (oldTerm != null) ? oldTerm.getHeight() : -1; - - double textScale = getTextScale(); - int termWidth = (int)Math.max( - Math.round( (m_width - 2.0 * ( TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN )) / (textScale * 6.0 * TileMonitor.RENDER_PIXEL_SCALE) ), - 1.0 - ); - int termHeight = (int)Math.max( - Math.round( (m_height - 2.0 * ( TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN )) / (textScale * 9.0 * TileMonitor.RENDER_PIXEL_SCALE) ), - 1.0 - ); - ((ServerTerminal)getLocalTerminal()).resize( termWidth, termHeight ); - - if( oldWidth != termWidth || oldHeight != termHeight ) - { - getLocalTerminal().getTerminal().clear(); - for( int y=0; y