Renamed Device -> DeviceInterface, IdentifiableDevice -> Device because that's more accurately what they are/represent.

This commit is contained in:
Florian Nücke
2020-12-01 20:30:38 +01:00
parent 796ca0e0d1
commit 1c43ff1a6a
36 changed files with 347 additions and 339 deletions

View File

@@ -3,6 +3,7 @@ package li.cil.oc2.api;
import com.google.gson.GsonBuilder;
import li.cil.oc2.api.device.DeviceMethod;
import li.cil.oc2.api.device.object.Callback;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import li.cil.oc2.api.imc.DeviceMethodParameterTypeAdapter;
import java.lang.reflect.Type;
@@ -11,7 +12,7 @@ public final class API {
public static final String MOD_ID = "oc2";
/**
* IMC message for registering a {@link li.cil.oc2.api.device.provider.DeviceProvider}.
* IMC message for registering a {@link DeviceInterfaceProvider}.
* <p>
* Example:
* <pre>

View File

@@ -1,12 +1,12 @@
package li.cil.oc2.api.bus;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.IdentifiableDevice;
import java.util.Collection;
/**
* A device bus provides the interface by which {@link Device} can be made available
* A device bus provides the interface by which {@link DeviceInterface} can be made available
* to a {@link DeviceBusController}, which is usually used by VMs to access devices.
*/
public interface DeviceBus {
@@ -22,24 +22,24 @@ public interface DeviceBus {
*
* @param device the device to add to the bus.
*/
void addDevice(IdentifiableDevice device);
void addDevice(Device device);
/**
* Removes a device from this device bus.
* <p>
* If the device has not been added with {@link #addDevice(IdentifiableDevice)} before calling
* If the device has not been added with {@link #addDevice(Device)} before calling
* this method, this method is a no-op.
*
* @param device the device to remove from the bus.
*/
void removeDevice(IdentifiableDevice device);
void removeDevice(Device device);
/**
* The list of all devices currently registered with this device bus.
*
* @return the list of all devices that are currently on this bus.
*/
Collection<IdentifiableDevice> getDevices();
Collection<Device> getDevices();
/**
* Schedules a rescan of the device bus.

View File

@@ -1,7 +1,7 @@
package li.cil.oc2.api.bus;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.IdentifiableDevice;
import java.util.Collection;
@@ -11,8 +11,8 @@ import java.util.Collection;
* {@link DeviceBusElement#setController(DeviceBusController)}.
* <p>
* This interface is usually provided by VM containers and used to collect connected
* {@link Device}s by aggregating the devices that were added to the device bus elements
* via {@link DeviceBus#addDevice(IdentifiableDevice)}.
* {@link DeviceInterface}s by aggregating the devices that were added to the device bus elements
* via {@link DeviceBus#addDevice(Device)}.
* <p>
* The only way for {@link DeviceBusElement}s to be added to a bus is for a
* {@link DeviceBusController} to detect them during a scan.
@@ -50,10 +50,10 @@ public interface DeviceBusController {
/**
* The list of all devices currently known to this controller.
* <p>
* This is the aggregation of all {@link Device} added to all {@link DeviceBusElement}s known
* This is the aggregation of all {@link DeviceInterface} added to all {@link DeviceBusElement}s known
* to the controller as found during the last scan scheduled via {@link #scheduleBusScan()}.
*
* @return the list of all devices on the bus managed by this controller.
*/
Collection<IdentifiableDevice> getDevices();
Collection<Device> getDevices();
}

View File

@@ -1,6 +1,6 @@
package li.cil.oc2.api.bus;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.api.device.Device;
import javax.annotation.Nullable;
import java.util.Collection;
@@ -48,5 +48,5 @@ public interface DeviceBusElement extends DeviceBus {
*
* @return the devices that have been added to this element.
*/
Collection<IdentifiableDevice> getLocalDevices();
Collection<Device> getLocalDevices();
}

View File

@@ -1,39 +1,42 @@
package li.cil.oc2.api.device;
import li.cil.oc2.api.bus.DeviceBus;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.provider.DeviceProvider;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import java.util.List;
import java.util.UUID;
/**
* Defines a device that may be added to a {@link DeviceBus}.
* Specialization of a device interface that can be referenced by a {@link UUID} and
* represents a device as a whole.
* <p>
* The easiest and hence recommended way of implementing this interface is to use
* the {@link ObjectDevice} class.
* Implementations will typically act as a top-level wrapper for one singular device
* as viewed by a list of {@link DeviceInterface}s.
* <p>
* Note that it is strongly encouraged for implementations to provide an overloaded
* {@link #equals(Object)} and {@link #hashCode()} so that identical devices can be
* detected.
*
* @see ObjectDevice
* @see DeviceProvider
* A unique ID is required when adding devices to a {@link DeviceBus} such that they
* may then be referenced.
* <p>
* Note that {@link DeviceInterfaceProvider}s are <em>not</em> expected to return instances
* implementing this interface, but return regular {@link DeviceInterface}s instead.
*/
public interface Device {
public interface Device extends DeviceInterface {
/**
* A list of device type names for this device.
* An id unique to this device.
* <p>
* Devices may be identified by multiple type names. Although every atomic
* implementation will usually only have one, when compounding such modular
* devices all the underlying type names can thus be retained.
* <p>
* In a more general sense, these can be considered tags the device can be
* referenced by inside a VM.
* This id must persist over save/load to prevent code in a running VM losing
* track of the device.
*/
List<String> getTypeNames();
UUID getUniqueIdentifier();
/**
* The list of methods implemented by this device.
* Returns a possible underlying instance of a device.
* <p>
* Frequently some {@link DeviceInterface} obtained from a {@link DeviceInterfaceProvider} will be
* wrapped by an instance of this interface. To prevent this leading to duplicated
* device listings this allows accessing the device proper for equality checks.
*
* @return the underlying device. May be this device itself.
*/
List<DeviceMethod> getMethods();
default DeviceInterface getIdentifiedDevice() {
return this;
}
}

View File

@@ -0,0 +1,43 @@
package li.cil.oc2.api.device;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import java.util.List;
/**
* Implementations act as an interface for a device.
* <p>
* A {@link DeviceInterface} represents a single view onto some device. One device
* may have multiple {@code DeviceInterfaces} providing different methods for the
* device. This allows specifying general purpose interfaces which provide logic
* for some aspect of an underlying device which may be shared with other devices.
* <p>
* The easiest and hence recommended way of implementing this interface is to use
* the {@link ObjectDeviceInterface} class.
* <p>
* Note that it is strongly encouraged for implementations to provide an overloaded
* {@link #equals(Object)} and {@link #hashCode()} so that identical devices can be
* detected.
*
* @see ObjectDeviceInterface
* @see DeviceInterfaceProvider
*/
public interface DeviceInterface {
/**
* A list of type names identifying this interface.
* <p>
* Device interfaces may be identified by multiple type names. Although every
* atomic implementation will usually only have one, when compounding interfaces
* all the underlying type names can thus be retained.
* <p>
* In a more general sense, these can be considered tags the device can be
* referenced by inside a VM.
*/
List<String> getTypeNames();
/**
* The list of methods provided by this interface.
*/
List<DeviceMethod> getMethods();
}

View File

@@ -1,22 +1,22 @@
package li.cil.oc2.api.device;
import li.cil.oc2.api.bus.DeviceBusController;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import javax.annotation.Nullable;
import java.util.Optional;
/**
* Represents a single method that can be exposed by a {@link Device}.
* Represents a single method that can be exposed by a {@link DeviceInterface}.
* <p>
* The easiest and hence recommended way of implementing this interface is to use
* the {@link ObjectDevice} class.
* the {@link ObjectDeviceInterface} class.
* <p>
* Method parameters are serialized and deserialized using Gson. When using custom
* parameter types it may be necessary to register a custom type adapter for them
* via {@link li.cil.oc2.api.API#IMC_ADD_DEVICE_METHOD_PARAMETER_TYPE_ADAPTER}.
*
* @see ObjectDevice
* @see ObjectDeviceInterface
*/
public interface DeviceMethod {
/**

View File

@@ -1,38 +0,0 @@
package li.cil.oc2.api.device;
import li.cil.oc2.api.device.provider.DeviceProvider;
import java.util.UUID;
/**
* Specialization of devices that allows referencing the device by a {@link UUID}.
* <p>
* This type is required when adding devices to a {@link li.cil.oc2.api.bus.DeviceBus}
* or referencing devices on a bus. Some {@link li.cil.oc2.api.bus.DeviceBusElement}s
* may take care of wrapping connected devices automatically.
* <p>
* Note that {@link DeviceProvider}s are <em>not</em>
* required to return identifiable devices.
*/
public interface IdentifiableDevice extends Device {
/**
* An id unique to this device.
* <p>
* This id must persist over save/load to prevent code in a running VM losing
* track of the device.
*/
UUID getUniqueIdentifier();
/**
* Returns a possible underlying instance of a device.
* <p>
* Frequently some {@link Device} obtained from a {@link DeviceProvider} will be
* wrapped by an instance of this interface. To prevent this leading to duplicated
* device listings this allows accessing the device proper for equality checks.
*
* @return the underlying device. May be this device itself.
*/
default Device getIdentifiedDevice() {
return this;
}
}

View File

@@ -11,8 +11,7 @@ import java.lang.annotation.Target;
* Utility annotation to allow generating lists of {@link DeviceMethod}s using
* {@link Callbacks#collectMethods(Object)}.
* <p>
* Intended to be used in classes instances of which are used in combination with
* {@link ObjectDevice} and subclasses of {@link ObjectDevice}.
* Intended to be used in classes instances of which are used as a target of {@link ObjectDeviceInterface}.
* <p>
* Method parameters are serialized and deserialized using Gson. When using custom
* parameter types it may be necessary to register a custom type adapter for them

View File

@@ -15,7 +15,7 @@ import java.util.stream.Collectors;
* Provides automated extraction of {@link DeviceMethod}s from instances of
* class with methods annotated with the {@link Callback} annotation.
* <p>
* Prefer using {@link ObjectDevice} instead of using this class directly.
* Prefer using {@link ObjectDeviceInterface} instead of using this class directly.
*/
public final class Callbacks {
private static final Logger LOGGER = LogManager.getLogger();

View File

@@ -6,14 +6,14 @@ import net.minecraft.tileentity.TileEntity;
import java.util.Collection;
/**
* This interface is used to declare additional type names for a device on targets of an {@link ObjectDevice}.
* This interface is used to declare additional type names for a device on targets of an {@link ObjectDeviceInterface}.
* <p>
* In particular {@link Block}s and {@link TileEntity}s that contain {@link Callback} methods may implement
* this interface to provide additional type names.
*/
public interface NamedDevice {
/**
* A list of additional type names to associate with any {@link ObjectDevice} used
* A list of additional type names to associate with any {@link ObjectDeviceInterface} used
* to make available methods in an instance of a class implementing this interface.
*
* @return the list of additional type names.

View File

@@ -1,6 +1,6 @@
package li.cil.oc2.api.device.object;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.DeviceMethod;
import javax.annotation.Nullable;
@@ -9,11 +9,11 @@ import java.util.Collections;
import java.util.List;
/**
* A reflection based implementation of {@link Device} using the {@link Callback}
* annotation to discover {@link DeviceMethod} in a target object via
* A reflection based implementation of {@link DeviceInterface} using the {@link Callback}
* annotation to discover {@link DeviceMethod}s in a target object via
* {@link Callbacks#collectMethods(Object)}.
*/
public final class ObjectDevice implements Device {
public final class ObjectDeviceInterface implements DeviceInterface {
private final Object object;
private final ArrayList<String> typeNames;
private final List<DeviceMethod> methods;
@@ -26,7 +26,7 @@ public final class ObjectDevice implements Device {
* @param object the object containing methods provided by this device.
* @param typeNames the type names of the device.
*/
public ObjectDevice(final Object object, final List<String> typeNames) {
public ObjectDeviceInterface(final Object object, final List<String> typeNames) {
this.object = object;
this.typeNames = new ArrayList<>(typeNames);
this.methods = Callbacks.collectMethods(object);
@@ -40,12 +40,12 @@ public final class ObjectDevice implements Device {
/**
* Creates a new object device with methods in the specified object and the specified
* type name. For convenience, the type name may be {@code null}, in which case using
* this constructor is equivalent to using {@link #ObjectDevice(Object)}.
* this constructor is equivalent to using {@link #ObjectDeviceInterface(Object)}.
*
* @param object the object containing methods provided by this device.
* @param typeName the type name of the device.
*/
public ObjectDevice(final Object object, @Nullable final String typeName) {
public ObjectDeviceInterface(final Object object, @Nullable final String typeName) {
this(object, typeName != null ? Collections.singletonList(typeName) : Collections.emptyList());
}
@@ -54,7 +54,7 @@ public final class ObjectDevice implements Device {
*
* @param object the object containing the methods provided by this device.
*/
public ObjectDevice(final Object object) {
public ObjectDeviceInterface(final Object object) {
this(object, Collections.emptyList());
}
@@ -72,7 +72,7 @@ public final class ObjectDevice implements Device {
public boolean equals(@Nullable final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ObjectDevice that = (ObjectDevice) o;
final ObjectDeviceInterface that = (ObjectDeviceInterface) o;
return object.equals(that.object);
}

View File

@@ -0,0 +1,47 @@
package li.cil.oc2.api.device.provider;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import net.minecraftforge.common.util.LazyOptional;
/**
* Allows querying for device interfaces given some context.
* <p>
* See the specializations of {@link DeviceQuery} for possible queries.
* <p>
* Returning a device interface does <em>not</em> transfer ownership of the device in terms
* of responsibility for persistence. Callers of this method will <em>not</em> attempt
* to persist objects returned by this method. It is the responsibility of the provider
* to ensure persistence where required.
* <ul>
* <li>Implementations <em>may</em> handle multiple query types and return various device
* interface types depending on the query.</li>
* <li>
* Implementations <em>should</em> return the same device interface for the same query.
* <p>
* Failing that, implementations <em>should</em> return instances that are equal to each
* other when compared using {@link #equals(Object)} and have equal {@link #hashCode()}s.
* <p>
* This is required to avoid device duplication when a device is connected to a bus more
* than once (e.g. for blocks when connected cables are adjacent to multiple faces of the
* block).
* </li>
* </ul>
* <p>
* Providers can be registered with the IMC message {@link li.cil.oc2.api.API#IMC_ADD_DEVICE_PROVIDER}.
*
* @see DeviceInterface
* @see ObjectDeviceInterface
* @see DeviceQuery
* @see BlockDeviceQuery
*/
@FunctionalInterface
public interface DeviceInterfaceProvider {
/**
* Get a device for the specified query.
*
* @param query the query describing the object to get a {@link DeviceInterface} for.
* @return a device for the specified query, if available.
*/
LazyOptional<DeviceInterface> getDeviceInterface(DeviceQuery query);
}

View File

@@ -1,49 +0,0 @@
package li.cil.oc2.api.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.object.ObjectDevice;
import net.minecraftforge.common.util.LazyOptional;
/**
* Allows querying for devices given some context.
* <p>
* See the specializations of {@link DeviceQuery} for possible queries.
* <p>
* Returning a device does <em>not</em> transfer ownership of the device in terms of
* responsibility for persistence. Callers of this method will <em>not</em> attempt
* to persist devices returned by this method. It is the responsibility of the provider
* to ensure persistence where required. Typically by returning devices that are
* themselves persisted objects such as {@link net.minecraft.tileentity.TileEntity}s
* or storing data in a related persisted object.
* <ul>
* <li>Implementations <em>may</em> handle multiple query types and return various device
* types depending on the query.</li>
* <li>Implementations <em>should</em> return the same device for the same query.</li>
* <li>
* Implementations <em>should</em> return either the same instance for identical
* queries or return instances that are equal to other when compared using
* {@link Object#equals(Object)} and have equal {@link Object#hashCode()}s.
* <p>
* This is required to avoid device duplication when a device is connected to a bus more
* than once (e.g. for blocks when connected cables are adjacent to multiple faces of the
* block).
* </li>
* <li>Implementations <em>must</em> return the same device type for the same query.</li>
* </ul>
* <p>
* Providers can be registered with the IMC message {@link li.cil.oc2.api.API#IMC_ADD_DEVICE_PROVIDER}.
*
* @see DeviceQuery
* @see BlockDeviceQuery
* @see ObjectDevice
*/
@FunctionalInterface
public interface DeviceProvider {
/**
* Get a device for the specified query.
*
* @param query the query describing the object to get a {@link Device} for.
* @return a device for the specified query, if available.
*/
LazyOptional<Device> getDevice(DeviceQuery query);
}

View File

@@ -1,9 +1,9 @@
package li.cil.oc2.api.device.provider;
/**
* Base interface for all queries to {@link DeviceProvider}s.
* Base interface for all queries to {@link DeviceInterfaceProvider}s.
*
* @see DeviceProvider
* @see DeviceInterfaceProvider
* @see BlockDeviceQuery
*/
public interface DeviceQuery {

View File

@@ -2,7 +2,7 @@ package li.cil.oc2.common;
import li.cil.oc2.common.capabilities.DeviceBusElementCapability;
import li.cil.oc2.common.device.DeviceMethodParameterTypeAdapters;
import li.cil.oc2.common.device.Providers;
import li.cil.oc2.common.device.provider.Providers;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.vm.Allocator;
import li.cil.oc2.serialization.BlobStorage;

View File

@@ -1,10 +1,10 @@
package li.cil.oc2.common;
import li.cil.oc2.api.API;
import li.cil.oc2.api.device.provider.DeviceProvider;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import li.cil.oc2.api.imc.DeviceMethodParameterTypeAdapter;
import li.cil.oc2.common.device.DeviceMethodParameterTypeAdapters;
import li.cil.oc2.common.device.Providers;
import li.cil.oc2.common.device.provider.Providers;
import net.minecraft.util.Util;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
@@ -39,7 +39,7 @@ public final class IMC {
}
private static void addDeviceProvider(final InterModComms.IMCMessage message) {
getMessageParameter(message, DeviceProvider.class).ifPresent(Providers::addProvider);
getMessageParameter(message, DeviceInterfaceProvider.class).ifPresent(Providers::addProvider);
}
private static void addDeviceMethodParameterTypeAdapter(final InterModComms.IMCMessage message) {

View File

@@ -5,10 +5,10 @@ import com.google.gson.JsonArray;
import li.cil.ceres.api.Serialized;
import li.cil.oc2.api.bus.DeviceBusController;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.DeviceMethod;
import li.cil.oc2.api.device.DeviceMethodParameter;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.device.DeviceMethodParameterTypeAdapters;
import li.cil.oc2.serialization.serializers.DeviceJsonSerializer;
@@ -49,7 +49,7 @@ public class DeviceBusControllerImpl implements DeviceBusController, Steppable {
public static final String ERROR_INVALID_PARAMETER_SIGNATURE = "invalid parameter signature";
private final Set<DeviceBusElement> elements = new HashSet<>();
private final ConcurrentHashMap<UUID, IdentifiableDevice> devices = new ConcurrentHashMap<>();
private final ConcurrentHashMap<UUID, Device> devices = new ConcurrentHashMap<>();
private final SerialDevice serialDevice;
private final Gson gson;
@@ -69,7 +69,7 @@ public class DeviceBusControllerImpl implements DeviceBusController, Steppable {
this.gson = DeviceMethodParameterTypeAdapters.beginBuildGson()
.registerTypeAdapter(MethodInvocation.class, new MethodInvocationJsonDeserializer())
.registerTypeAdapter(Message.class, new MessageJsonDeserializer())
.registerTypeAdapter(Device.class, new DeviceJsonSerializer())
.registerTypeAdapter(DeviceInterface.class, new DeviceJsonSerializer())
.registerTypeAdapter(DeviceMethod.class, new DeviceMethodJsonSerializer())
.create();
}
@@ -91,22 +91,22 @@ public class DeviceBusControllerImpl implements DeviceBusController, Steppable {
public void scanDevices() {
devices.clear();
final HashMap<Device, ArrayList<IdentifiableDevice>> groupedDevices = new HashMap<>();
final HashMap<DeviceInterface, ArrayList<Device>> groupedDevices = new HashMap<>();
for (final DeviceBusElement element : elements) {
for (final IdentifiableDevice device : element.getLocalDevices()) {
for (final Device device : element.getLocalDevices()) {
groupedDevices.computeIfAbsent(device.getIdentifiedDevice(), d -> new ArrayList<>()).add(device);
}
}
for (final ArrayList<IdentifiableDevice> group : groupedDevices.values()) {
final IdentifiableDevice device = selectDeviceDeterministically(group);
for (final ArrayList<Device> group : groupedDevices.values()) {
final Device device = selectDeviceDeterministically(group);
devices.putIfAbsent(device.getUniqueIdentifier(), device);
}
}
@Override
public Collection<IdentifiableDevice> getDevices() {
public Collection<Device> getDevices() {
return devices.values();
}
@@ -208,10 +208,10 @@ public class DeviceBusControllerImpl implements DeviceBusController, Steppable {
writeToDevice();
}
private static IdentifiableDevice selectDeviceDeterministically(final ArrayList<IdentifiableDevice> devices) {
IdentifiableDevice deviceWithLowestUuid = devices.get(0);
private static Device selectDeviceDeterministically(final ArrayList<Device> devices) {
Device deviceWithLowestUuid = devices.get(0);
for (int i = 1; i < devices.size(); i++) {
final IdentifiableDevice device = devices.get(i);
final Device device = devices.get(i);
if (device.getUniqueIdentifier().compareTo(deviceWithLowestUuid.getUniqueIdentifier()) < 0) {
deviceWithLowestUuid = device;
}
@@ -293,7 +293,7 @@ public class DeviceBusControllerImpl implements DeviceBusController, Steppable {
}
private void processMethodInvocation(final MethodInvocation methodInvocation, final boolean isMainThread) {
final Device device = devices.get(methodInvocation.deviceId);
final DeviceInterface device = devices.get(methodInvocation.deviceId);
if (device == null) {
writeError(ERROR_UNKNOWN_DEVICE);
return;
@@ -346,7 +346,7 @@ public class DeviceBusControllerImpl implements DeviceBusController, Steppable {
}
private void writeStatus() {
writeMessage(Message.MESSAGE_TYPE_STATUS, devices.values().toArray(new Device[0]));
writeMessage(Message.MESSAGE_TYPE_STATUS, devices.values().toArray(new DeviceInterface[0]));
}
private void writeError(final String message) {

View File

@@ -2,7 +2,7 @@ package li.cil.oc2.common.bus;
import li.cil.oc2.api.bus.DeviceBusController;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.api.device.Device;
import javax.annotation.Nullable;
import java.util.ArrayList;
@@ -11,7 +11,7 @@ import java.util.List;
import java.util.Optional;
public final class DeviceBusElementImpl implements DeviceBusElement {
private final List<IdentifiableDevice> devices = new ArrayList<>();
private final List<Device> devices = new ArrayList<>();
@Nullable private DeviceBusController controller;
@Override
@@ -24,12 +24,12 @@ public final class DeviceBusElementImpl implements DeviceBusElement {
}
@Override
public Collection<IdentifiableDevice> getLocalDevices() {
public Collection<Device> getLocalDevices() {
return devices;
}
@Override
public void addDevice(final IdentifiableDevice device) {
public void addDevice(final Device device) {
devices.add(device);
if (controller != null) {
controller.scanDevices();
@@ -37,7 +37,7 @@ public final class DeviceBusElementImpl implements DeviceBusElement {
}
@Override
public void removeDevice(final IdentifiableDevice device) {
public void removeDevice(final Device device) {
devices.remove(device);
if (controller != null) {
controller.scanDevices();
@@ -45,7 +45,7 @@ public final class DeviceBusElementImpl implements DeviceBusElement {
}
@Override
public Collection<IdentifiableDevice> getDevices() {
public Collection<Device> getDevices() {
if (controller != null) {
return controller.getDevices();
} else {

View File

@@ -4,9 +4,9 @@ import li.cil.oc2.api.bus.DeviceBus;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.common.ServerScheduler;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.device.CompoundDevice;
import li.cil.oc2.common.device.IdentifiableDeviceImpl;
import li.cil.oc2.common.device.Providers;
import li.cil.oc2.common.device.DeviceInterfaceCollection;
import li.cil.oc2.common.device.DeviceImpl;
import li.cil.oc2.common.device.provider.Providers;
import li.cil.oc2.common.util.NBTTagIds;
import li.cil.oc2.common.util.WorldUtils;
import net.minecraft.nbt.CompoundNBT;
@@ -31,7 +31,7 @@ public final class TileEntityDeviceBusElement implements INBTSerializable<Compou
private final DeviceBusElementImpl busElement = new DeviceBusElementImpl();
private final UUID[] deviceIds = new UUID[NEIGHBOR_COUNT];
private final IdentifiableDeviceImpl[] devices = new IdentifiableDeviceImpl[NEIGHBOR_COUNT];
private final DeviceImpl[] devices = new DeviceImpl[NEIGHBOR_COUNT];
public TileEntityDeviceBusElement(final TileEntity tileEntity) {
this.tileEntity = tileEntity;
@@ -59,12 +59,12 @@ public final class TileEntityDeviceBusElement implements INBTSerializable<Compou
final int index = direction.getIndex();
final LazyOptional<CompoundDevice> device = Providers.getDevice(world, pos, direction);
final IdentifiableDeviceImpl identifiableDevice;
final LazyOptional<DeviceInterfaceCollection> device = Providers.getDevice(world, pos, direction);
final DeviceImpl identifiableDevice;
if (device.isPresent()) {
final String typeName = WorldUtils.getBlockName(world, pos);
identifiableDevice = new IdentifiableDeviceImpl(device, deviceIds[index], typeName);
identifiableDevice = new DeviceImpl(device, deviceIds[index], typeName);
device.addListener((ignored) -> handleNeighborChanged(pos));
} else {
identifiableDevice = null;

View File

@@ -1,25 +1,25 @@
package li.cil.oc2.common.device;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.DeviceMethod;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.common.util.LazyOptionalUtils;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nullable;
import java.util.*;
public final class IdentifiableDeviceImpl implements IdentifiableDevice {
private final LazyOptional<? extends Device> device;
public final class DeviceImpl implements Device {
private final LazyOptional<DeviceInterface> deviceInterface;
private final UUID uuid;
@Nullable private final String typeName;
public IdentifiableDeviceImpl(final LazyOptional<? extends Device> device, final UUID uuid) {
this(device, uuid, null);
public DeviceImpl(final LazyOptional<? extends DeviceInterface> deviceInterface, final UUID uuid) {
this(deviceInterface, uuid, null);
}
public IdentifiableDeviceImpl(final LazyOptional<? extends Device> device, final UUID uuid, @Nullable final String typeName) {
this.device = device;
public DeviceImpl(final LazyOptional<? extends DeviceInterface> deviceInterface, final UUID uuid, @Nullable final String typeName) {
this.deviceInterface = deviceInterface.cast();
this.uuid = uuid;
this.typeName = typeName;
}
@@ -30,38 +30,38 @@ public final class IdentifiableDeviceImpl implements IdentifiableDevice {
}
@Override
public Device getIdentifiedDevice() {
return device.<Device>cast().orElse(this);
public DeviceInterface getIdentifiedDevice() {
return deviceInterface.orElse(this);
}
@Override
public List<String> getTypeNames() {
if (typeName != null) {
final List<String> typeNames = new ArrayList<>(device.map(Device::getTypeNames).orElse(Collections.emptyList()));
final List<String> typeNames = new ArrayList<>(deviceInterface.map(DeviceInterface::getTypeNames).orElse(Collections.emptyList()));
typeNames.add(typeName);
return typeNames;
} else {
return device.map(Device::getTypeNames).orElse(Collections.emptyList());
return deviceInterface.map(DeviceInterface::getTypeNames).orElse(Collections.emptyList());
}
}
@Override
public List<DeviceMethod> getMethods() {
return device.map(Device::getMethods).orElse(Collections.emptyList());
return deviceInterface.map(DeviceInterface::getMethods).orElse(Collections.emptyList());
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final IdentifiableDeviceImpl that = (IdentifiableDeviceImpl) o;
final DeviceImpl that = (DeviceImpl) o;
return uuid.equals(that.uuid) &&
LazyOptionalUtils.equals(device, that.device) &&
LazyOptionalUtils.equals(deviceInterface, that.deviceInterface) &&
Objects.equals(typeName, that.typeName);
}
@Override
public int hashCode() {
return Objects.hash(uuid, LazyOptionalUtils.hashCode(device), typeName);
return Objects.hash(uuid, LazyOptionalUtils.hashCode(deviceInterface), typeName);
}
}

View File

@@ -1,6 +1,6 @@
package li.cil.oc2.common.device;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.DeviceMethod;
import java.util.ArrayList;
@@ -9,25 +9,25 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public final class CompoundDevice implements Device {
private final ArrayList<Device> devices;
public final class DeviceInterfaceCollection implements DeviceInterface {
private final ArrayList<DeviceInterface> deviceInterfaces;
public CompoundDevice(final ArrayList<Device> devices) {
this.devices = devices;
public DeviceInterfaceCollection(final ArrayList<DeviceInterface> deviceInterfaces) {
this.deviceInterfaces = deviceInterfaces;
}
@Override
public List<String> getTypeNames() {
return devices.stream()
.map(Device::getTypeNames)
return deviceInterfaces.stream()
.map(DeviceInterface::getTypeNames)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@Override
public List<DeviceMethod> getMethods() {
return devices.stream()
.map(Device::getMethods)
return deviceInterfaces.stream()
.map(DeviceInterface::getMethods)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@@ -36,12 +36,12 @@ public final class CompoundDevice implements Device {
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final CompoundDevice that = (CompoundDevice) o;
return devices.equals(that.devices);
final DeviceInterfaceCollection that = (DeviceInterfaceCollection) o;
return deviceInterfaces.equals(that.deviceInterfaces);
}
@Override
public int hashCode() {
return Objects.hash(devices);
return Objects.hash(deviceInterfaces);
}
}

View File

@@ -1,66 +0,0 @@
package li.cil.oc2.common.device;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.provider.DeviceProvider;
import li.cil.oc2.api.device.provider.DeviceQuery;
import li.cil.oc2.common.device.provider.*;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import java.util.ArrayList;
public final class Providers {
private static final ArrayList<DeviceProvider> DEVICE_PROVIDERS = new ArrayList<>();
public static void initialize() {
addProvider(new EnergyStorageDeviceProvider());
addProvider(new FluidHandlerDeviceProvider());
addProvider(new ItemHandlerDeviceProvider());
addProvider(new TileEntityDeviceProvider());
addProvider(new BlockDeviceProvider());
}
public static void addProvider(final DeviceProvider provider) {
if (!DEVICE_PROVIDERS.contains(provider)) {
DEVICE_PROVIDERS.add(provider);
}
}
public static LazyOptional<CompoundDevice> getDevice(final TileEntity tileEntity, final Direction side) {
final World world = tileEntity.getWorld();
final BlockPos pos = tileEntity.getPos();
if (world == null) throw new IllegalArgumentException();
return getDevice(world, pos, side);
}
public static LazyOptional<CompoundDevice> getDevice(final World world, final BlockPos pos, final Direction side) {
return getDevice(new BlockDeviceQueryImpl(world, pos, side));
}
public static LazyOptional<CompoundDevice> getDevice(final DeviceQuery query) {
final ArrayList<Device> devices = new ArrayList<>();
final ArrayList<LazyOptional<Device>> optionals = new ArrayList<>();
for (final DeviceProvider provider : DEVICE_PROVIDERS) {
final LazyOptional<Device> optional = provider.getDevice(query);
optional.ifPresent((device) -> {
devices.add(device);
optionals.add(optional);
});
}
if (devices.isEmpty()) {
return LazyOptional.empty();
} else {
final LazyOptional<CompoundDevice> compoundOptional = LazyOptional.of(() -> new CompoundDevice(devices));
for (final LazyOptional<Device> optional : optionals) {
optional.addListener((ignored) -> compoundOptional.invalidate());
}
return compoundOptional;
}
}
}

View File

@@ -0,0 +1,12 @@
package li.cil.oc2.common.device.provider;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.capabilities.Capability;
import java.util.function.Supplier;
public abstract class AbstractCapabilityAnyTileEntityDeviceInterfaceProvider<TCapability> extends AbstractCapabilityTileEntityDeviceInterfaceProvider<TCapability, TileEntity> {
public AbstractCapabilityAnyTileEntityDeviceInterfaceProvider(final Supplier<Capability<TCapability>> capabilitySupplier) {
super(TileEntity.class, capabilitySupplier);
}
}

View File

@@ -1,12 +0,0 @@
package li.cil.oc2.common.device.provider;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.capabilities.Capability;
import java.util.function.Supplier;
public abstract class AbstractCapabilityAnyTileEntityDeviceProvider<TCapability> extends AbstractCapabilityTileEntityDeviceProvider<TCapability, TileEntity> {
public AbstractCapabilityAnyTileEntityDeviceProvider(final Supplier<Capability<TCapability>> capabilitySupplier) {
super(TileEntity.class, capabilitySupplier);
}
}

View File

@@ -1,6 +1,6 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.capabilities.Capability;
@@ -8,16 +8,16 @@ import net.minecraftforge.common.util.LazyOptional;
import java.util.function.Supplier;
public abstract class AbstractCapabilityTileEntityDeviceProvider<TCapability, TTileEntity extends TileEntity> extends AbstractTileEntityDeviceProvider<TTileEntity> {
public abstract class AbstractCapabilityTileEntityDeviceInterfaceProvider<TCapability, TTileEntity extends TileEntity> extends AbstractTileEntityDeviceInterfaceProvider<TTileEntity> {
private final Supplier<Capability<TCapability>> capabilitySupplier;
protected AbstractCapabilityTileEntityDeviceProvider(final Class<TTileEntity> tileEntityType, final Supplier<Capability<TCapability>> capabilitySupplier) {
protected AbstractCapabilityTileEntityDeviceInterfaceProvider(final Class<TTileEntity> tileEntityType, final Supplier<Capability<TCapability>> capabilitySupplier) {
super(tileEntityType);
this.capabilitySupplier = capabilitySupplier;
}
@Override
protected final LazyOptional<Device> getDevice(final BlockDeviceQuery blockQuery, final TileEntity tileEntity) {
protected final LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery blockQuery, final TileEntity tileEntity) {
final Capability<TCapability> capability = capabilitySupplier.get();
if (capability == null) throw new IllegalStateException();
final LazyOptional<TCapability> optional = tileEntity.getCapability(capability, blockQuery.getQuerySide());
@@ -26,10 +26,10 @@ public abstract class AbstractCapabilityTileEntityDeviceProvider<TCapability, TT
}
final TCapability value = optional.orElseThrow(AssertionError::new);
final LazyOptional<Device> device = getDevice(blockQuery, value);
final LazyOptional<DeviceInterface> device = getDeviceInterface(blockQuery, value);
optional.addListener(ignored -> device.invalidate());
return device;
}
protected abstract LazyOptional<Device> getDevice(final BlockDeviceQuery query, final TCapability value);
protected abstract LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery query, final TCapability value);
}

View File

@@ -1,22 +1,22 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import li.cil.oc2.api.device.provider.DeviceProvider;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import li.cil.oc2.api.device.provider.DeviceQuery;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.LazyOptional;
public abstract class AbstractTileEntityDeviceProvider<T extends TileEntity> implements DeviceProvider {
public abstract class AbstractTileEntityDeviceInterfaceProvider<T extends TileEntity> implements DeviceInterfaceProvider {
private final Class<T> tileEntityType;
protected AbstractTileEntityDeviceProvider(final Class<T> tileEntityType) {
protected AbstractTileEntityDeviceInterfaceProvider(final Class<T> tileEntityType) {
this.tileEntityType = tileEntityType;
}
@SuppressWarnings("unchecked")
@Override
public LazyOptional<Device> getDevice(final DeviceQuery query) {
public LazyOptional<DeviceInterface> getDeviceInterface(final DeviceQuery query) {
if (!(query instanceof BlockDeviceQuery)) {
return LazyOptional.empty();
}
@@ -27,8 +27,8 @@ public abstract class AbstractTileEntityDeviceProvider<T extends TileEntity> imp
return LazyOptional.empty();
}
return getDevice(blockQuery, (T) tileEntity);
return getDeviceInterface(blockQuery, (T) tileEntity);
}
protected abstract LazyOptional<Device> getDevice(final BlockDeviceQuery query, final T tileEntity);
protected abstract LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery query, final T tileEntity);
}

View File

@@ -1,19 +1,19 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.object.Callbacks;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import li.cil.oc2.api.device.provider.DeviceProvider;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import li.cil.oc2.api.device.provider.DeviceQuery;
import li.cil.oc2.common.util.WorldUtils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraftforge.common.util.LazyOptional;
public class BlockDeviceProvider implements DeviceProvider {
public class BlockDeviceInterfaceProvider implements DeviceInterfaceProvider {
@Override
public LazyOptional<Device> getDevice(final DeviceQuery query) {
public LazyOptional<DeviceInterface> getDeviceInterface(final DeviceQuery query) {
if (!(query instanceof BlockDeviceQuery)) {
return LazyOptional.empty();
}
@@ -30,6 +30,6 @@ public class BlockDeviceProvider implements DeviceProvider {
}
final String typeName = WorldUtils.getBlockName(blockQuery.getWorld(), blockQuery.getQueryPosition());
return LazyOptional.of(() -> new ObjectDevice(block, typeName));
return LazyOptional.of(() -> new ObjectDeviceInterface(block, typeName));
}
}

View File

@@ -1,23 +1,23 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.object.Callback;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import li.cil.oc2.common.capabilities.Capabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
public class EnergyStorageDeviceProvider extends AbstractCapabilityAnyTileEntityDeviceProvider<IEnergyStorage> {
public class EnergyStorageDeviceInterfaceProvider extends AbstractCapabilityAnyTileEntityDeviceInterfaceProvider<IEnergyStorage> {
private static final String ENERGY_STORAGE_TYPE_NAME = "energyStorage";
public EnergyStorageDeviceProvider() {
public EnergyStorageDeviceInterfaceProvider() {
super(() -> Capabilities.ENERGY_STORAGE_CAPABILITY);
}
@Override
protected LazyOptional<Device> getDevice(final BlockDeviceQuery query, final IEnergyStorage value) {
return LazyOptional.of(() -> new ObjectDevice(new EnergyStorageDevice(value), ENERGY_STORAGE_TYPE_NAME));
protected LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery query, final IEnergyStorage value) {
return LazyOptional.of(() -> new ObjectDeviceInterface(new EnergyStorageDevice(value), ENERGY_STORAGE_TYPE_NAME));
}
public static final class EnergyStorageDevice extends AbstractObjectProxy<IEnergyStorage> {

View File

@@ -1,24 +1,24 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.object.Callback;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import li.cil.oc2.common.capabilities.Capabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
public class FluidHandlerDeviceProvider extends AbstractCapabilityAnyTileEntityDeviceProvider<IFluidHandler> {
public class FluidHandlerDeviceInterfaceProvider extends AbstractCapabilityAnyTileEntityDeviceInterfaceProvider<IFluidHandler> {
private static final String FLUID_HANDLER_TYPE_NAME = "fluidHandler";
public FluidHandlerDeviceProvider() {
public FluidHandlerDeviceInterfaceProvider() {
super(() -> Capabilities.FLUID_HANDLER_CAPABILITY);
}
@Override
protected LazyOptional<Device> getDevice(final BlockDeviceQuery query, final IFluidHandler value) {
return LazyOptional.of(() -> new ObjectDevice(new FluidHandlerDevice(value), FLUID_HANDLER_TYPE_NAME));
protected LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery query, final IFluidHandler value) {
return LazyOptional.of(() -> new ObjectDeviceInterface(new FluidHandlerDevice(value), FLUID_HANDLER_TYPE_NAME));
}
public static final class FluidHandlerDevice extends AbstractObjectProxy<IFluidHandler> {

View File

@@ -1,24 +1,24 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.object.Callback;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import li.cil.oc2.common.capabilities.Capabilities;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
public class ItemHandlerDeviceProvider extends AbstractCapabilityAnyTileEntityDeviceProvider<IItemHandler> {
public class ItemHandlerDeviceInterfaceProvider extends AbstractCapabilityAnyTileEntityDeviceInterfaceProvider<IItemHandler> {
private static final String ITEM_HANDLER_TYPE_NAME = "itemHandler";
public ItemHandlerDeviceProvider() {
public ItemHandlerDeviceInterfaceProvider() {
super(() -> Capabilities.ITEM_HANDLER_CAPABILITY);
}
@Override
protected LazyOptional<Device> getDevice(final BlockDeviceQuery query, final IItemHandler value) {
return LazyOptional.of(() -> new ObjectDevice(new ItemHandlerDevice(value), ITEM_HANDLER_TYPE_NAME));
protected LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery query, final IItemHandler value) {
return LazyOptional.of(() -> new ObjectDeviceInterface(new ItemHandlerDevice(value), ITEM_HANDLER_TYPE_NAME));
}
public static final class ItemHandlerDevice extends AbstractObjectProxy<IItemHandler> {

View File

@@ -0,0 +1,68 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.provider.DeviceInterfaceProvider;
import li.cil.oc2.api.device.provider.DeviceQuery;
import li.cil.oc2.common.device.BlockDeviceQueryImpl;
import li.cil.oc2.common.device.DeviceInterfaceCollection;
import li.cil.oc2.common.device.provider.*;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import java.util.ArrayList;
public final class Providers {
private static final ArrayList<DeviceInterfaceProvider> DEVICE_PROVIDERS = new ArrayList<>();
public static void initialize() {
addProvider(new EnergyStorageDeviceInterfaceProvider());
addProvider(new FluidHandlerDeviceInterfaceProvider());
addProvider(new ItemHandlerDeviceInterfaceProvider());
addProvider(new TileEntityDeviceInterfaceProvider());
addProvider(new BlockDeviceInterfaceProvider());
}
public static void addProvider(final DeviceInterfaceProvider provider) {
if (!DEVICE_PROVIDERS.contains(provider)) {
DEVICE_PROVIDERS.add(provider);
}
}
public static LazyOptional<DeviceInterfaceCollection> getDevice(final TileEntity tileEntity, final Direction side) {
final World world = tileEntity.getWorld();
final BlockPos pos = tileEntity.getPos();
if (world == null) throw new IllegalArgumentException();
return getDevice(world, pos, side);
}
public static LazyOptional<DeviceInterfaceCollection> getDevice(final World world, final BlockPos pos, final Direction side) {
return getDevice(new BlockDeviceQueryImpl(world, pos, side));
}
public static LazyOptional<DeviceInterfaceCollection> getDevice(final DeviceQuery query) {
final ArrayList<DeviceInterface> deviceInterfaces = new ArrayList<>();
final ArrayList<LazyOptional<DeviceInterface>> optionals = new ArrayList<>();
for (final DeviceInterfaceProvider provider : DEVICE_PROVIDERS) {
final LazyOptional<DeviceInterface> optional = provider.getDeviceInterface(query);
optional.ifPresent((device) -> {
deviceInterfaces.add(device);
optionals.add(optional);
});
}
if (deviceInterfaces.isEmpty()) {
return LazyOptional.empty();
} else {
final LazyOptional<DeviceInterfaceCollection> compoundOptional = LazyOptional.of(() -> new DeviceInterfaceCollection(deviceInterfaces));
for (final LazyOptional<DeviceInterface> optional : optionals) {
optional.addListener((ignored) -> compoundOptional.invalidate());
}
return compoundOptional;
}
}
}

View File

@@ -1,24 +1,24 @@
package li.cil.oc2.common.device.provider;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceInterface;
import li.cil.oc2.api.device.object.Callbacks;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.provider.BlockDeviceQuery;
import li.cil.oc2.common.util.WorldUtils;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.LazyOptional;
public final class TileEntityDeviceProvider extends AbstractTileEntityDeviceProvider<TileEntity> {
public TileEntityDeviceProvider() {
public final class TileEntityDeviceInterfaceProvider extends AbstractTileEntityDeviceInterfaceProvider<TileEntity> {
public TileEntityDeviceInterfaceProvider() {
super(TileEntity.class);
}
@Override
public LazyOptional<Device> getDevice(final BlockDeviceQuery query, final TileEntity tileEntity) {
public LazyOptional<DeviceInterface> getDeviceInterface(final BlockDeviceQuery query, final TileEntity tileEntity) {
if (Callbacks.hasMethods(tileEntity)) {
return LazyOptional.of(() -> {
final String typeName = WorldUtils.getBlockName(query.getWorld(), query.getQueryPosition());
return new ObjectDevice(tileEntity, typeName);
return new ObjectDeviceInterface(tileEntity, typeName);
});
} else {
return LazyOptional.empty();

View File

@@ -2,13 +2,13 @@ package li.cil.oc2.serialization.serializers;
import com.google.gson.*;
import li.cil.oc2.api.device.DeviceMethod;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.api.device.Device;
import java.lang.reflect.Type;
public final class DeviceJsonSerializer implements JsonSerializer<IdentifiableDevice> {
public final class DeviceJsonSerializer implements JsonSerializer<Device> {
@Override
public JsonElement serialize(final IdentifiableDevice src, final Type typeOfSrc, final JsonSerializationContext context) {
public JsonElement serialize(final Device src, final Type typeOfSrc, final JsonSerializationContext context) {
if (src == null) {
return JsonNull.INSTANCE;
}

View File

@@ -1,7 +1,7 @@
package li.cil.oc2.bus;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.common.bus.DeviceBusControllerImpl;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.sedna.api.device.serial.SerialDevice;
@@ -64,7 +64,7 @@ public class DeviceBusTests {
final DeviceBusElement busElement = mock(DeviceBusElement.class);
when(tileEntity.getCapability(eq(busElementCapability), any())).thenReturn(LazyOptional.of(() -> busElement));
final IdentifiableDevice device = mock(IdentifiableDevice.class);
final Device device = mock(Device.class);
when(busElement.getLocalDevices()).thenReturn(Collections.singletonList(device));
when(device.getUniqueIdentifier()).thenReturn(UUID.randomUUID());

View File

@@ -4,14 +4,14 @@ import com.google.gson.*;
import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.device.DeviceMethod;
import li.cil.oc2.api.device.IdentifiableDevice;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.object.Callback;
import li.cil.oc2.api.device.object.ObjectDevice;
import li.cil.oc2.api.device.object.ObjectDeviceInterface;
import li.cil.oc2.api.device.object.Parameter;
import li.cil.oc2.common.bus.DeviceBusControllerImpl;
import li.cil.oc2.common.bus.DeviceBusElementImpl;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.device.IdentifiableDeviceImpl;
import li.cil.oc2.common.device.DeviceImpl;
import li.cil.sedna.api.device.serial.SerialDevice;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
@@ -65,7 +65,7 @@ public class ObjectDeviceProtocolTests {
public void resetAndReadDescriptor() {
final VoidIntMethod method = new VoidIntMethod();
busElement.addDevice(new TestDevice(method));
busElement.addDevice(new TestDeviceInterface(method));
controller.scan(world, CONTROLLER_POS);
final JsonObject request = new JsonObject();
@@ -90,7 +90,7 @@ public class ObjectDeviceProtocolTests {
@Test
public void simpleMethod() {
final VoidIntMethod method = new VoidIntMethod();
final TestDevice device = new TestDevice(method);
final TestDeviceInterface device = new TestDeviceInterface(method);
busElement.addDevice(device);
controller.scan(world, CONTROLLER_POS);
@@ -103,7 +103,7 @@ public class ObjectDeviceProtocolTests {
@Test
public void returningMethod() {
final IntLongMethod method = new IntLongMethod();
final TestDevice device = new TestDevice(method);
final TestDeviceInterface device = new TestDeviceInterface(method);
busElement.addDevice(device);
controller.scan(world, CONTROLLER_POS);
@@ -117,8 +117,8 @@ public class ObjectDeviceProtocolTests {
@Test
public void annotatedObject() {
final SimpleObject object = new SimpleObject();
final ObjectDevice device = new ObjectDevice(object);
final IdentifiableDeviceImpl identifiableDevice = new IdentifiableDeviceImpl(LazyOptional.of(() -> device), UUID.randomUUID());
final ObjectDeviceInterface device = new ObjectDeviceInterface(object);
final DeviceImpl identifiableDevice = new DeviceImpl(LazyOptional.of(() -> device), UUID.randomUUID());
busElement.addDevice(identifiableDevice);
controller.scan(world, CONTROLLER_POS);
@@ -126,7 +126,7 @@ public class ObjectDeviceProtocolTests {
Assertions.assertEquals(42 + 23, invokeMethod(identifiableDevice, "add", 42, 23).getAsInt());
}
private JsonElement invokeMethod(final IdentifiableDevice device, final String name, final Object... parameters) {
private JsonElement invokeMethod(final Device device, final String name, final Object... parameters) {
final JsonObject request = new JsonObject();
request.addProperty("type", "invoke");
final JsonObject methodInvocation = new JsonObject();
@@ -243,12 +243,12 @@ public class ObjectDeviceProtocolTests {
}
}
private static final class TestDevice implements IdentifiableDevice {
private static final class TestDeviceInterface implements Device {
private static final UUID UUID = java.util.UUID.randomUUID();
private final DeviceMethod method;
public TestDevice(final DeviceMethod method) {
public TestDeviceInterface(final DeviceMethod method) {
this.method = method;
}