1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-04-28 05:33:22 +00:00

Make disk drives thread-safe

This commit is contained in:
SquidDev 2019-04-02 13:17:06 +01:00
parent cbe6e9b5f5
commit 2f96283286
2 changed files with 36 additions and 33 deletions

View File

@ -11,6 +11,7 @@ import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.media.IMedia; import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.MediaProviders;
import dan200.computercraft.shared.media.items.ItemDiskLegacy; import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.util.StringUtil; import dan200.computercraft.shared.util.StringUtil;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -20,11 +21,11 @@ import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optString; import static dan200.computercraft.core.apis.ArgumentHelper.optString;
public class DiskDrivePeripheral implements IPeripheral class DiskDrivePeripheral implements IPeripheral
{ {
private final TileDiskDrive m_diskDrive; private final TileDiskDrive m_diskDrive;
public DiskDrivePeripheral( TileDiskDrive diskDrive ) DiskDrivePeripheral( TileDiskDrive diskDrive )
{ {
m_diskDrive = diskDrive; m_diskDrive = diskDrive;
} }
@ -56,7 +57,7 @@ public class DiskDrivePeripheral implements IPeripheral
} }
@Override @Override
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
{ {
switch( method ) switch( method )
{ {
@ -64,21 +65,26 @@ public class DiskDrivePeripheral implements IPeripheral
return new Object[] { !m_diskDrive.getDiskStack().isEmpty() }; return new Object[] { !m_diskDrive.getDiskStack().isEmpty() };
case 1: // getDiskLabel case 1: // getDiskLabel
{ {
IMedia media = m_diskDrive.getDiskMedia(); ItemStack stack = m_diskDrive.getDiskStack();
return media == null ? null : new Object[] { media.getLabel( m_diskDrive.getDiskStack() ) }; IMedia media = MediaProviders.get( stack );
return media == null ? null : new Object[] { media.getLabel( stack ) };
} }
case 2: // setDiskLabel case 2: // setDiskLabel
{ {
String label = optString( arguments, 0, null ); String label = optString( arguments, 0, null );
IMedia media = m_diskDrive.getDiskMedia(); return context.executeMainThreadTask( () -> {
ItemStack stack = m_diskDrive.getDiskStack();
IMedia media = MediaProviders.get( stack );
if( media == null ) return null; if( media == null ) return null;
ItemStack disk = m_diskDrive.getDiskStack(); if( !media.setLabel( stack, StringUtil.normaliseLabel( label ) ) )
label = StringUtil.normaliseLabel( label ); {
if( !media.setLabel( disk, label ) ) throw new LuaException( "Disk label cannot be changed" ); throw new LuaException( "Disk label cannot be changed" );
m_diskDrive.setDiskStack( disk ); }
m_diskDrive.setDiskStack( stack );
return null; return null;
} );
} }
case 3: // hasData case 3: // hasData
return new Object[] { m_diskDrive.getDiskMountPath( computer ) != null }; return new Object[] { m_diskDrive.getDiskMountPath( computer ) != null };
@ -87,14 +93,16 @@ public class DiskDrivePeripheral implements IPeripheral
case 5: case 5:
{ {
// hasAudio // hasAudio
IMedia media = m_diskDrive.getDiskMedia(); ItemStack stack = m_diskDrive.getDiskStack();
return new Object[] { media != null && media.getAudio( m_diskDrive.getDiskStack() ) != null }; IMedia media = MediaProviders.get( stack );
return new Object[] { media != null && media.getAudio( stack ) != null };
} }
case 6: case 6:
{ {
// getAudioTitle // getAudioTitle
IMedia media = m_diskDrive.getDiskMedia(); ItemStack stack = m_diskDrive.getDiskStack();
return new Object[] { media != null ? media.getAudioTitle( m_diskDrive.getDiskStack() ) : false }; IMedia media = MediaProviders.get( stack );
return new Object[] { media != null ? media.getAudioTitle( stack ) : false };
} }
case 7: // playAudio case 7: // playAudio
m_diskDrive.playDiskAudio(); m_diskDrive.playDiskAudio();
@ -131,8 +139,7 @@ public class DiskDrivePeripheral implements IPeripheral
@Override @Override
public boolean equals( IPeripheral other ) public boolean equals( IPeripheral other )
{ {
if( this == other ) return true; return this == other || other instanceof DiskDrivePeripheral && ((DiskDrivePeripheral) other).m_diskDrive == m_diskDrive;
return other instanceof DiskDrivePeripheral && ((DiskDrivePeripheral) other).m_diskDrive == m_diskDrive;
} }
@Nonnull @Nonnull

View File

@ -318,35 +318,31 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
} }
@Nonnull @Nonnull
public ItemStack getDiskStack() ItemStack getDiskStack()
{ {
return getStackInSlot( 0 ); return getStackInSlot( 0 );
} }
public void setDiskStack( @Nonnull ItemStack stack ) void setDiskStack( @Nonnull ItemStack stack )
{ {
setInventorySlotContents( 0, stack ); setInventorySlotContents( 0, stack );
} }
public IMedia getDiskMedia() private IMedia getDiskMedia()
{ {
return MediaProviders.get( getDiskStack() ); return MediaProviders.get( getDiskStack() );
} }
public String getDiskMountPath( IComputerAccess computer ) String getDiskMountPath( IComputerAccess computer )
{ {
synchronized( this ) synchronized( this )
{
if( m_computers.containsKey( computer ) )
{ {
MountInfo info = m_computers.get( computer ); MountInfo info = m_computers.get( computer );
return info.mountPath; return info != null ? info.mountPath : null;
} }
} }
return null;
}
public void mount( IComputerAccess computer ) void mount( IComputerAccess computer )
{ {
synchronized( this ) synchronized( this )
{ {
@ -355,7 +351,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
} }
} }
public void unmount( IComputerAccess computer ) void unmount( IComputerAccess computer )
{ {
synchronized( this ) synchronized( this )
{ {
@ -364,7 +360,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
} }
} }
public void playDiskAudio() void playDiskAudio()
{ {
synchronized( this ) synchronized( this )
{ {
@ -377,7 +373,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
} }
} }
public void stopDiskAudio() void stopDiskAudio()
{ {
synchronized( this ) synchronized( this )
{ {
@ -386,7 +382,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
} }
} }
public void ejectDisk() void ejectDisk()
{ {
synchronized( this ) synchronized( this )
{ {