package com.rwtema.funkylocomotion.proxydelegates; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import org.apache.commons.lang3.Validate; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; public class ProxyRegistry { public static final HashMap<Class<?>, HashMap<Object, Object>> proxies = new HashMap<>(); public static <T> T register(Object a, Class<? extends T> iface, T proxy) { Validate.isTrue(proxy != null); Validate.isTrue(a != null); Validate.isTrue(iface.isAssignableFrom(proxy.getClass())); if (iface.isAssignableFrom(a.getClass())) return iface.cast(a); HashMap<Object, Object> h = proxies.get(iface); if (h == null) { h = new HashMap<>(); proxies.put(iface, h); } h.put(a, iface.cast(proxy)); return iface.cast(proxy); } @SuppressWarnings("unchecked") public static <T> T getInterface(Object a, Class<? extends T> iface, Capability<T> capability) { if (a == null) return null; if (a instanceof ICapabilityProvider) { ICapabilityProvider capabilityProvider = (ICapabilityProvider) a; if (capabilityProvider.hasCapability(capability, null)) { T t = capabilityProvider.getCapability(capability, null); if (t != null) return t; } } Class<?> aClass = a.getClass(); if (iface.isAssignableFrom(aClass)) { return (T) a; } HashMap<Object, Object> proxyMap = proxies.get(iface); if (proxyMap == null) return null; Object obj = proxyMap.get(a); if (obj == null) { if (proxyMap.containsKey(aClass)) { obj = proxyMap.get(aClass); } else { LinkedList<Class<?>> toCheck = new LinkedList<>(); Collections.addAll(toCheck, aClass.getInterfaces()); Class<?> poll; while ((poll = toCheck.poll()) != null) { obj = proxyMap.get(poll); if (obj != null) { proxyMap.put(aClass, obj); break; } Collections.addAll(toCheck, poll.getInterfaces()); } if (obj == null) proxyMap.put(aClass, null); } } if (obj == null) return null; else return (T) obj; } }