Moved cached proxies into cached factories

This commit is contained in:
Auxilor
2021-01-17 13:35:53 +00:00
parent 8be8e1dab2
commit f67f01278e
3 changed files with 63 additions and 41 deletions

View File

@@ -318,6 +318,9 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.getScheduler().cancelAll();
this.disable();
INSTANCES.remove(this.getClass());
INSTANCES.remove(this.getClass(), this);
}
/**

View File

@@ -4,20 +4,17 @@ import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.IdentityHashMap;
import java.util.Map;
public class ProxyFactory<T extends AbstractProxy> extends PluginDependent {
/**
* Cached proxy implementations in order to not perform expensive reflective class-finding.
*/
private static final Map<Class<? extends AbstractProxy>, AbstractProxy> CACHE = new IdentityHashMap<>();
/**
* The class of the proxy interface.
*/
private final Class<T> proxyClass;
/**
* The instance of the proxy.
*/
private final T instance;
/**
* Create a new Proxy Factory for a specific type.
*
@@ -28,6 +25,20 @@ public class ProxyFactory<T extends AbstractProxy> extends PluginDependent {
@NotNull final Class<T> proxyClass) {
super(plugin);
this.proxyClass = proxyClass;
try {
String className = this.getPlugin().getProxyPackage() + "." + ProxyConstants.NMS_VERSION + "." + proxyClass.getSimpleName().replace("Proxy", "");
final Class<?> class2 = Class.forName(className);
Object instance = class2.getConstructor().newInstance();
if (proxyClass.isInstance(instance)) {
this.instance = proxyClass.cast(instance);
} else {
throw new UnsupportedVersionException("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION);
}
} catch (Exception e) {
throw new UnsupportedVersionException("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION);
}
}
/**
@@ -36,37 +47,6 @@ public class ProxyFactory<T extends AbstractProxy> extends PluginDependent {
* @return The proxy implementation.
*/
public @NotNull T getProxy() {
try {
T cachedProxy = attemptCache();
if (cachedProxy != null) {
return cachedProxy;
}
String className = this.getPlugin().getProxyPackage() + "." + ProxyConstants.NMS_VERSION + "." + proxyClass.getSimpleName().replace("Proxy", "");
final Class<?> class2 = Class.forName(className);
Object instance = class2.getConstructor().newInstance();
if (proxyClass.isAssignableFrom(class2) && proxyClass.isInstance(instance)) {
T proxy = proxyClass.cast(instance);
CACHE.put(proxyClass, proxy);
return proxy;
}
} catch (Exception e) {
// If not returned, then throw error
}
throw new UnsupportedVersionException("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION);
}
private T attemptCache() {
Object proxy = CACHE.get(proxyClass);
if (proxy == null) {
return null;
}
if (proxyClass.isInstance(proxy)) {
return proxyClass.cast(proxy);
}
return null;
return instance;
}
}

View File

@@ -3,8 +3,18 @@ package com.willfp.eco.util.proxy;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("unchecked")
public class ProxyFactoryFactory extends PluginDependent {
/**
* Cached proxy implementations in order to not perform expensive reflective class-finding.
*/
private final Map<Class<? extends AbstractProxy>, ProxyFactory<? extends AbstractProxy>> cache = new HashMap<>();
/**
* Pass an {@link AbstractEcoPlugin} in order to interface with it.
*
@@ -22,6 +32,35 @@ public class ProxyFactoryFactory extends PluginDependent {
* @return The factory.
*/
public <T extends AbstractProxy> ProxyFactory<T> getFactory(@NotNull final Class<T> proxyClass) {
return new ProxyFactory<>(this.getPlugin(), proxyClass);
ProxyFactory<T> cached = getCached(proxyClass);
if (cached == null) {
cache(proxyClass, new ProxyFactory<>(this.getPlugin(), proxyClass));
} else {
return cached;
}
return getFactory(proxyClass);
}
/**
* Cache proxy factory.
*
* @param proxyClass The class.
* @param factory The factory.
*/
public void cache(@NotNull final Class<? extends AbstractProxy> proxyClass,
@NotNull final ProxyFactory<? extends AbstractProxy> factory) {
cache.put(proxyClass, factory);
}
/**
* Get cached proxy factory.
*
* @param proxyClass The class.
* @param <T> The type of proxy.
* @return The factory.
*/
@Nullable
public <T extends AbstractProxy> ProxyFactory<T> getCached(@NotNull final Class<T> proxyClass) {
return (ProxyFactory<T>) cache.get(proxyClass);
}
}