mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-04-18 08:43:13 +00:00
Move API factories to the common package
We don't actually use this functionality in other projects (e.g. emulators). In fact the method to add new APIs only exists in the mod itself! We still need some mechanism to remove mounts when the computer is shutdown. We add a new ApiLifecycle interface (with startup and shutdown hooks), and use those in the ComputerSystem impl.
This commit is contained in:
parent
cbe075b001
commit
dc3d8ea198
@ -5,6 +5,7 @@
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -12,6 +13,7 @@ import javax.annotation.Nullable;
|
||||
* An interface passed to {@link ILuaAPIFactory} in order to provide additional information
|
||||
* about a computer.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface IComputerSystem extends IComputerAccess {
|
||||
/**
|
||||
* Get the label for this computer.
|
@ -4,13 +4,15 @@
|
||||
|
||||
package dan200.computercraft.api.lua;
|
||||
|
||||
import dan200.computercraft.api.ComputerCraftAPI;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Construct an {@link ILuaAPI} for a specific computer.
|
||||
* Construct an {@link ILuaAPI} for a computer.
|
||||
*
|
||||
* @see ILuaAPI
|
||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
|
||||
* @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ILuaAPIFactory {
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.core.computer;
|
||||
package dan200.computercraft.shared.computer.core;
|
||||
|
||||
import dan200.computercraft.api.lua.IComputerSystem;
|
||||
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
||||
@ -10,6 +10,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.apis.ComputerAccess;
|
||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||
import dan200.computercraft.core.computer.ApiLifecycle;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
@ -18,9 +19,8 @@ import java.util.Map;
|
||||
* Implementation of {@link IComputerAccess}/{@link IComputerSystem} for usage by externally registered APIs.
|
||||
*
|
||||
* @see ILuaAPIFactory
|
||||
* @see ApiWrapper
|
||||
*/
|
||||
public class ComputerSystem extends ComputerAccess implements IComputerSystem {
|
||||
class ComputerSystem extends ComputerAccess implements IComputerSystem, ApiLifecycle {
|
||||
private final IAPIEnvironment environment;
|
||||
|
||||
ComputerSystem(IAPIEnvironment environment) {
|
||||
@ -28,6 +28,11 @@ public class ComputerSystem extends ComputerAccess implements IComputerSystem {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
unmountAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttachmentName() {
|
||||
return "computer";
|
@ -13,6 +13,7 @@ import dan200.computercraft.core.computer.Computer;
|
||||
import dan200.computercraft.core.computer.ComputerEnvironment;
|
||||
import dan200.computercraft.core.computer.ComputerSide;
|
||||
import dan200.computercraft.core.metrics.MetricsObserver;
|
||||
import dan200.computercraft.impl.ApiFactories;
|
||||
import dan200.computercraft.shared.computer.apis.CommandAPI;
|
||||
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
|
||||
@ -63,6 +64,13 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
|
||||
computer = new Computer(context.computerContext(), this, terminal, computerID);
|
||||
computer.setLabel(label);
|
||||
|
||||
// Load in the externally registered APIs.
|
||||
for (var factory : ApiFactories.getAll()) {
|
||||
var system = new ComputerSystem(computer.getAPIEnvironment());
|
||||
var api = factory.create(system);
|
||||
if (api != null) computer.addApi(api, system);
|
||||
}
|
||||
|
||||
if (family == ComputerFamily.COMMAND) addAPI(new CommandAPI(this));
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import dan200.computercraft.core.lua.ILuaMachine;
|
||||
import dan200.computercraft.core.methods.MethodSupplier;
|
||||
import dan200.computercraft.core.methods.PeripheralMethod;
|
||||
import dan200.computercraft.impl.AbstractComputerCraftAPI;
|
||||
import dan200.computercraft.impl.ApiFactories;
|
||||
import dan200.computercraft.impl.GenericSources;
|
||||
import dan200.computercraft.shared.CommonHooks;
|
||||
import dan200.computercraft.shared.computer.metrics.GlobalMetrics;
|
||||
@ -74,7 +73,6 @@ public final class ServerContext {
|
||||
.computerThreads(ConfigSpec.computerThreads.get())
|
||||
.mainThreadScheduler(mainThread)
|
||||
.luaFactory(luaMachine)
|
||||
.apiFactories(ApiFactories.getAll())
|
||||
.genericMethods(GenericSources.getAllMethods())
|
||||
.build();
|
||||
idAssigner = new IDAssigner(storageDir.resolve("ids.json"));
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
package dan200.computercraft.core;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
||||
import dan200.computercraft.core.asm.GenericMethod;
|
||||
import dan200.computercraft.core.asm.LuaMethodSupplier;
|
||||
import dan200.computercraft.core.asm.PeripheralMethodSupplier;
|
||||
@ -35,21 +34,19 @@ public final class ComputerContext {
|
||||
private final ComputerScheduler computerScheduler;
|
||||
private final MainThreadScheduler mainThreadScheduler;
|
||||
private final ILuaMachine.Factory luaFactory;
|
||||
private final List<ILuaAPIFactory> apiFactories;
|
||||
private final MethodSupplier<LuaMethod> luaMethods;
|
||||
private final MethodSupplier<PeripheralMethod> peripheralMethods;
|
||||
|
||||
ComputerContext(
|
||||
private ComputerContext(
|
||||
GlobalEnvironment globalEnvironment, ComputerScheduler computerScheduler,
|
||||
MainThreadScheduler mainThreadScheduler, ILuaMachine.Factory luaFactory,
|
||||
List<ILuaAPIFactory> apiFactories, MethodSupplier<LuaMethod> luaMethods,
|
||||
MethodSupplier<LuaMethod> luaMethods,
|
||||
MethodSupplier<PeripheralMethod> peripheralMethods
|
||||
) {
|
||||
this.globalEnvironment = globalEnvironment;
|
||||
this.computerScheduler = computerScheduler;
|
||||
this.mainThreadScheduler = mainThreadScheduler;
|
||||
this.luaFactory = luaFactory;
|
||||
this.apiFactories = apiFactories;
|
||||
this.luaMethods = luaMethods;
|
||||
this.peripheralMethods = peripheralMethods;
|
||||
}
|
||||
@ -91,15 +88,6 @@ public final class ComputerContext {
|
||||
return luaFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional APIs to inject into each computer.
|
||||
*
|
||||
* @return All available API factories.
|
||||
*/
|
||||
public List<ILuaAPIFactory> apiFactories() {
|
||||
return apiFactories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link MethodSupplier} used to find methods on Lua values.
|
||||
*
|
||||
@ -166,7 +154,6 @@ public final class ComputerContext {
|
||||
private @Nullable ComputerScheduler computerScheduler = null;
|
||||
private @Nullable MainThreadScheduler mainThreadScheduler;
|
||||
private @Nullable ILuaMachine.Factory luaFactory;
|
||||
private @Nullable List<ILuaAPIFactory> apiFactories;
|
||||
private @Nullable List<GenericMethod> genericMethods;
|
||||
|
||||
Builder(GlobalEnvironment environment) {
|
||||
@ -227,20 +214,6 @@ public final class ComputerContext {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the additional {@linkplain ILuaAPIFactory APIs} to add to each computer.
|
||||
*
|
||||
* @param apis A list of API factories.
|
||||
* @return {@code this}, for chaining
|
||||
* @see ComputerContext#apiFactories()
|
||||
*/
|
||||
public Builder apiFactories(Collection<ILuaAPIFactory> apis) {
|
||||
Objects.requireNonNull(apis);
|
||||
if (apiFactories != null) throw new IllegalStateException("Main-thread scheduler already specified");
|
||||
apiFactories = List.copyOf(apis);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the set of {@link GenericMethod}s used by the {@linkplain MethodSupplier method suppliers}.
|
||||
*
|
||||
@ -267,7 +240,6 @@ public final class ComputerContext {
|
||||
computerScheduler == null ? new ComputerThread(1) : computerScheduler,
|
||||
mainThreadScheduler == null ? new NoWorkMainThreadScheduler() : mainThreadScheduler,
|
||||
luaFactory == null ? CobaltLuaMachine::new : luaFactory,
|
||||
apiFactories == null ? List.of() : apiFactories,
|
||||
LuaMethodSupplier.create(genericMethods == null ? List.of() : genericMethods),
|
||||
PeripheralMethodSupplier.create(genericMethods == null ? List.of() : genericMethods)
|
||||
);
|
||||
|
@ -21,7 +21,7 @@ public abstract class ComputerAccess implements IComputerAccess {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ComputerAccess.class);
|
||||
|
||||
private final IAPIEnvironment environment;
|
||||
private final Set<String> mounts = new HashSet<>();
|
||||
private final Set<String> mounts = new HashSet<>(0);
|
||||
|
||||
protected ComputerAccess(IAPIEnvironment environment) {
|
||||
this.environment = environment;
|
||||
|
@ -0,0 +1,28 @@
|
||||
// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.core.computer;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaAPI;
|
||||
|
||||
/**
|
||||
* Hooks for managing the lifecycle of an API. This allows adding additional logic to an API's {@link ILuaAPI#startup()}
|
||||
* and {@link ILuaAPI#shutdown()} methods.
|
||||
*
|
||||
* @see ILuaAPI
|
||||
* @see Computer#addApi(ILuaAPI, ApiLifecycle)
|
||||
*/
|
||||
public interface ApiLifecycle {
|
||||
/**
|
||||
* Called before the API's {@link ILuaAPI#startup()} method, may be used to set up resources.
|
||||
*/
|
||||
default void startup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the API's {@link ILuaAPI#shutdown()} method, may be used to tear down resources.
|
||||
*/
|
||||
default void shutdown() {
|
||||
}
|
||||
}
|
@ -9,18 +9,14 @@ import dan200.computercraft.api.lua.ILuaAPI;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A wrapper for {@link ILuaAPI}s which optionally manages the lifecycle of a {@link ComputerSystem}.
|
||||
* A wrapper for {@link ILuaAPI}s which provides an optional shutdown hook to clean up resources.
|
||||
*
|
||||
* @param api The original API.
|
||||
* @param lifecycle The optional lifecycle hooks for this API.
|
||||
*/
|
||||
final class ApiWrapper {
|
||||
private final ILuaAPI api;
|
||||
private final @Nullable ComputerSystem system;
|
||||
|
||||
ApiWrapper(ILuaAPI api, @Nullable ComputerSystem system) {
|
||||
this.api = api;
|
||||
this.system = system;
|
||||
}
|
||||
|
||||
record ApiWrapper(ILuaAPI api, @Nullable ApiLifecycle lifecycle) {
|
||||
public void startup() {
|
||||
if (lifecycle != null) lifecycle.startup();
|
||||
api.startup();
|
||||
}
|
||||
|
||||
@ -30,7 +26,7 @@ final class ApiWrapper {
|
||||
|
||||
public void shutdown() {
|
||||
api.shutdown();
|
||||
if (system != null) system.unmountAll();
|
||||
if (lifecycle != null) lifecycle.shutdown();
|
||||
}
|
||||
|
||||
public ILuaAPI api() {
|
||||
|
@ -184,6 +184,10 @@ public class Computer {
|
||||
executor.addApi(api);
|
||||
}
|
||||
|
||||
public void addApi(ILuaAPI api, ApiLifecycle lifecycleHooks) {
|
||||
executor.addApi(api, lifecycleHooks);
|
||||
}
|
||||
|
||||
long getUniqueTaskId() {
|
||||
return lastTaskId.incrementAndGet();
|
||||
}
|
||||
|
@ -162,13 +162,6 @@ final class ComputerExecutor implements ComputerScheduler.Worker {
|
||||
addApi(new PeripheralAPI(environment, context.peripheralMethods()));
|
||||
addApi(new OSAPI(environment));
|
||||
if (CoreConfig.httpEnabled) addApi(new HTTPAPI(environment));
|
||||
|
||||
// Load in the externally registered APIs.
|
||||
for (var factory : context.apiFactories()) {
|
||||
var system = new ComputerSystem(environment);
|
||||
var api = factory.create(system);
|
||||
if (api != null) apis.add(new ApiWrapper(api, system));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -190,6 +183,10 @@ final class ComputerExecutor implements ComputerScheduler.Worker {
|
||||
apis.add(new ApiWrapper(api, null));
|
||||
}
|
||||
|
||||
void addApi(ILuaAPI api, ApiLifecycle lifecycleHooks) {
|
||||
apis.add(new ApiWrapper(api, lifecycleHooks));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule this computer to be started if not already on.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user