mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-23 09:57:39 +00:00
Clean up how we enumerate Lua/peripheral methods
- Move several interfaces out of `d00.computercraft.core.asm` into a new `aethods` package. It may make sense to expose this to the public API in a future commit (possibly part of #1462). - Add a new MethodSupplier<T> interface, which provides methods to iterate over all methods exported by an object (either directly, or including those from ObjectSources). This interface's concrete implementation (asm.MethodSupplierImpl), uses Generators and IntCaches as before - we can now make that all package-private though, which is nice! - Make the LuaMethod and PeripheralMethod MethodSupplier local to the ComputerContext. This currently has no effect (the underlying Generator is still global), but eventually we'll make GenericMethods non-global, which unlocks the door for #1382. - Update everything to use this new interface. This is mostly pretty sensible, but is a little uglier on the MC side (especially in generic peripherals), as we need to access the global ServerContext.
This commit is contained in:
@@ -14,6 +14,8 @@ import dan200.computercraft.core.computer.mainthread.MainThread;
|
||||
import dan200.computercraft.core.computer.mainthread.MainThreadConfig;
|
||||
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
||||
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.shared.CommonHooks;
|
||||
@@ -134,6 +136,16 @@ public final class ServerContext {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link MethodSupplier} used to find methods on peripherals.
|
||||
*
|
||||
* @return The {@link PeripheralMethod} method supplier.
|
||||
* @see ComputerContext#peripheralMethods()
|
||||
*/
|
||||
public MethodSupplier<PeripheralMethod> peripheralMethods() {
|
||||
return context.peripheralMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tick all components of this server context. This should <em>NOT</em> be called outside of {@link CommonHooks}.
|
||||
*/
|
||||
|
@@ -7,7 +7,7 @@ package dan200.computercraft.shared.computer.upload;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import dan200.computercraft.core.apis.handles.BinaryReadableHandle;
|
||||
import dan200.computercraft.core.apis.handles.ByteBufferChannel;
|
||||
import dan200.computercraft.core.asm.ObjectSource;
|
||||
import dan200.computercraft.core.methods.ObjectSource;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
|
@@ -6,9 +6,12 @@ package dan200.computercraft.shared.peripheral.generic;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.PeripheralType;
|
||||
import dan200.computercraft.core.asm.NamedMethod;
|
||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||
import dan200.computercraft.core.methods.MethodSupplier;
|
||||
import dan200.computercraft.core.methods.NamedMethod;
|
||||
import dan200.computercraft.core.methods.PeripheralMethod;
|
||||
import dan200.computercraft.shared.computer.core.ServerContext;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -25,37 +28,36 @@ import java.util.Set;
|
||||
* See the platform-specific peripheral providers for the usage of this.
|
||||
*/
|
||||
final class GenericPeripheralBuilder {
|
||||
private final MethodSupplier<PeripheralMethod> peripheralMethods;
|
||||
|
||||
private @Nullable String name;
|
||||
private final Set<String> additionalTypes = new HashSet<>(0);
|
||||
private final ArrayList<SaturatedMethod> methods = new ArrayList<>(0);
|
||||
private final ArrayList<SaturatedMethod> methods = new ArrayList<>();
|
||||
|
||||
GenericPeripheralBuilder(MinecraftServer server) {
|
||||
peripheralMethods = ServerContext.get(server).peripheralMethods();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
IPeripheral toPeripheral(BlockEntity tile, Direction side) {
|
||||
IPeripheral toPeripheral(BlockEntity blockEntity, Direction side) {
|
||||
if (methods.isEmpty()) return null;
|
||||
|
||||
methods.trimToSize();
|
||||
return new GenericPeripheral(tile, side, name, additionalTypes, methods);
|
||||
return new GenericPeripheral(blockEntity, side, name, additionalTypes, methods);
|
||||
}
|
||||
|
||||
boolean addMethods(Object target) {
|
||||
var methods = PeripheralMethod.GENERATOR.getMethods(target.getClass());
|
||||
if (methods.isEmpty()) return false;
|
||||
|
||||
var saturatedMethods = this.methods;
|
||||
saturatedMethods.ensureCapacity(saturatedMethods.size() + methods.size());
|
||||
for (var method : methods) {
|
||||
saturatedMethods.add(new SaturatedMethod(target, method.name(), method.method()));
|
||||
return peripheralMethods.forEachSelfMethod(target, (name, method, info) -> {
|
||||
methods.add(new SaturatedMethod(target, name, method));
|
||||
|
||||
// If we have a peripheral type, use it. Always pick the smallest one, so it's consistent (assuming mods
|
||||
// don't change).
|
||||
var type = method.genericType();
|
||||
var type = info == null ? null : info.genericType();
|
||||
if (type != null && type.getPrimaryType() != null) {
|
||||
var name = type.getPrimaryType();
|
||||
if (this.name == null || this.name.compareTo(name) > 0) this.name = name;
|
||||
var primaryType = type.getPrimaryType();
|
||||
if (this.name == null || this.name.compareTo(primaryType) > 0) this.name = primaryType;
|
||||
}
|
||||
if (type != null) additionalTypes.addAll(type.getAdditionalTypes());
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.MethodResult;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||
import dan200.computercraft.core.methods.PeripheralMethod;
|
||||
|
||||
/**
|
||||
* A {@link PeripheralMethod} along with the method's target.
|
||||
|
@@ -16,10 +16,12 @@ import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.NotAttachedException;
|
||||
import dan200.computercraft.api.peripheral.WorkMonitor;
|
||||
import dan200.computercraft.core.apis.PeripheralAPI;
|
||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||
import dan200.computercraft.core.methods.PeripheralMethod;
|
||||
import dan200.computercraft.core.util.LuaUtil;
|
||||
import dan200.computercraft.shared.computer.core.ServerContext;
|
||||
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -284,7 +286,8 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
|
||||
|
||||
private void attachPeripheralImpl(IComputerAccess computer, ConcurrentMap<String, RemotePeripheralWrapper> peripherals, String periphName, IPeripheral peripheral) {
|
||||
if (!peripherals.containsKey(periphName) && !periphName.equals(getLocalPeripheral().getConnectedName())) {
|
||||
var wrapper = new RemotePeripheralWrapper(modem, peripheral, computer, periphName);
|
||||
var methods = ServerContext.get(((ServerLevel) getLevel()).getServer()).peripheralMethods().getSelfMethods(peripheral);
|
||||
var wrapper = new RemotePeripheralWrapper(modem, peripheral, computer, periphName, methods);
|
||||
peripherals.put(periphName, wrapper);
|
||||
wrapper.attach();
|
||||
}
|
||||
@@ -314,7 +317,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
|
||||
private volatile boolean attached;
|
||||
private final Set<String> mounts = new HashSet<>();
|
||||
|
||||
RemotePeripheralWrapper(WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name) {
|
||||
RemotePeripheralWrapper(WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name, Map<String, PeripheralMethod> methods) {
|
||||
this.element = element;
|
||||
this.peripheral = peripheral;
|
||||
this.computer = computer;
|
||||
@@ -322,7 +325,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
|
||||
|
||||
type = Objects.requireNonNull(peripheral.getType(), "Peripheral type cannot be null");
|
||||
additionalTypes = peripheral.getAdditionalTypes();
|
||||
methodMap = PeripheralAPI.getMethods(peripheral);
|
||||
methodMap = methods;
|
||||
}
|
||||
|
||||
public void attach() {
|
||||
|
Reference in New Issue
Block a user