mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 12:10:30 +00:00
Be a little more rigorous in KotlinLuaMachine's threading
This commit is contained in:
parent
5ee5b11995
commit
1a87175ae7
@ -14,8 +14,6 @@ public enum UploadResult
|
|||||||
CONSUMED,
|
CONSUMED,
|
||||||
ERROR;
|
ERROR;
|
||||||
|
|
||||||
public static final ITextComponent SUCCESS_TITLE = new TranslationTextComponent( "gui.computercraft.upload.success" );
|
|
||||||
|
|
||||||
public static final ITextComponent FAILED_TITLE = new TranslationTextComponent( "gui.computercraft.upload.failed" );
|
public static final ITextComponent FAILED_TITLE = new TranslationTextComponent( "gui.computercraft.upload.failed" );
|
||||||
public static final ITextComponent COMPUTER_OFF_MSG = new TranslationTextComponent( "gui.computercraft.upload.failed.computer_off" );
|
public static final ITextComponent COMPUTER_OFF_MSG = new TranslationTextComponent( "gui.computercraft.upload.failed.computer_off" );
|
||||||
public static final ITextComponent TOO_MUCH_MSG = new TranslationTextComponent( "gui.computercraft.upload.failed.too_much" );
|
public static final ITextComponent TOO_MUCH_MSG = new TranslationTextComponent( "gui.computercraft.upload.failed.too_much" );
|
||||||
|
@ -116,8 +116,6 @@
|
|||||||
"gui.computercraft.tooltip.turn_off.key": "Hold Ctrl+S",
|
"gui.computercraft.tooltip.turn_off.key": "Hold Ctrl+S",
|
||||||
"gui.computercraft.tooltip.terminate": "Stop the currently running code",
|
"gui.computercraft.tooltip.terminate": "Stop the currently running code",
|
||||||
"gui.computercraft.tooltip.terminate.key": "Hold Ctrl+T",
|
"gui.computercraft.tooltip.terminate.key": "Hold Ctrl+T",
|
||||||
"gui.computercraft.upload.success": "Upload Succeeded",
|
|
||||||
"gui.computercraft.upload.success.msg": "%d files uploaded.",
|
|
||||||
"gui.computercraft.upload.failed": "Upload Failed",
|
"gui.computercraft.upload.failed": "Upload Failed",
|
||||||
"gui.computercraft.upload.failed.computer_off": "You must turn the computer on before uploading files.",
|
"gui.computercraft.upload.failed.computer_off": "You must turn the computer on before uploading files.",
|
||||||
"gui.computercraft.upload.failed.too_much": "Your files are too large to be uploaded.",
|
"gui.computercraft.upload.failed.too_much": "Your files are too large to be uploaded.",
|
||||||
|
@ -5,11 +5,9 @@ import dan200.computercraft.api.lua.ILuaContext
|
|||||||
import dan200.computercraft.core.lua.ILuaMachine
|
import dan200.computercraft.core.lua.ILuaMachine
|
||||||
import dan200.computercraft.core.lua.MachineEnvironment
|
import dan200.computercraft.core.lua.MachineEnvironment
|
||||||
import dan200.computercraft.core.lua.MachineResult
|
import dan200.computercraft.core.lua.MachineResult
|
||||||
import kotlinx.coroutines.CoroutineName
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An [ILuaMachine] which runs Kotlin functions instead.
|
* An [ILuaMachine] which runs Kotlin functions instead.
|
||||||
@ -26,7 +24,7 @@ abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine,
|
|||||||
queueEvent(eventName, arguments)
|
queueEvent(eventName, arguments)
|
||||||
} else {
|
} else {
|
||||||
val task = getTask()
|
val task = getTask()
|
||||||
if (task != null) CoroutineScope(Dispatchers.Unconfined + CoroutineName("Computer")).launch { task() }
|
if (task != null) CoroutineScope(NeverDispatcher() + CoroutineName("Computer")).launch { task() }
|
||||||
}
|
}
|
||||||
|
|
||||||
return MachineResult.OK
|
return MachineResult.OK
|
||||||
@ -38,4 +36,20 @@ abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine,
|
|||||||
* Get the next task to execute on this computer.
|
* Get the next task to execute on this computer.
|
||||||
*/
|
*/
|
||||||
protected abstract fun getTask(): (suspend KotlinLuaMachine.() -> Unit)?
|
protected abstract fun getTask(): (suspend KotlinLuaMachine.() -> Unit)?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [CoroutineDispatcher] which only allows resuming from the computer thread. In practice, this means the only
|
||||||
|
* way to yield is with [pullEvent].
|
||||||
|
*/
|
||||||
|
private class NeverDispatcher : CoroutineDispatcher() {
|
||||||
|
private val expectedGroup = Thread.currentThread().threadGroup
|
||||||
|
|
||||||
|
override fun dispatch(context: CoroutineContext, block: Runnable) {
|
||||||
|
if (Thread.currentThread().threadGroup != expectedGroup) {
|
||||||
|
throw UnsupportedOperationException("Cannot perform arbitrary yields")
|
||||||
|
}
|
||||||
|
|
||||||
|
block.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,11 @@ import dan200.computercraft.api.lua.ILuaAPI
|
|||||||
import dan200.computercraft.api.lua.ILuaContext
|
import dan200.computercraft.api.lua.ILuaContext
|
||||||
import dan200.computercraft.api.lua.MethodResult
|
import dan200.computercraft.api.lua.MethodResult
|
||||||
import dan200.computercraft.api.lua.ObjectArguments
|
import dan200.computercraft.api.lua.ObjectArguments
|
||||||
|
import dan200.computercraft.core.apis.OSAPI
|
||||||
import dan200.computercraft.core.apis.PeripheralAPI
|
import dan200.computercraft.core.apis.PeripheralAPI
|
||||||
import kotlinx.coroutines.CancellableContinuation
|
import kotlinx.coroutines.CancellableContinuation
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The context for tasks which consume Lua objects.
|
* The context for tasks which consume Lua objects.
|
||||||
@ -40,6 +42,19 @@ interface LuaTaskContext {
|
|||||||
/** Call a peripheral method. */
|
/** Call a peripheral method. */
|
||||||
suspend fun LuaTaskContext.callPeripheral(name: String, method: String, vararg args: Any?): Array<out Any?>? =
|
suspend fun LuaTaskContext.callPeripheral(name: String, method: String, vararg args: Any?): Array<out Any?>? =
|
||||||
getApi<PeripheralAPI>().call(context, ObjectArguments(name, method, *args)).await()
|
getApi<PeripheralAPI>().call(context, ObjectArguments(name, method, *args)).await()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sleep for the given duration. This uses the internal computer clock, so won't be accurate.
|
||||||
|
*/
|
||||||
|
suspend fun LuaTaskContext.sleep(duration: Duration) {
|
||||||
|
val timer = getApi<OSAPI>().startTimer(duration.inWholeMilliseconds / 1000.0)
|
||||||
|
while (true) {
|
||||||
|
val event = pullEvent("timer")
|
||||||
|
if (event[0] == "timer" && event[1] is Number && (event[1] as Number).toInt() == timer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a registered API. */
|
/** Get a registered API. */
|
||||||
|
Loading…
Reference in New Issue
Block a user