1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-06-05 16:14:11 +00:00

A couple of minor tweaks

- Rename unload -> close to be a little more consistent
 - Make pollAndResetChanged be atomic, so we don't need to aquire a lock
 - Get the computer queue from the task owner, rather than a separate
   argument.
This commit is contained in:
SquidDev 2019-02-26 12:42:24 +00:00
parent c373583723
commit 6d383d005c
7 changed files with 45 additions and 53 deletions

View File

@ -16,7 +16,7 @@ import javax.annotation.Nullable;
/** /**
* A wrapper for {@link ILuaAPI}s which cleans up after a {@link ComputerSystem} when the computer is shutdown. * A wrapper for {@link ILuaAPI}s which cleans up after a {@link ComputerSystem} when the computer is shutdown.
*/ */
public class ApiWrapper implements ILuaAPI final class ApiWrapper implements ILuaAPI
{ {
private final ILuaAPI delegate; private final ILuaAPI delegate;
private final ComputerSystem system; private final ComputerSystem system;

View File

@ -20,10 +20,12 @@ import dan200.computercraft.core.lua.CobaltLuaMachine;
import dan200.computercraft.core.lua.ILuaMachine; import dan200.computercraft.core.lua.ILuaMachine;
import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.Terminal;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class Computer public class Computer
{ {
@ -54,7 +56,7 @@ public class Computer
private FileSystem m_fileSystem = null; private FileSystem m_fileSystem = null;
private IWritableMount m_rootMount = null; private IWritableMount m_rootMount = null;
private boolean m_externalOutputChanged; private final AtomicBoolean externalOutputChanged = new AtomicBoolean();
public Computer( IComputerEnvironment environment, Terminal terminal, int id ) public Computer( IComputerEnvironment environment, Terminal terminal, int id )
{ {
@ -182,7 +184,7 @@ public class Computer
if( !Objects.equal( label, m_label ) ) if( !Objects.equal( label, m_label ) )
{ {
m_label = label; m_label = label;
m_externalOutputChanged = true; externalOutputChanged.set( true );
} }
} }
@ -212,7 +214,7 @@ public class Computer
} }
// Prepare to propagate the environment's output to the world. // Prepare to propagate the environment's output to the world.
if( m_internalEnvironment.updateOutput() ) m_externalOutputChanged = true; if( m_internalEnvironment.updateOutput() ) externalOutputChanged.set( true );
// Set output changed if the terminal has changed from blinking to not // Set output changed if the terminal has changed from blinking to not
boolean blinking = boolean blinking =
@ -223,18 +225,13 @@ public class Computer
if( blinking != m_blinking ) if( blinking != m_blinking )
{ {
m_blinking = blinking; m_blinking = blinking;
m_externalOutputChanged = true; externalOutputChanged.set( true );
} }
} }
public boolean pollAndResetChanged() public boolean pollAndResetChanged()
{ {
synchronized( this ) return externalOutputChanged.getAndSet( false );
{
boolean changed = m_externalOutputChanged;
m_externalOutputChanged = false;
return changed;
}
} }
public boolean isBlinking() public boolean isBlinking()
@ -327,7 +324,7 @@ public class Computer
m_terminal.setCursorPos( 0, 1 ); m_terminal.setCursorPos( 0, 1 );
m_terminal.write( "ComputerCraft may be installed incorrectly" ); m_terminal.write( "ComputerCraft may be installed incorrectly" );
machine.unload(); machine.close();
m_machine = null; m_machine = null;
} }
else else
@ -342,7 +339,7 @@ public class Computer
m_terminal.setCursorPos( 0, 1 ); m_terminal.setCursorPos( 0, 1 );
m_terminal.write( "ComputerCraft may be installed incorrectly" ); m_terminal.write( "ComputerCraft may be installed incorrectly" );
machine.unload(); machine.close();
m_machine = null; m_machine = null;
} }
} }
@ -356,18 +353,18 @@ public class Computer
return; return;
} }
m_state = State.Starting; m_state = State.Starting;
m_externalOutputChanged = true; externalOutputChanged.set( true );
m_ticksSinceStart = 0; m_ticksSinceStart = 0;
} }
// Turn the computercraft on // Turn the computer on
final Computer computer = this;
ComputerThread.queueTask( new ITask() ComputerThread.queueTask( new ITask()
{ {
@Nonnull
@Override @Override
public Computer getOwner() public Computer getOwner()
{ {
return computer; return Computer.this;
} }
@Override @Override
@ -414,14 +411,14 @@ public class Computer
// Start a new state // Start a new state
m_state = State.Running; m_state = State.Running;
m_externalOutputChanged = true; externalOutputChanged.set( true );
synchronized( m_machine ) synchronized( m_machine )
{ {
m_machine.handleEvent( null, null ); m_machine.handleEvent( null, null );
} }
} }
} }
}, computer ); } );
} }
private void stopComputer( final boolean reboot ) private void stopComputer( final boolean reboot )
@ -433,17 +430,17 @@ public class Computer
return; return;
} }
m_state = State.Stopping; m_state = State.Stopping;
m_externalOutputChanged = true; externalOutputChanged.set( true );
} }
// Turn the computercraft off // Turn the computercraft off
final Computer computer = this;
ComputerThread.queueTask( new ITask() ComputerThread.queueTask( new ITask()
{ {
@Nonnull
@Override @Override
public Computer getOwner() public Computer getOwner()
{ {
return computer; return Computer.this;
} }
@Override @Override
@ -468,7 +465,7 @@ public class Computer
// Shutdown terminal and filesystem // Shutdown terminal and filesystem
if( m_fileSystem != null ) if( m_fileSystem != null )
{ {
m_fileSystem.unload(); m_fileSystem.close();
m_fileSystem = null; m_fileSystem = null;
} }
@ -478,7 +475,7 @@ public class Computer
synchronized( m_machine ) synchronized( m_machine )
{ {
m_machine.unload(); m_machine.close();
m_machine = null; m_machine = null;
} }
} }
@ -487,14 +484,14 @@ public class Computer
m_internalEnvironment.resetOutput(); m_internalEnvironment.resetOutput();
m_state = State.Off; m_state = State.Off;
m_externalOutputChanged = true; externalOutputChanged.set( true );
if( reboot ) if( reboot )
{ {
m_startRequested = true; m_startRequested = true;
} }
} }
} }
}, computer ); } );
} }
public void queueEvent( final String event, final Object[] arguments ) public void queueEvent( final String event, final Object[] arguments )
@ -507,13 +504,13 @@ public class Computer
} }
} }
final Computer computer = this; ComputerThread.queueTask( new ITask()
ITask task = new ITask()
{ {
@Nonnull
@Override @Override
public Computer getOwner() public Computer getOwner()
{ {
return computer; return Computer.this;
} }
@Override @Override
@ -541,9 +538,7 @@ public class Computer
} }
} }
} }
}; } );
ComputerThread.queueTask( task, computer );
} }
@Deprecated @Deprecated

