mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-07-03 02:22:51 +00:00
Add support for running multiple computers at the same time
- ComputerThread constructs multiple threads instead of just one, depending on a config options. - The synchronized blocks of PeripheralAPI.PeripheralWrapper have been shifted a little to ensure no deadlocks occur.
This commit is contained in:
parent
ed8e9d7817
commit
dd5698241b
@ -127,6 +127,7 @@ public class ComputerCraft
|
|||||||
public static boolean disable_lua51_features = false;
|
public static boolean disable_lua51_features = false;
|
||||||
public static String default_computer_settings = "";
|
public static String default_computer_settings = "";
|
||||||
public static boolean debug_enable = false;
|
public static boolean debug_enable = false;
|
||||||
|
public static int computer_threads = 1;
|
||||||
public static boolean logPeripheralErrors = false;
|
public static boolean logPeripheralErrors = false;
|
||||||
|
|
||||||
public static boolean enableCommandBlock = false;
|
public static boolean enableCommandBlock = false;
|
||||||
@ -208,6 +209,7 @@ public class ComputerCraft
|
|||||||
public static Property disable_lua51_features;
|
public static Property disable_lua51_features;
|
||||||
public static Property default_computer_settings;
|
public static Property default_computer_settings;
|
||||||
public static Property debug_enable;
|
public static Property debug_enable;
|
||||||
|
public static Property computer_threads;
|
||||||
public static Property logPeripheralErrors;
|
public static Property logPeripheralErrors;
|
||||||
|
|
||||||
public static Property enableCommandBlock;
|
public static Property enableCommandBlock;
|
||||||
@ -308,6 +310,13 @@ public class ComputerCraft
|
|||||||
Config.debug_enable = Config.config.get( Configuration.CATEGORY_GENERAL, "debug_enable", debug_enable );
|
Config.debug_enable = Config.config.get( Configuration.CATEGORY_GENERAL, "debug_enable", debug_enable );
|
||||||
Config.debug_enable.setComment( "Enable Lua's debug library. Whilst this should be safe for general use, it may allow players to interact with other computers. Enable at your own risk." );
|
Config.debug_enable.setComment( "Enable Lua's debug library. Whilst this should be safe for general use, it may allow players to interact with other computers. Enable at your own risk." );
|
||||||
|
|
||||||
|
Config.computer_threads = Config.config.get( Configuration.CATEGORY_GENERAL, "computer_threads", computer_threads );
|
||||||
|
Config.computer_threads
|
||||||
|
.setMinValue( 1 )
|
||||||
|
.setRequiresWorldRestart( true )
|
||||||
|
.setComment( "Set the number of threads computers can run on. A higher number means more computers can run at once, but may induce lag.\n" +
|
||||||
|
"Please note that some mods may not work with a thread count higher than 1. Use with caution." );
|
||||||
|
|
||||||
Config.logPeripheralErrors = Config.config.get( Configuration.CATEGORY_GENERAL, "logPeripheralErrors", logPeripheralErrors );
|
Config.logPeripheralErrors = Config.config.get( Configuration.CATEGORY_GENERAL, "logPeripheralErrors", logPeripheralErrors );
|
||||||
Config.logPeripheralErrors.setComment( "Log exceptions thrown by peripherals and other Lua objects.\n" +
|
Config.logPeripheralErrors.setComment( "Log exceptions thrown by peripherals and other Lua objects.\n" +
|
||||||
"This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." );
|
"This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." );
|
||||||
@ -378,6 +387,7 @@ public class ComputerCraft
|
|||||||
disable_lua51_features = Config.disable_lua51_features.getBoolean();
|
disable_lua51_features = Config.disable_lua51_features.getBoolean();
|
||||||
default_computer_settings = Config.default_computer_settings.getString();
|
default_computer_settings = Config.default_computer_settings.getString();
|
||||||
debug_enable = Config.debug_enable.getBoolean();
|
debug_enable = Config.debug_enable.getBoolean();
|
||||||
|
computer_threads = Config.computer_threads.getInt();
|
||||||
logPeripheralErrors = Config.logPeripheralErrors.getBoolean();
|
logPeripheralErrors = Config.logPeripheralErrors.getBoolean();
|
||||||
|
|
||||||
enableCommandBlock = Config.enableCommandBlock.getBoolean();
|
enableCommandBlock = Config.enableCommandBlock.getBoolean();
|
||||||
|
@ -84,12 +84,14 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
m_peripheral.attach( this );
|
m_peripheral.attach( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void detach()
|
public void detach()
|
||||||
{
|
{
|
||||||
// Call detach
|
// Call detach
|
||||||
m_peripheral.detach( this );
|
m_peripheral.detach( this );
|
||||||
m_attached = false;
|
|
||||||
|
|
||||||
|
synchronized( this )
|
||||||
|
{
|
||||||
|
m_attached = false;
|
||||||
// Unmount everything the detach function forgot to do
|
// Unmount everything the detach function forgot to do
|
||||||
for( String m_mount : m_mounts )
|
for( String m_mount : m_mounts )
|
||||||
{
|
{
|
||||||
@ -97,6 +99,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}
|
}
|
||||||
m_mounts.clear();
|
m_mounts.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Object[] call( ILuaContext context, String methodName, Object[] arguments ) throws LuaException, InterruptedException
|
public Object[] call( ILuaContext context, String methodName, Object[] arguments ) throws LuaException, InterruptedException
|
||||||
{
|
{
|
||||||
@ -209,7 +212,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized int getID()
|
public int getID()
|
||||||
{
|
{
|
||||||
if( !m_attached ) {
|
if( !m_attached ) {
|
||||||
throw new RuntimeException( "You are not attached to this Computer" );
|
throw new RuntimeException( "You are not attached to this Computer" );
|
||||||
@ -218,7 +221,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void queueEvent( @Nonnull final String event, final Object[] arguments )
|
public void queueEvent( @Nonnull final String event, final Object[] arguments )
|
||||||
{
|
{
|
||||||
if( !m_attached ) {
|
if( !m_attached ) {
|
||||||
throw new RuntimeException( "You are not attached to this Computer" );
|
throw new RuntimeException( "You are not attached to this Computer" );
|
||||||
@ -228,7 +231,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public synchronized String getAttachmentName()
|
public String getAttachmentName()
|
||||||
{
|
{
|
||||||
if( !m_attached ) {
|
if( !m_attached ) {
|
||||||
throw new RuntimeException( "You are not attached to this Computer" );
|
throw new RuntimeException( "You are not attached to this Computer" );
|
||||||
@ -464,7 +467,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
// call
|
// call
|
||||||
int side = parseSide( args );
|
int side = parseSide( args );
|
||||||
String methodName = getString( args, 1 );
|
String methodName = getString( args, 1 );
|
||||||
Object[] methodArgs = trimArray( args, 2 );
|
Object[] methodArgs = Arrays.copyOfRange( args, 2, args.length );
|
||||||
|
|
||||||
if( side >= 0 )
|
if( side >= 0 )
|
||||||
{
|
{
|
||||||
@ -489,11 +492,6 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
|
|
||||||
// Privates
|
// Privates
|
||||||
|
|
||||||
private Object[] trimArray( Object[] array, int skip )
|
|
||||||
{
|
|
||||||
return Arrays.copyOfRange( array, skip, array.length );
|
|
||||||
}
|
|
||||||
|
|
||||||
private int parseSide( Object[] args ) throws LuaException
|
private int parseSide( Object[] args ) throws LuaException
|
||||||
{
|
{
|
||||||
String side = getString( args, 0 );
|
String side = getString( args, 0 );
|
||||||
|
@ -53,9 +53,10 @@ public class ComputerThread
|
|||||||
/**
|
/**
|
||||||
* The thread tasks execute on
|
* The thread tasks execute on
|
||||||
*/
|
*/
|
||||||
private static Thread s_thread = null;
|
private static Thread[] s_threads = null;
|
||||||
|
|
||||||
private static final AtomicInteger s_counter = new AtomicInteger( 1 );
|
private static final AtomicInteger s_ManagerCounter = new AtomicInteger( 1 );
|
||||||
|
private static final AtomicInteger s_DelegateCounter = new AtomicInteger( 1 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the computer thread
|
* Start the computer thread
|
||||||
@ -65,17 +66,25 @@ public class ComputerThread
|
|||||||
synchronized( s_stateLock )
|
synchronized( s_stateLock )
|
||||||
{
|
{
|
||||||
s_stopped = false;
|
s_stopped = false;
|
||||||
if( s_thread == null || !s_thread.isAlive() )
|
if( s_threads == null || s_threads.length != ComputerCraft.computer_threads )
|
||||||
{
|
{
|
||||||
|
s_threads = new Thread[ ComputerCraft.computer_threads ];
|
||||||
|
}
|
||||||
|
|
||||||
SecurityManager manager = System.getSecurityManager();
|
SecurityManager manager = System.getSecurityManager();
|
||||||
final ThreadGroup group = manager == null ? Thread.currentThread().getThreadGroup() : manager.getThreadGroup();
|
final ThreadGroup group = manager == null ? Thread.currentThread().getThreadGroup() : manager.getThreadGroup();
|
||||||
|
for( int i = 0; i < s_threads.length; i++ )
|
||||||
Thread thread = s_thread = new Thread( group, new TaskExecutor(), "ComputerCraft-Computer-Manager" );
|
{
|
||||||
|
Thread thread = s_threads[ i ];
|
||||||
|
if( thread == null || !thread.isAlive() )
|
||||||
|
{
|
||||||
|
thread = s_threads[ i ] = new Thread( group, new TaskExecutor(), "ComputerCraft-Computer-Manager-" + s_ManagerCounter.getAndIncrement() );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to stop the computer thread
|
* Attempt to stop the computer thread
|
||||||
@ -84,12 +93,15 @@ public class ComputerThread
|
|||||||
{
|
{
|
||||||
synchronized( s_stateLock )
|
synchronized( s_stateLock )
|
||||||
{
|
{
|
||||||
if( s_thread != null )
|
if( s_threads != null )
|
||||||
{
|
{
|
||||||
s_stopped = true;
|
s_stopped = true;
|
||||||
if( s_thread.isAlive() )
|
for( Thread thread : s_threads )
|
||||||
{
|
{
|
||||||
s_thread.interrupt();
|
if( thread != null && thread.isAlive() )
|
||||||
|
{
|
||||||
|
thread.interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +190,7 @@ public class ComputerThread
|
|||||||
|
|
||||||
SecurityManager manager = System.getSecurityManager();
|
SecurityManager manager = System.getSecurityManager();
|
||||||
final ThreadGroup group = manager == null ? Thread.currentThread().getThreadGroup() : manager.getThreadGroup();
|
final ThreadGroup group = manager == null ? Thread.currentThread().getThreadGroup() : manager.getThreadGroup();
|
||||||
Thread thread = this.thread = new Thread( group, runner, "ComputerCraft-Computer-Runner" + s_counter.getAndIncrement() );
|
Thread thread = this.thread = new Thread( group, runner, "ComputerCraft-Computer-Runner" + s_DelegateCounter.getAndIncrement() );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user