9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-19 15:09:18 +00:00

replace IrisCustomData class with a proxy to keep full access to the base BlockData

This commit is contained in:
Julian Krings
2025-11-26 21:32:13 +01:00
parent f7a459f3bc
commit 528c97f367
4 changed files with 63 additions and 112 deletions

View File

@@ -67,7 +67,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider {
BlockData blockData = Bukkit.createBlockData(material);
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
leaves.setPersistent(true);
return new IrisCustomData(blockData, ExternalDataSVC.buildState(blockId, state));
return IrisCustomData.of(blockData, ExternalDataSVC.buildState(blockId, state));
}
@NotNull

View File

@@ -72,7 +72,7 @@ public class MythicCrucibleDataProvider extends ExternalDataProvider {
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
if (furnitureItemContext != null) {
return new IrisCustomData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
return IrisCustomData.of(B.getAir(), ExternalDataSVC.buildState(blockId, state));
} else if (blockItemContext != null) {
return blockItemContext.getBlockData();
}

View File

@@ -49,9 +49,9 @@ public class NexoDataProvider extends ExternalDataProvider {
BlockData data = NexoBlocks.blockData(blockId.key());
if (data == null)
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
return new IrisCustomData(data, blockState);
return IrisCustomData.of(data, blockState);
} else if (NexoFurniture.isFurniture(blockId.key())) {
return new IrisCustomData(B.getAir(), blockState);
return IrisCustomData.of(B.getAir(), blockState);
}
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());

View File

@@ -1,127 +1,78 @@
package com.volmit.iris.util.data;
import com.volmit.iris.core.link.Identifier;
import lombok.Data;
import com.volmit.iris.util.collection.KMap;
import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SoundGroup;
import org.bukkit.block.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.structure.Mirror;
import org.bukkit.block.structure.StructureRotation;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Data
public class IrisCustomData implements BlockData {
private final @NonNull BlockData base;
private final @NotNull Identifier custom;
import java.lang.reflect.Proxy;
import java.util.*;
@NotNull
@Override
public Material getMaterial() {
return base.getMaterial();
public interface IrisCustomData extends BlockData {
@NonNull BlockData getBase();
@NonNull Identifier getCustom();
static IrisCustomData of(@NotNull BlockData base, @NotNull Identifier custom) {
var clazz = base.getClass();
var loader = clazz.getClassLoader();
return (IrisCustomData) Proxy.newProxyInstance(loader, Internal.getInterfaces(loader, clazz), (proxy, method, args) ->
switch (method.getName()) {
case "getBase" -> base;
case "getCustom" -> custom;
case "merge" -> of(base.merge((BlockData) args[0]), custom);
case "clone" -> of(base.clone(), custom);
case "hashCode" -> Objects.hash(base, custom);
case "copyTo" -> throw new UnsupportedOperationException("Cannot copy from custom block data");
case "matches" -> {
if (!(args[0] instanceof IrisCustomData store))
yield false;
yield base.matches(store.getBase()) && custom.equals(store.getCustom());
}
case "equals" -> {
if (!(args[0] instanceof IrisCustomData store))
yield false;
yield store.getBase().equals(base) && store.getCustom().equals(custom);
}
default -> method.invoke(base, args);
});
}
@NotNull
@Override
public String getAsString() {
return base.getAsString();
@ApiStatus.Internal
abstract class Internal {
private static final KMap<Class<?>, Class<?>[]> cache = new KMap<>();
private static Class<?>[] getInterfaces(ClassLoader loader, Class<?> base) {
return cache.computeIfAbsent(base, k -> {
Queue<Class<?>> queue = new LinkedList<>();
Set<Class<?>> set = new HashSet<>();
queue.add(k);
while (!queue.isEmpty()) {
Class<?> i = queue.poll();
if (!BlockData.class.isAssignableFrom(i))
continue;
for (Class<?> j : i.getInterfaces()) {
if (j.isSealed() || j.isHidden())
continue;
try {
Class.forName(j.getName(), false, loader);
set.add(j);
} catch (ClassNotFoundException ignored) {}
}
@NotNull
@Override
public String getAsString(boolean b) {
return base.getAsString(b);
var parent = i.getSuperclass();
if (parent != null)
queue.add(parent);
}
@NotNull
@Override
public BlockData merge(@NotNull BlockData blockData) {
return new IrisCustomData(base.merge(blockData), custom);
}
@Override
public boolean matches(@Nullable BlockData blockData) {
if (blockData instanceof IrisCustomData b)
return custom.equals(b.custom) && base.matches(b.base);
return base.matches(blockData);
}
@NotNull
@Override
public BlockData clone() {
return new IrisCustomData(base.clone(), custom);
}
@NotNull
@Override
public SoundGroup getSoundGroup() {
return base.getSoundGroup();
}
@Override
public int getLightEmission() {
return base.getLightEmission();
}
@Override
public boolean isOccluding() {
return base.isOccluding();
}
@Override
public boolean requiresCorrectToolForDrops() {
return base.requiresCorrectToolForDrops();
}
@Override
public boolean isPreferredTool(@NotNull ItemStack itemStack) {
return base.isPreferredTool(itemStack);
}
@NotNull
@Override
public PistonMoveReaction getPistonMoveReaction() {
return base.getPistonMoveReaction();
}
@Override
public boolean isSupported(@NotNull Block block) {
return base.isSupported(block);
}
@Override
public boolean isSupported(@NotNull Location location) {
return base.isSupported(location);
}
@Override
public boolean isFaceSturdy(@NotNull BlockFace blockFace, @NotNull BlockSupport blockSupport) {
return base.isFaceSturdy(blockFace, blockSupport);
}
@NotNull
@Override
public Material getPlacementMaterial() {
return base.getPlacementMaterial();
}
@Override
public void rotate(@NotNull StructureRotation structureRotation) {
base.rotate(structureRotation);
}
@Override
public void mirror(@NotNull Mirror mirror) {
base.mirror(mirror);
}
@NotNull
@Override
public BlockState createBlockState() {
return base.createBlockState();
set.add(IrisCustomData.class);
return set.toArray(Class<?>[]::new);
});
}
}
}