mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-07-06 12:02:52 +00:00
Construct ILuaMachines in one go
This means creating an ILuaMachine is largely atomic - it either is created or it fails.
This commit is contained in:
parent
988219ffca
commit
986c65f56e
@ -4,12 +4,10 @@
|
|||||||
|
|
||||||
package dan200.computercraft.gametest.core
|
package dan200.computercraft.gametest.core
|
||||||
|
|
||||||
import dan200.computercraft.api.lua.ILuaAPI
|
|
||||||
import dan200.computercraft.core.apis.OSAPI
|
import dan200.computercraft.core.apis.OSAPI
|
||||||
import dan200.computercraft.core.lua.CobaltLuaMachine
|
import dan200.computercraft.core.lua.CobaltLuaMachine
|
||||||
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.gametest.api.thenOnComputer
|
import dan200.computercraft.gametest.api.thenOnComputer
|
||||||
import dan200.computercraft.mixin.gametest.GameTestInfoAccessor
|
import dan200.computercraft.mixin.gametest.GameTestInfoAccessor
|
||||||
import dan200.computercraft.shared.computer.core.ServerContext
|
import dan200.computercraft.shared.computer.core.ServerContext
|
||||||
@ -60,52 +58,18 @@ object ManagedComputers : ILuaMachine.Factory {
|
|||||||
return monitor
|
return monitor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun create(environment: MachineEnvironment): ILuaMachine = DelegateMachine(environment)
|
override fun create(environment: MachineEnvironment, bios: InputStream): ILuaMachine {
|
||||||
|
val os = environment.apis.asSequence().filterIsInstance(OSAPI::class.java).first()
|
||||||
private class DelegateMachine(private val environment: MachineEnvironment) : ILuaMachine {
|
val id = os.computerID
|
||||||
private val apis = mutableListOf<ILuaAPI>()
|
val label = os.computerLabel
|
||||||
private var delegate: ILuaMachine? = null
|
return when {
|
||||||
|
id != 1 -> CobaltLuaMachine(environment, bios)
|
||||||
override fun addAPI(api: ILuaAPI) {
|
|
||||||
val delegate = this.delegate
|
|
||||||
if (delegate != null) return delegate.addAPI(api)
|
|
||||||
|
|
||||||
apis.add(api)
|
|
||||||
|
|
||||||
if (api is OSAPI) {
|
|
||||||
val id = api.computerID
|
|
||||||
val label = api.computerLabel
|
|
||||||
val newMachine = when {
|
|
||||||
id != 1 -> CobaltLuaMachine(environment)
|
|
||||||
label != null && label[0] != null -> KotlinMachine(environment, label[0] as String)
|
label != null && label[0] != null -> KotlinMachine(environment, label[0] as String)
|
||||||
else -> {
|
else -> {
|
||||||
LOGGER.error("Kotlin Lua machine must have a label")
|
LOGGER.error("Kotlin Lua machine must have a label")
|
||||||
CobaltLuaMachine(environment)
|
CobaltLuaMachine(environment, bios)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.delegate = newMachine
|
|
||||||
for (api in apis) newMachine.addAPI(api)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadBios(bios: InputStream): MachineResult {
|
|
||||||
val delegate = this.delegate ?: return MachineResult.error("Computer not created")
|
|
||||||
return delegate.loadBios(bios)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handleEvent(eventName: String?, arguments: Array<out Any>?): MachineResult {
|
|
||||||
val delegate = this.delegate ?: return MachineResult.error("Computer not created")
|
|
||||||
return delegate.handleEvent(eventName, arguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun printExecutionState(out: StringBuilder) {
|
|
||||||
delegate?.printExecutionState(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun close() {
|
|
||||||
delegate?.close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KotlinMachine(environment: MachineEnvironment, private val label: String) :
|
private class KotlinMachine(environment: MachineEnvironment, private val label: String) :
|
||||||
|
@ -14,15 +14,16 @@ import dan200.computercraft.core.filesystem.FileSystem;
|
|||||||
import dan200.computercraft.core.filesystem.FileSystemException;
|
import dan200.computercraft.core.filesystem.FileSystemException;
|
||||||
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.MachineException;
|
||||||
import dan200.computercraft.core.metrics.Metrics;
|
import dan200.computercraft.core.metrics.Metrics;
|
||||||
import dan200.computercraft.core.metrics.MetricsObserver;
|
import dan200.computercraft.core.metrics.MetricsObserver;
|
||||||
import dan200.computercraft.core.util.Colour;
|
import dan200.computercraft.core.util.Colour;
|
||||||
import dan200.computercraft.core.util.IoUtil;
|
|
||||||
import dan200.computercraft.core.util.Nullability;
|
import dan200.computercraft.core.util.Nullability;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -377,24 +378,20 @@ final class ComputerExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the lua machine
|
// Create the lua machine
|
||||||
var machine = luaFactory.create(new MachineEnvironment(
|
try (var bios = biosStream) {
|
||||||
new LuaContext(computer), metrics, timeout, computer.getGlobalEnvironment().getHostString()
|
return luaFactory.create(new MachineEnvironment(
|
||||||
));
|
new LuaContext(computer), metrics, timeout,
|
||||||
|
() -> apis.stream().map(api -> api instanceof ApiWrapper wrapper ? wrapper.getDelegate() : api).iterator(),
|
||||||
// Add the APIs. We unwrap them (yes, this is horrible) to get access to the underlying object.
|
computer.getGlobalEnvironment().getHostString()
|
||||||
for (var api : apis) machine.addAPI(api instanceof ApiWrapper wrapper ? wrapper.getDelegate() : api);
|
), bios);
|
||||||
|
} catch (IOException e) {
|
||||||
// Start the machine running the bios resource
|
LOG.error("Failed to read bios.lua", e);
|
||||||
var result = machine.loadBios(biosStream);
|
displayFailure("Error loading bios.lua", null);
|
||||||
IoUtil.closeQuietly(biosStream);
|
return null;
|
||||||
|
} catch (MachineException e) {
|
||||||
if (result.isError()) {
|
displayFailure("Error loading bios.lua", e.getMessage());
|
||||||
machine.close();
|
|
||||||
displayFailure("Error loading bios.lua", result.getMessage());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return machine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void turnOn() throws InterruptedException {
|
private void turnOn() throws InterruptedException {
|
||||||
|
@ -14,6 +14,7 @@ import dan200.computercraft.core.asm.LuaMethod;
|
|||||||
import dan200.computercraft.core.asm.ObjectSource;
|
import dan200.computercraft.core.asm.ObjectSource;
|
||||||
import dan200.computercraft.core.computer.TimeoutState;
|
import dan200.computercraft.core.computer.TimeoutState;
|
||||||
import dan200.computercraft.core.metrics.Metrics;
|
import dan200.computercraft.core.metrics.Metrics;
|
||||||
|
import dan200.computercraft.core.util.Nullability;
|
||||||
import dan200.computercraft.core.util.ThreadUtils;
|
import dan200.computercraft.core.util.ThreadUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -27,6 +28,7 @@ import org.squiddev.cobalt.lib.*;
|
|||||||
import org.squiddev.cobalt.lib.platform.VoidResourceManipulator;
|
import org.squiddev.cobalt.lib.platform.VoidResourceManipulator;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -62,7 +64,7 @@ public class CobaltLuaMachine implements ILuaMachine {
|
|||||||
private @Nullable LuaThread mainRoutine = null;
|
private @Nullable LuaThread mainRoutine = null;
|
||||||
private @Nullable String eventFilter = null;
|
private @Nullable String eventFilter = null;
|
||||||
|
|
||||||
public CobaltLuaMachine(MachineEnvironment environment) {
|
public CobaltLuaMachine(MachineEnvironment environment, InputStream bios) throws MachineException, IOException {
|
||||||
timeout = environment.timeout();
|
timeout = environment.timeout();
|
||||||
context = environment.context();
|
context = environment.context();
|
||||||
debug = new TimeoutDebugHandler();
|
debug = new TimeoutDebugHandler();
|
||||||
@ -115,10 +117,20 @@ public class CobaltLuaMachine implements ILuaMachine {
|
|||||||
if (CoreConfig.disableLua51Features) {
|
if (CoreConfig.disableLua51Features) {
|
||||||
globals.rawset("_CC_DISABLE_LUA51_FEATURES", Constants.TRUE);
|
globals.rawset("_CC_DISABLE_LUA51_FEATURES", Constants.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add default APIs
|
||||||
|
for (var api : environment.apis()) addAPI(api);
|
||||||
|
|
||||||
|
// And load the BIOS
|
||||||
|
try {
|
||||||
|
var value = LoadState.load(state, bios, "@bios.lua", globals);
|
||||||
|
mainRoutine = new LuaThread(state, value, globals);
|
||||||
|
} catch (CompileException e) {
|
||||||
|
throw new MachineException(Nullability.assertNonNull(e.getMessage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void addAPI(ILuaAPI api) {
|
||||||
public void addAPI(ILuaAPI api) {
|
|
||||||
if (globals == null) throw new IllegalStateException("Machine has been closed");
|
if (globals == null) throw new IllegalStateException("Machine has been closed");
|
||||||
|
|
||||||
// Add the methods of an API to the global table
|
// Add the methods of an API to the global table
|
||||||
@ -132,25 +144,6 @@ public class CobaltLuaMachine implements ILuaMachine {
|
|||||||
for (var name : names) globals.rawset(name, table);
|
for (var name : names) globals.rawset(name, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MachineResult loadBios(InputStream bios) {
|
|
||||||
if (mainRoutine != null) throw new IllegalStateException("Already set up the machine");
|
|
||||||
if (state == null || globals == null) throw new IllegalStateException("Machine has been destroyed.");
|
|
||||||
|
|
||||||
try {
|
|
||||||
var value = LoadState.load(state, bios, "@bios.lua", globals);
|
|
||||||
mainRoutine = new LuaThread(state, value, globals);
|
|
||||||
return MachineResult.OK;
|
|
||||||
} catch (CompileException e) {
|
|
||||||
close();
|
|
||||||
return MachineResult.error(e);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.warn("Could not load bios.lua", e);
|
|
||||||
close();
|
|
||||||
return MachineResult.GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MachineResult handleEvent(@Nullable String eventName, @Nullable Object[] arguments) {
|
public MachineResult handleEvent(@Nullable String eventName, @Nullable Object[] arguments) {
|
||||||
if (mainRoutine == null || state == null) throw new IllegalStateException("Machine has been closed");
|
if (mainRoutine == null || state == null) throw new IllegalStateException("Machine has been closed");
|
||||||
|
@ -4,10 +4,8 @@
|
|||||||
|
|
||||||
package dan200.computercraft.core.lua;
|
package dan200.computercraft.core.lua;
|
||||||
|
|
||||||
import dan200.computercraft.api.lua.IDynamicLuaObject;
|
|
||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,32 +15,8 @@ import java.io.InputStream;
|
|||||||
* There should only be one concrete implementation at any one time, which is currently {@link CobaltLuaMachine}. If
|
* There should only be one concrete implementation at any one time, which is currently {@link CobaltLuaMachine}. If
|
||||||
* external mod authors are interested in registering their own machines, we can look into how we can provide some
|
* external mod authors are interested in registering their own machines, we can look into how we can provide some
|
||||||
* mechanism for registering these.
|
* mechanism for registering these.
|
||||||
* <p>
|
|
||||||
* This should provide implementations of {@link dan200.computercraft.api.lua.ILuaContext}, and the ability to convert
|
|
||||||
* {@link IDynamicLuaObject}s into something the VM understands, as well as handling method calls.
|
|
||||||
*/
|
*/
|
||||||
public interface ILuaMachine {
|
public interface ILuaMachine {
|
||||||
/**
|
|
||||||
* Inject an API into the global environment of this machine. This should construct an object, as it would for any
|
|
||||||
* {@link IDynamicLuaObject} and set it to all names in {@link ILuaAPI#getNames()}.
|
|
||||||
* <p>
|
|
||||||
* Called before {@link #loadBios(InputStream)}.
|
|
||||||
*
|
|
||||||
* @param api The API to register.
|
|
||||||
*/
|
|
||||||
void addAPI(ILuaAPI api);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a function from the provided program, and set it up to run when {@link #handleEvent(String, Object[])} is
|
|
||||||
* called.
|
|
||||||
* <p>
|
|
||||||
* This should destroy the machine if it failed to load the bios.
|
|
||||||
*
|
|
||||||
* @param bios The stream containing the boot program.
|
|
||||||
* @return The result of loading this machine. Will either be OK, or the error message when loading the bios.
|
|
||||||
*/
|
|
||||||
MachineResult loadBios(InputStream bios);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume the machine, either starting or resuming the coroutine.
|
* Resume the machine, either starting or resuming the coroutine.
|
||||||
* <p>
|
* <p>
|
||||||
@ -71,6 +45,16 @@ public interface ILuaMachine {
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
interface Factory {
|
interface Factory {
|
||||||
ILuaMachine create(MachineEnvironment environment);
|
/**
|
||||||
|
* Attempt to create a Lua machine.
|
||||||
|
*
|
||||||
|
* @param environment The environment under which to create the machine.
|
||||||
|
* @param bios The {@link InputStream} which contains the initial function to run. This should be used to
|
||||||
|
* load the initial function - it should <em>NOT</em> be executed.
|
||||||
|
* @return The successfully created machine, or an error.
|
||||||
|
* @throws IOException If reading the underlying {@link InputStream} failed.
|
||||||
|
* @throws MachineException An error occurred while creating the machine.
|
||||||
|
*/
|
||||||
|
ILuaMachine create(MachineEnvironment environment, InputStream bios) throws IOException, MachineException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
package dan200.computercraft.core.lua;
|
package dan200.computercraft.core.lua;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.lua.ILuaAPI;
|
||||||
import dan200.computercraft.api.lua.ILuaContext;
|
import dan200.computercraft.api.lua.ILuaContext;
|
||||||
import dan200.computercraft.core.computer.GlobalEnvironment;
|
import dan200.computercraft.core.computer.GlobalEnvironment;
|
||||||
import dan200.computercraft.core.computer.TimeoutState;
|
import dan200.computercraft.core.computer.TimeoutState;
|
||||||
@ -17,6 +18,8 @@ import dan200.computercraft.core.metrics.MetricsObserver;
|
|||||||
* @param metrics A sink to submit metrics to. You do not need to submit task timings here, it should only be for additional
|
* @param metrics A sink to submit metrics to. You do not need to submit task timings here, it should only be for additional
|
||||||
* metrics such as {@link Metrics#COROUTINES_CREATED}
|
* metrics such as {@link Metrics#COROUTINES_CREATED}
|
||||||
* @param timeout The current timeout state. This should be used by the machine to interrupt its execution.
|
* @param timeout The current timeout state. This should be used by the machine to interrupt its execution.
|
||||||
|
* @param apis APIs to inject into the global environment. Each API should be converted into a Lua object
|
||||||
|
* (following the same rules as any other value), and then set to all names in {@link ILuaAPI#getNames()}.
|
||||||
* @param hostString A {@linkplain GlobalEnvironment#getHostString() host string} to identify the current environment.
|
* @param hostString A {@linkplain GlobalEnvironment#getHostString() host string} to identify the current environment.
|
||||||
* @see ILuaMachine.Factory
|
* @see ILuaMachine.Factory
|
||||||
*/
|
*/
|
||||||
@ -24,6 +27,7 @@ public record MachineEnvironment(
|
|||||||
ILuaContext context,
|
ILuaContext context,
|
||||||
MetricsObserver metrics,
|
MetricsObserver metrics,
|
||||||
TimeoutState timeout,
|
TimeoutState timeout,
|
||||||
|
Iterable<ILuaAPI> apis,
|
||||||
String hostString
|
String hostString
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
package dan200.computercraft.core.lua;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception thrown by a {@link ILuaMachine}.
|
||||||
|
*/
|
||||||
|
public class MachineException extends Exception {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 400833668352232261L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link MachineException}.
|
||||||
|
*
|
||||||
|
* @param message The message to display. This should be user-friendly, and not contain any internal information -
|
||||||
|
* that should just be logged to the console.
|
||||||
|
*/
|
||||||
|
public MachineException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -7,14 +7,12 @@ package dan200.computercraft.core.lua;
|
|||||||
import dan200.computercraft.core.computer.TimeoutState;
|
import dan200.computercraft.core.computer.TimeoutState;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The result of executing an action on a machine.
|
* The result of executing an action on a machine.
|
||||||
* <p>
|
* <p>
|
||||||
* Errors should halt the machine and display the error to the user.
|
* Errors should halt the machine and display the error to the user.
|
||||||
*
|
*
|
||||||
* @see ILuaMachine#loadBios(InputStream)
|
|
||||||
* @see ILuaMachine#handleEvent(String, Object[])
|
* @see ILuaMachine#handleEvent(String, Object[])
|
||||||
*/
|
*/
|
||||||
public final class MachineResult {
|
public final class MachineResult {
|
||||||
|
@ -17,7 +17,7 @@ import dan200.computercraft.core.filesystem.FileSystemException;
|
|||||||
import dan200.computercraft.core.filesystem.WritableFileMount;
|
import dan200.computercraft.core.filesystem.WritableFileMount;
|
||||||
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
||||||
import dan200.computercraft.core.lua.MachineEnvironment;
|
import dan200.computercraft.core.lua.MachineEnvironment;
|
||||||
import dan200.computercraft.core.lua.MachineResult;
|
import dan200.computercraft.core.lua.MachineException;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.test.core.computer.BasicEnvironment;
|
import dan200.computercraft.test.core.computer.BasicEnvironment;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
||||||
@ -477,14 +477,8 @@ public class ComputerTestDelegate {
|
|||||||
* This is a super nasty hack, but is also an order of magnitude faster than tracking this in Lua.
|
* This is a super nasty hack, but is also an order of magnitude faster than tracking this in Lua.
|
||||||
*/
|
*/
|
||||||
private class CoverageLuaMachine extends CobaltLuaMachine {
|
private class CoverageLuaMachine extends CobaltLuaMachine {
|
||||||
CoverageLuaMachine(MachineEnvironment environment) {
|
CoverageLuaMachine(MachineEnvironment environment, InputStream bios) throws MachineException, IOException {
|
||||||
super(environment);
|
super(environment, bios);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MachineResult loadBios(InputStream bios) {
|
|
||||||
var result = super.loadBios(bios);
|
|
||||||
if (result != MachineResult.OK) return result;
|
|
||||||
|
|
||||||
LuaTable globals;
|
LuaTable globals;
|
||||||
LuaThread mainRoutine;
|
LuaThread mainRoutine;
|
||||||
@ -535,8 +529,6 @@ public class ComputerTestDelegate {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mainRoutine.getDebugState().setHook(hook, false, true, false, 0);
|
mainRoutine.getDebugState().setHook(hook, false, true, false, 0);
|
||||||
|
|
||||||
return MachineResult.OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class KotlinComputerManager : AutoCloseable {
|
|||||||
BasicEnvironment(),
|
BasicEnvironment(),
|
||||||
ComputerThread(1),
|
ComputerThread(1),
|
||||||
NoWorkMainThreadScheduler(),
|
NoWorkMainThreadScheduler(),
|
||||||
) { DummyLuaMachine(it) }
|
) { env, _ -> DummyLuaMachine(env) }
|
||||||
private val errorLock: Lock = ReentrantLock()
|
private val errorLock: Lock = ReentrantLock()
|
||||||
private val hasError = errorLock.newCondition()
|
private val hasError = errorLock.newCondition()
|
||||||
|
|
||||||
@ -153,15 +153,11 @@ class KotlinComputerManager : AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class DummyLuaMachine(private val environment: MachineEnvironment) : KotlinLuaMachine(environment) {
|
private inner class DummyLuaMachine(private val environment: MachineEnvironment) : KotlinLuaMachine(environment) {
|
||||||
private var tasks: Queue<FakeComputerTask>? = null
|
private val tasks: Queue<FakeComputerTask> =
|
||||||
override fun addAPI(api: ILuaAPI) {
|
environment.apis.asSequence().filterIsInstance(QueuePassingAPI::class.java).first().tasks
|
||||||
super.addAPI(api)
|
|
||||||
if (api is QueuePassingAPI) tasks = api.tasks
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTask(): (suspend KotlinLuaMachine.() -> Unit)? {
|
override fun getTask(): (suspend KotlinLuaMachine.() -> Unit)? {
|
||||||
try {
|
try {
|
||||||
val tasks = this.tasks ?: throw NullPointerException("Not received tasks yet")
|
|
||||||
val task = tasks.remove()
|
val task = tasks.remove()
|
||||||
return {
|
return {
|
||||||
try {
|
try {
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
|
|
||||||
package dan200.computercraft.test.core.computer
|
package dan200.computercraft.test.core.computer
|
||||||
|
|
||||||
import dan200.computercraft.api.lua.ILuaAPI
|
|
||||||
import dan200.computercraft.api.lua.ILuaContext
|
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.*
|
import kotlinx.coroutines.*
|
||||||
import java.io.InputStream
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,9 +17,9 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine, AbstractLuaTaskContext() {
|
abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine, AbstractLuaTaskContext() {
|
||||||
override val context: ILuaContext = environment.context
|
override val context: ILuaContext = environment.context
|
||||||
|
|
||||||
override fun addAPI(api: ILuaAPI) = addApi(api)
|
init {
|
||||||
|
for (api in environment.apis) addApi(api)
|
||||||
override fun loadBios(bios: InputStream): MachineResult = MachineResult.OK
|
}
|
||||||
|
|
||||||
override fun handleEvent(eventName: String?, arguments: Array<out Any>?): MachineResult {
|
override fun handleEvent(eventName: String?, arguments: Array<out Any>?): MachineResult {
|
||||||
if (hasEventListeners) {
|
if (hasEventListeners) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user