Merge pull request #2933 from Owain94/config-enumset-ugh

config: Support for EnumSet
This commit is contained in:
Owain van Brakel
2021-02-22 23:32:51 +01:00
committed by GitHub
3 changed files with 168 additions and 0 deletions

View File

@@ -56,4 +56,12 @@ public @interface ConfigItem
Class<?> clazz() default void.class;
String method() default "";
/**
* Use this to indicate the enum class that is going to be used in the multiple select config.
* This implementation made debugging problems with multiple selects a lot easier
*
* @return The Enum that will be used for the multiple select
*/
Class<? extends Enum> enumClass() default Enum.class;
}

View File

@@ -59,6 +59,7 @@ import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -95,6 +96,7 @@ import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ClientShutdown;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.RuneScapeProfileChanged;
import net.runelite.client.plugins.OPRSExternalPluginManager;
import net.runelite.client.util.ColorUtil;
import net.runelite.http.api.config.ConfigClient;
import net.runelite.http.api.config.ConfigEntry;
@@ -841,6 +843,41 @@ public class ConfigManager
{
return Base64.getUrlDecoder().decode(str);
}
if (type == EnumSet.class)
{
try
{
String substring = str.substring(str.indexOf("{") + 1, str.length() - 1);
String[] splitStr = substring.split(", ");
Class<? extends Enum> enumClass = null;
if (!str.contains("{"))
{
return null;
}
enumClass = findEnumClass(str, OPRSExternalPluginManager.pluginClassLoaders);
EnumSet enumSet = EnumSet.noneOf(enumClass);
for (String s : splitStr)
{
try
{
enumSet.add(Enum.valueOf(enumClass, s.replace("[", "").replace("]", "")));
}
catch (IllegalArgumentException ignore)
{
return EnumSet.noneOf(enumClass);
}
}
return enumSet;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
return str;
}
@@ -892,6 +929,16 @@ public class ConfigManager
{
return Base64.getUrlEncoder().encodeToString((byte[]) object);
}
if (object instanceof EnumSet)
{
if (((EnumSet) object).size() == 0)
{
return getElementType((EnumSet) object).getCanonicalName() + "{}";
}
return ((EnumSet) object).toArray()[0].getClass().getCanonicalName() + "{" + object.toString() + "}";
}
return object == null ? null : object.toString();
}
@@ -924,6 +971,59 @@ public class ConfigManager
}
}
public static <T extends Enum<T>> Class<T> getElementType(EnumSet<T> enumSet)
{
if (enumSet.isEmpty())
{
enumSet = EnumSet.complementOf(enumSet);
}
return enumSet.iterator().next().getDeclaringClass();
}
public static Class<? extends Enum> findEnumClass(String clasz, ArrayList<ClassLoader> classLoaders)
{
StringBuilder transformedString = new StringBuilder();
for (ClassLoader cl : classLoaders)
{
try
{
String[] strings = clasz.substring(0, clasz.indexOf("{")).split("\\.");
int i = 0;
while (i != strings.length)
{
if (i == 0)
{
transformedString.append(strings[i]);
}
else if (i == strings.length - 1)
{
transformedString.append("$").append(strings[i]);
}
else
{
transformedString.append(".").append(strings[i]);
}
i++;
}
return (Class<? extends Enum>) cl.loadClass(transformedString.toString());
}
catch (Exception e2)
{
// Will likely fail a lot
}
try
{
return (Class<? extends Enum>) cl.loadClass(clasz.substring(0, clasz.indexOf("{")));
}
catch (Exception e)
{
// Will likely fail a lot
}
transformedString = new StringBuilder();
}
throw new RuntimeException("Failed to find Enum for " + clasz.substring(0, clasz.indexOf("{")));
}
@Nullable
private CompletableFuture<Void> sendConfig()
{

View File

@@ -44,7 +44,10 @@ import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.inject.Inject;
@@ -702,6 +705,37 @@ class ConfigPanel extends PluginPanel
item.add(button, BorderLayout.EAST);
}
if (cid.getType() == EnumSet.class)
{
Class enumType = cid.getItem().enumClass();
EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(),
cid.getItem().keyName(), EnumSet.class);
if (enumSet == null || enumSet.contains(null))
{
enumSet = EnumSet.noneOf(enumType);
}
JPanel enumsetLayout = new JPanel(new GridLayout(0, 2));
List<JCheckBox> jcheckboxes = new ArrayList<>();
for (Object obj : enumType.getEnumConstants())
{
String option = String.valueOf(obj).toLowerCase().replace("_", " ");
JCheckBox checkbox = new JCheckBox(option);
checkbox.setBackground(ColorScheme.LIGHT_GRAY_COLOR);
checkbox.setSelected(enumSet.contains(obj));
jcheckboxes.add(checkbox);
enumsetLayout.add(checkbox);
}
jcheckboxes.forEach(checkbox -> checkbox.addActionListener(ae -> changeConfiguration(jcheckboxes, cd, cid)));
item.add(enumsetLayout, BorderLayout.SOUTH);
}
JPanel section = sectionWidgets.get(cid.getItem().section());
JPanel title = titleWidgets.get(cid.getItem().title());
@@ -788,6 +822,32 @@ class ConfigPanel extends PluginPanel
}
}
private void changeConfiguration(List<JCheckBox> components, ConfigDescriptor cd, ConfigItemDescriptor cid)
{
Class<? extends Enum> enumType = cid.getItem().enumClass();
EnumSet enumSet = configManager.getConfiguration(cd.getGroup().value(),
cid.getItem().keyName(), EnumSet.class);
if (enumSet == null)
{
//noinspection unchecked
enumSet = EnumSet.noneOf(enumType);
}
enumSet.clear();
EnumSet finalEnumSet = enumSet;
//noinspection unchecked
components.forEach(value ->
{
if (value.isSelected())
{
finalEnumSet.add(Enum.valueOf(cid.getItem().enumClass(), String.valueOf(value.getText()).toUpperCase().replace(" ", "_")));
}
});
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), finalEnumSet);
}
private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid)
{
final ConfigItem configItem = cid.getItem();