Skip to content

Commit

Permalink
Merge branch 'AE2-UEL:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
KasumiNova authored Feb 2, 2024
2 parents d8c9c54 + ec2c3eb commit bed1517
Show file tree
Hide file tree
Showing 35 changed files with 1,598 additions and 130 deletions.
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
*/
dependencies {
implementation rfg.deobf("curse.maven:ae2-extended-life-570458:5035908")
implementation rfg.deobf("curse.maven:ae2-extended-life-570458:5073329")
implementation rfg.deobf("curse.maven:ae2-fluid-crafting-rework-623955:4804730")
compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667")
compileOnlyApi rfg.deobf("curse.maven:jei-238222:4538010")
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/co/neeve/nae2/NAE2.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@
public class NAE2 {
public static NAE2 instance;
private static ConfigManager configManager;
private final Logger logger = LogManager.getLogger("NAE2");
private final Logger logger = LogManager.getLogger(Tags.MODID.toUpperCase());
private final NetHandler network = new NetHandler();
private final NAE2API api = new NAE2API();
private Registration registration;

private GuiHandler guiHandler;

@SideOnly(Side.CLIENT)
private ItemStack icon;

Expand All @@ -55,6 +54,15 @@ public static Registration definitions() {
return instance.registration;
}

/**
* Returns the NAE2API for NAE2.
*
* @return NAE2 NAE2API
*/
public static NAE2API api() {
return instance.api;
}

@SideOnly(Side.CLIENT)
public static ItemStack icon() {
return instance.icon;
Expand Down Expand Up @@ -122,4 +130,5 @@ public ConfigManager() {
config.save();
}
}

}
18 changes: 18 additions & 0 deletions src/main/java/co/neeve/nae2/NAE2API.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package co.neeve.nae2;

import co.neeve.nae2.common.api.ExposerAPI;

public class NAE2API {
private final ExposerAPI exposerAPI = new ExposerAPI();

NAE2API() {}

/**
* Returns the Exposer API.
*
* @return Exposer API
*/
public ExposerAPI exposer() {
return this.exposerAPI;
}
}
177 changes: 177 additions & 0 deletions src/main/java/co/neeve/nae2/common/api/ExposerAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package co.neeve.nae2.common.api;

import appeng.api.storage.data.IAEStack;
import co.neeve.nae2.NAE2;
import co.neeve.nae2.common.interfaces.IExposerHandler;
import co.neeve.nae2.common.interfaces.IExposerHost;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
* API for the Exposer block/part.
*
* @author NotMyWing
*/
public class ExposerAPI {
@SuppressWarnings("rawtypes")
private final DataHolder dataHolder = new DataHolder();

@SideOnly(Side.CLIENT)
public void addTooltipInformation(ItemStack stack, World world, List<String> lines,
ITooltipFlag advancedTooltips) {
lines.add(I18n.format("nae2.exposer.tooltip"));

var registered = this.getRegisteredHandlers();
if (registered.isEmpty()) {
lines.add("");
lines.add(I18n.format("nae2.exposer.noneregistered"));
} else {
lines.add("");
lines.add(I18n.format("nae2.exposer.registered"));

for (var handler : registered.object2ObjectEntrySet()) {
var name = handler.getKey().getName();

// If name is a class path, strip everything but the name.
if (name.contains(".")) {
name = name.substring(name.lastIndexOf('.') + 1);
}

lines.add(" - "
+ "§6" + name + "§r"
+ " (" + handler.getValue().getMod().getAnnotation(Mod.class).name() + ")");
}
}
}

/**
* Creates a handler for the given host and capability.
*
* @param host Host to create the handler for
* @param capability Capability to create the handler for
* @param <T> Type of stack handled by the handler
* @return Handler for the given host and capability
*/
@SuppressWarnings("unchecked")
public <T extends IAEStack<T>> IExposerHandler<T> createHandler(IExposerHost host, Capability<?> capability) {
var info = this.getHandlerInfo(capability);
if (info == null) {
return null;
}

try {
var result = info.getHandlerClass().getConstructor(IExposerHost.class).newInstance(host);
NAE2.logger().debug("Created exposer handler for capability {} at {}: {}",
capability,
host.getProxy().getLocation(),
result);

return (IExposerHandler<T>) result;
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}

/**
* Registers a handler for the given capability.
*
* @param mod Mod class for the handler
* @param capability Capability to register the handler for
* @param exposerClass Handler class
* @param <T> Type of stack handled by the handler
*/
@SuppressWarnings("unchecked")
public <T extends IAEStack<T>> void registerHandler(Class<?> mod, Capability<?> capability,
Class<? extends IExposerHandler<T>> exposerClass) {
var handlerInfo = new HandlerInfo<>(exposerClass, mod);
this.dataHolder.registeredHandlers.put(capability, handlerInfo);
}

/**
* Returns an immutable map of registered handlers.
*
* @return Map of registered handlers
*/
@SuppressWarnings("unchecked")
public <T extends IAEStack<T>, U extends Capability<?>> Object2ObjectMap<U, HandlerInfo<T>> getRegisteredHandlers() {
return this.dataHolder.immutableWrapper;
}

/**
* Returns whether the capability is registered for handling by the Exposer API.
*
* @param capability Capability to check
* @return Whether the capability is registered
*/
public boolean isCapabilityRegistered(Capability<?> capability) {
return this.dataHolder.registeredHandlers.containsKey(capability);
}

/**
* Returns information about the handler for the given capability.
*
* @param capability Capability to get handler info for
* @return Handler info for the capability, or null if the capability is not registered
*/
@Nullable
@SuppressWarnings("unchecked")
public <T extends IAEStack<T>, U extends Capability<?>> HandlerInfo<T> getHandlerInfo(U capability) {
return (HandlerInfo<T>) this.dataHolder.registeredHandlers.getOrDefault(capability, null);
}

public static final class HandlerInfo<T extends IAEStack<T>> {
private final Class<? extends IExposerHandler<T>> handlerClass;
private final Class<?> mod;

private HandlerInfo(@NotNull Class<? extends IExposerHandler<T>> handlerClass, @NotNull Class<?> mod) {
// Check mod for the Mod annotation and throw if it doesn't exist.
if (!mod.isAnnotationPresent(Mod.class)) {
throw new IllegalArgumentException("Mod class must be annotated with @Mod");
}

this.handlerClass = handlerClass;
this.mod = mod;
}

/**
* Returns the handler class.
*
* @return Handler class
*/
public Class<? extends IExposerHandler<T>> getHandlerClass() {return this.handlerClass;}

/**
* Returns the mod class for the handler.
*
* @return Mod class for the handler
*/
public Class<?> getMod() {return this.mod;}
}

/**
* Holds the data for the Exposer API.
* Necessary to make this its own class because of the generic type.
*/
private static class DataHolder<T extends IAEStack<T>, U extends Capability<?>> {
private final Object2ObjectMap<U, HandlerInfo<T>> registeredHandlers =
new Object2ObjectOpenHashMap<>();

private final Object2ObjectMap<U, HandlerInfo<T>> immutableWrapper =
Object2ObjectMaps.unmodifiable(this.registeredHandlers);
}
}
26 changes: 26 additions & 0 deletions src/main/java/co/neeve/nae2/common/blocks/BlockExposer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package co.neeve.nae2.common.blocks;

import appeng.block.AEBaseTileBlock;
import co.neeve.nae2.NAE2;
import net.minecraft.block.material.Material;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import java.util.List;

public class BlockExposer extends AEBaseTileBlock {
public BlockExposer() {
super(Material.IRON);
}

@Override
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack is, World world, List<String> lines, ITooltipFlag advancedItemTooltips) {
super.addInformation(is, world, lines, advancedItemTooltips);

NAE2.api().exposer().addTooltipInformation(is, world, lines, advancedItemTooltips);
}
}
3 changes: 2 additions & 1 deletion src/main/java/co/neeve/nae2/common/features/Features.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public boolean isEnabled() {
},
DENSE_CELLS(EnumSet.allOf(DenseCellFeatures.class)),
DENSE_CPU_COPROCESSORS("dense.coprocessor"),
DENSE_FLUID_CELLS();
DENSE_FLUID_CELLS(),
EXPOSER();

private String[] mixins;
private EnumSet<? extends ISubFeature> subFeatures = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package co.neeve.nae2.common.helpers;

import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

public class ObjectIndexableLinkedOpenHashSet<T> implements Set<T> {
private final ObjectArrayList<T> indexes = new ObjectArrayList<>();
private final ObjectLinkedOpenHashSet<T> values = new ObjectLinkedOpenHashSet<>();

@Override
public int size() {
return this.indexes.size();
}

@Override
public boolean isEmpty() {
return this.indexes.isEmpty();
}

@Override
public boolean contains(Object o) {
return this.values.contains(o);
}

@NotNull
@Override
public Iterator<T> iterator() {
return this.values.iterator();
}

@NotNull
@Override
public Object @NotNull [] toArray() {
return this.values.toArray();
}

@NotNull
@Override
public <T1> T1 @NotNull [] toArray(T1 @NotNull [] a) {
return this.values.toArray(a);
}

@Override
public boolean add(T t) {
if (this.values.add(t)) {
this.indexes.add(t);
return true;
}
return false;
}

@Override
public boolean remove(Object o) {
if (this.values.remove(o)) {
this.indexes.remove(o);
return true;
}
return false;
}

@Override
public boolean containsAll(@NotNull Collection<?> c) {
return this.values.containsAll(c);
}

@Override
public boolean addAll(@NotNull Collection<? extends T> c) {
if (this.values.addAll(c)) {
this.indexes.addAll(c);
return true;
}
return false;
}

@Override
public boolean retainAll(@NotNull Collection<?> c) {
if (this.values.retainAll(c)) {
this.indexes.retainAll(c);
return true;
}
return false;
}

@Override
public boolean removeAll(@NotNull Collection<?> c) {
if (this.values.removeAll(c)) {
this.indexes.removeAll(c);
return true;
}
return false;
}

@Override
public void clear() {
this.values.clear();
this.indexes.clear();
}

public T getByIndex(int index) {
return this.indexes.get(index);
}

public void makeFirst(T o) {
if (this.remove(o)) {
if (this.values.addAndMoveToFirst(o)) {
this.indexes.add(0, o);
}
}
}
}
Loading

0 comments on commit bed1517

Please sign in to comment.