Remove abstract device class; not really worth it.

This commit is contained in:
Florian Nücke
2020-11-29 13:38:17 +01:00
parent fd70381f31
commit 0ea992dac2
7 changed files with 83 additions and 159 deletions

View File

@@ -1,56 +0,0 @@
package li.cil.oc2.api.device;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.common.util.INBTSerializable;
import java.util.*;
/**
* Convenience base class for {@link Device} implementations.
* <p>
* In particular, this implements the logic needed for generating and
* storing the unique ID for this device.
*/
public abstract class AbstractDevice implements Device, INBTSerializable<CompoundNBT> {
protected static final String UUID_NBT_TAG_NAME = "uuid";
protected final List<String> typeNames;
protected UUID uuid;
protected AbstractDevice() {
this(Collections.emptyList());
}
protected AbstractDevice(final Collection<String> typeNames) {
this.typeNames = new ArrayList<>(typeNames);
this.uuid = java.util.UUID.randomUUID();
}
@Override
public UUID getUniqueId() {
return uuid;
}
public void setUniqueId(final UUID uuid) {
this.uuid = uuid;
}
@Override
public List<String> getTypeNames() {
return typeNames;
}
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = new CompoundNBT();
nbt.putUniqueId(UUID_NBT_TAG_NAME, uuid);
return nbt;
}
@Override
public void deserializeNBT(final CompoundNBT nbt) {
if (nbt.hasUniqueId(UUID_NBT_TAG_NAME)) {
uuid = nbt.getUniqueId(UUID_NBT_TAG_NAME);
}
}
}

View File

@@ -1,95 +0,0 @@
package li.cil.oc2.api.device;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraftforge.common.util.INBTSerializable;
import java.util.*;
import java.util.stream.Collectors;
/**
* A utility device type that allows grouping multiple {@link Device} instances.
* <p>
* Serialization of contained devices requires the added devices' unique id to
* have been restored prior to calling {@link #deserializeNBT(CompoundNBT)}.
*/
public class CompoundDevice extends AbstractDevice {
private final ArrayList<Device> devices;
public CompoundDevice(final Collection<Device> devices) {
this.devices = new ArrayList<>(devices);
}
public CompoundDevice(final Device... devices) {
this(Arrays.asList(devices));
}
public CompoundDevice() {
this(Collections.emptyList());
}
/**
* The list of devices grouped in this device.
* <p>
* Use this in case you need to inspect the current list of devices, add new
* devices or remove existing devices.
*/
public List<Device> getDevices() {
return devices;
}
@Override
public List<String> getTypeNames() {
return devices.stream()
.map(Device::getTypeNames)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@Override
public List<DeviceMethod> getMethods() {
return devices.stream()
.map(Device::getMethods)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@SuppressWarnings("rawtypes")
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = super.serializeNBT();
final CompoundNBT devicesNbt = new CompoundNBT();
for (final Device device : devices) {
if (device instanceof INBTSerializable) {
final INBTSerializable serializable = (INBTSerializable) device;
final String uuid = device.getUniqueId().toString();
final INBT deviceNbt = serializable.serializeNBT();
devicesNbt.put(uuid, deviceNbt);
}
}
nbt.put("devices", devicesNbt);
return nbt;
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void deserializeNBT(final CompoundNBT nbt) {
super.deserializeNBT(nbt);
final CompoundNBT devicesNbt = nbt.getCompound("devices");
for (final Device device : devices) {
final String uuid = device.getUniqueId().toString();
if (!devicesNbt.contains(uuid)) {
continue;
}
if (device instanceof INBTSerializable) {
final INBTSerializable serializable = (INBTSerializable) device;
final INBT deviceNbt = devicesNbt.get(uuid);
serializable.deserializeNBT(deviceNbt);
}
}
}
}

View File

@@ -20,8 +20,7 @@ public interface DeviceMethod {
* <p>
* When invoked through a {@link DeviceBusController} this is what the method
* will be referenced by, so the name should be unlikely to be duplicated in
* another device to avoid ambiguity when devices are combined, e.g. in a
* {@link CompoundDevice}.
* another device to avoid ambiguity when devices are combined.
*/
String getName();

View File

@@ -47,7 +47,7 @@ public final class Callbacks {
.filter(m -> m.isAnnotationPresent(Callback.class))
.collect(Collectors.toList()));
final List<DeviceMethod> methods = new ArrayList<>();
final ArrayList<DeviceMethod> methods = new ArrayList<>();
for (final Method method : reflectedMethods) {
try {
methods.add(new ObjectDeviceMethod(methodContainer, method));

View File

@@ -1,11 +1,12 @@
package li.cil.oc2.api.device.object;
import li.cil.oc2.api.device.AbstractDevice;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceMethod;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* A reflection based implementation of {@link Device} using the {@link Callback}
@@ -21,12 +22,15 @@ import java.util.List;
* targeting the workflow using an external object being {@code public}, the ones targeting
* subclassing being {@code protected}.
*/
public class ObjectDevice extends AbstractDevice {
public class ObjectDevice implements Device {
private final ArrayList<String> typeNames;
private final List<DeviceMethod> methods;
private final String className;
public ObjectDevice(final Object object, final List<String> typeNames) {
super(typeNames);
this.typeNames = new ArrayList<>(typeNames);
this.methods = Callbacks.collectMethods(object);
this.className = object.getClass().getSimpleName();
}
public ObjectDevice(final Object object, final String typeName) {
@@ -38,8 +42,9 @@ public class ObjectDevice extends AbstractDevice {
}
protected ObjectDevice(final List<String> typeNames) {
super(typeNames);
this.typeNames = new ArrayList<>(typeNames);
this.methods = Callbacks.collectMethods(this);
this.className = getClass().getSimpleName();
}
protected ObjectDevice(final String typeName) {
@@ -50,8 +55,32 @@ public class ObjectDevice extends AbstractDevice {
this(Collections.emptyList());
}
@Override
public List<String> getTypeNames() {
return typeNames;
}
@Override
public List<DeviceMethod> getMethods() {
return methods;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ObjectDevice that = (ObjectDevice) o;
return typeNames.equals(that.typeNames) &&
methods.equals(that.methods);
}
@Override
public int hashCode() {
return Objects.hash(typeNames, methods);
}
@Override
public String toString() {
return className;
}
}

View File

@@ -1,7 +1,7 @@
package li.cil.oc2.common.capabilities;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.common.vm.DeviceBusElementImpl;
import li.cil.oc2.common.bus.DeviceBusElementImpl;
import net.minecraftforge.common.capabilities.CapabilityManager;
public final class DeviceBusElementCapability {

View File

@@ -0,0 +1,47 @@
package li.cil.oc2.common.device;
import li.cil.oc2.api.device.Device;
import li.cil.oc2.api.device.DeviceMethod;
import java.util.ArrayList;
import java.util.Collection;
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 CompoundDevice(final ArrayList<Device> devices) {
this.devices = devices;
}
@Override
public List<String> getTypeNames() {
return devices.stream()
.map(Device::getTypeNames)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@Override
public List<DeviceMethod> getMethods() {
return devices.stream()
.map(Device::getMethods)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@Override
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);
}
@Override
public int hashCode() {
return Objects.hash(devices);
}
}