View File

@ -35,7 +35,7 @@ public class ComputerThread
/** /**
* Map of objects to task list * Map of objects to task list
*/ */
private static final WeakHashMap<Object, BlockingQueue<ITask>> s_computerTaskQueues = new WeakHashMap<>(); private static final WeakHashMap<Computer, BlockingQueue<ITask>> s_computerTaskQueues = new WeakHashMap<>();
/** /**
* Active queues to execute * Active queues to execute
@ -43,11 +43,6 @@ public class ComputerThread
private static final BlockingQueue<BlockingQueue<ITask>> s_computerTasksActive = new LinkedBlockingQueue<>(); private static final BlockingQueue<BlockingQueue<ITask>> s_computerTasksActive = new LinkedBlockingQueue<>();
private static final Set<BlockingQueue<ITask>> s_computerTasksActiveSet = new HashSet<>(); private static final Set<BlockingQueue<ITask>> s_computerTasksActiveSet = new HashSet<>();
/**
* The default object for items which don't have an owner
*/
private static final Object s_defaultOwner = new Object();
/** /**
* Whether the thread is stopped or should be stopped * Whether the thread is stopped or should be stopped
*/ */
@ -64,7 +59,7 @@ public class ComputerThread
/** /**
* Start the computer thread * Start the computer thread
*/ */
public static void start() static void start()
{ {
synchronized( s_stateLock ) synchronized( s_stateLock )
{ {
@ -116,20 +111,18 @@ public class ComputerThread
/** /**
* Queue a task to execute on the thread * Queue a task to execute on the thread
* *
* @param task The task to execute * @param task The task to execute
* @param computer The computer to execute it on, use {@code null} to execute on the default object.
*/ */
public static void queueTask( ITask task, Computer computer ) static void queueTask( ITask task )
{ {
Object queueObject = computer == null ? s_defaultOwner : computer; Computer computer = task.getOwner();
BlockingQueue<ITask> queue; BlockingQueue<ITask> queue;
synchronized( s_computerTaskQueues ) synchronized( s_computerTaskQueues )
{ {
queue = s_computerTaskQueues.get( queueObject ); queue = s_computerTaskQueues.get( computer );
if( queue == null ) if( queue == null )
{ {
s_computerTaskQueues.put( queueObject, queue = new LinkedBlockingQueue<>( QUEUE_LIMIT ) ); s_computerTaskQueues.put( computer, queue = new LinkedBlockingQueue<>( QUEUE_LIMIT ) );
} }
} }

View File

@ -6,8 +6,11 @@
package dan200.computercraft.core.computer; package dan200.computercraft.core.computer;
import javax.annotation.Nonnull;
public interface ITask public interface ITask
{ {
@Nonnull
Computer getOwner(); Computer getOwner();
void execute(); void execute();

View File

@ -330,7 +330,7 @@ public class FileSystem
mountWritable( rootLabel, "", rootMount ); mountWritable( rootLabel, "", rootMount );
} }
public void unload() public void close()
{ {
// Close all dangling open files // Close all dangling open files
synchronized( m_openFiles ) synchronized( m_openFiles )

View File

@ -196,12 +196,12 @@ public class CobaltLuaMachine implements ILuaMachine
} }
catch( CompileException e ) catch( CompileException e )
{ {
unload(); close();
} }
catch( IOException e ) catch( IOException e )
{ {
ComputerCraft.log.warn( "Could not load bios.lua ", e ); ComputerCraft.log.warn( "Could not load bios.lua ", e );
unload(); close();
} }
} }
@ -229,11 +229,11 @@ public class CobaltLuaMachine implements ILuaMachine
LuaValue filter = results.first(); LuaValue filter = results.first();
m_eventFilter = filter.isString() ? filter.toString() : null; m_eventFilter = filter.isString() ? filter.toString() : null;
if( m_mainRoutine.getStatus().equals( "dead" ) ) unload(); if( m_mainRoutine.getStatus().equals( "dead" ) ) close();
} }
catch( LuaError | HardAbortError | InterruptedException e ) catch( LuaError | HardAbortError | InterruptedException e )
{ {
unload(); close();
ComputerCraft.log.warn( "Top level coroutine errored", e ); ComputerCraft.log.warn( "Top level coroutine errored", e );
} }
finally finally
@ -275,7 +275,7 @@ public class CobaltLuaMachine implements ILuaMachine
} }
@Override @Override
public void unload() public void close()
{ {
if( m_state == null ) return; if( m_state == null ) return;
@ -348,6 +348,7 @@ public class CobaltLuaMachine implements ILuaMachine
final long taskID = MainThread.getUniqueTaskID(); final long taskID = MainThread.getUniqueTaskID();
final ITask iTask = new ITask() final ITask iTask = new ITask()
{ {
@Nonnull
@Override @Override
public Computer getOwner() public Computer getOwner()
{ {

View File

@ -29,5 +29,5 @@ public interface ILuaMachine
boolean isFinished(); boolean isFinished();
void unload(); void close();
} }