diff --git a/src/main/java/dan200/computercraft/shared/computer/upload/UploadResult.java b/src/main/java/dan200/computercraft/shared/computer/upload/UploadResult.java index d785080cd..ed480b609 100644 --- a/src/main/java/dan200/computercraft/shared/computer/upload/UploadResult.java +++ b/src/main/java/dan200/computercraft/shared/computer/upload/UploadResult.java @@ -14,8 +14,6 @@ public enum UploadResult CONSUMED, 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 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" ); diff --git a/src/main/resources/assets/computercraft/lang/en_us.json b/src/main/resources/assets/computercraft/lang/en_us.json index 33de587af..4f6f730e5 100644 --- a/src/main/resources/assets/computercraft/lang/en_us.json +++ b/src/main/resources/assets/computercraft/lang/en_us.json @@ -116,8 +116,6 @@ "gui.computercraft.tooltip.turn_off.key": "Hold Ctrl+S", "gui.computercraft.tooltip.terminate": "Stop the currently running code", "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.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.", diff --git a/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt b/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt index ad36ae258..3e94dea31 100644 --- a/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt +++ b/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt @@ -5,11 +5,9 @@ import dan200.computercraft.api.lua.ILuaContext import dan200.computercraft.core.lua.ILuaMachine import dan200.computercraft.core.lua.MachineEnvironment import dan200.computercraft.core.lua.MachineResult -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import java.io.InputStream +import kotlin.coroutines.CoroutineContext /** * An [ILuaMachine] which runs Kotlin functions instead. @@ -26,7 +24,7 @@ abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine, queueEvent(eventName, arguments) } else { 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 @@ -38,4 +36,20 @@ abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine, * Get the next task to execute on this computer. */ 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() + } + } } diff --git a/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/LuaTaskContext.kt b/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/LuaTaskContext.kt index 28ab11c3a..066045b87 100644 --- a/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/LuaTaskContext.kt +++ b/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/LuaTaskContext.kt @@ -4,9 +4,11 @@ import dan200.computercraft.api.lua.ILuaAPI import dan200.computercraft.api.lua.ILuaContext import dan200.computercraft.api.lua.MethodResult import dan200.computercraft.api.lua.ObjectArguments +import dan200.computercraft.core.apis.OSAPI import dan200.computercraft.core.apis.PeripheralAPI import kotlinx.coroutines.CancellableContinuation import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.time.Duration /** * The context for tasks which consume Lua objects. @@ -40,6 +42,19 @@ interface LuaTaskContext { /** Call a peripheral method. */ suspend fun LuaTaskContext.callPeripheral(name: String, method: String, vararg args: Any?): Array? = getApi().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().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. */