config: add support for enum sets

This commit is contained in:
Adam
2021-11-29 17:50:35 -05:00
parent c3880a8c74
commit 095a0e6257
5 changed files with 116 additions and 45 deletions

View File

@@ -99,11 +99,9 @@ class ConfigInvocationHandler implements InvocationHandler
}
// Convert value to return type
Class<?> returnType = method.getReturnType();
try
{
Object objectValue = ConfigManager.stringToObject(value, returnType);
Object objectValue = manager.stringToObject(value, method.getGenericReturnType());
cache.put(method, objectValue == null ? NULL : objectValue);
return objectValue;
}
@@ -155,7 +153,7 @@ class ConfigInvocationHandler implements InvocationHandler
}
else
{
String newValueStr = ConfigManager.objectToString(newValue);
String newValueStr = manager.objectToString(newValue);
manager.setConfiguration(group.value(), item.keyName(), newValueStr);
}
return null;

View File

@@ -24,13 +24,14 @@
*/
package net.runelite.client.config;
import java.lang.reflect.Type;
import lombok.Value;
@Value
public class ConfigItemDescriptor implements ConfigObject
{
private final ConfigItem item;
private final Class<?> type;
private final Type type;
private final Range range;
private final Alpha alpha;
private final Units units;

View File

@@ -30,6 +30,7 @@ import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.gson.Gson;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
@@ -43,7 +44,9 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.AtomicMoveNotSupportedException;
@@ -120,6 +123,7 @@ public class ConfigManager
private final File settingsFileInput;
private final EventBus eventBus;
private final OkHttpClient okHttpClient;
private final Gson gson;
private AccountSession session;
private ConfigClient configClient;
@@ -143,13 +147,15 @@ public class ConfigManager
ScheduledExecutorService scheduledExecutorService,
EventBus eventBus,
OkHttpClient okHttpClient,
@Nullable Client client)
@Nullable Client client,
Gson gson)
{
this.settingsFileInput = config;
this.eventBus = eventBus;
this.okHttpClient = okHttpClient;
this.client = client;
this.propertiesFile = getPropertiesFile();
this.gson = gson;
scheduledExecutorService.scheduleWithFixedDelay(this::sendConfig, 30, 30, TimeUnit.SECONDS);
}
@@ -449,12 +455,12 @@ public class ConfigManager
return properties.getProperty(getWholeKey(groupName, profile, key));
}
public <T> T getConfiguration(String groupName, String key, Class<T> clazz)
public <T> T getConfiguration(String groupName, String key, Type clazz)
{
return getConfiguration(groupName, null, key, clazz);
}
public <T> T getRSProfileConfiguration(String groupName, String key, Class<T> clazz)
public <T> T getRSProfileConfiguration(String groupName, String key, Type clazz)
{
String rsProfileKey = this.rsProfileKey;
if (rsProfileKey == null)
@@ -465,14 +471,14 @@ public class ConfigManager
return getConfiguration(groupName, rsProfileKey, key, clazz);
}
public <T> T getConfiguration(String groupName, String profile, String key, Class<T> clazz)
public <T> T getConfiguration(String groupName, String profile, String key, Type type)
{
String value = getConfiguration(groupName, profile, key);
if (!Strings.isNullOrEmpty(value))
{
try
{
return (T) stringToObject(value, clazz);
return (T) stringToObject(value, type);
}
catch (Exception e)
{
@@ -525,17 +531,17 @@ public class ConfigManager
eventBus.post(configChanged);
}
public void setConfiguration(String groupName, String profile, String key, Object value)
public <T> void setConfiguration(String groupName, String profile, String key, T value)
{
setConfiguration(groupName, profile, key, objectToString(value));
}
public void setConfiguration(String groupName, String key, Object value)
public <T> void setConfiguration(String groupName, String key, T value)
{
setConfiguration(groupName, null, key, value);
}
public void setRSProfileConfiguration(String groupName, String key, Object value)
public <T> void setRSProfileConfiguration(String groupName, String key, T value)
{
String rsProfileKey = this.rsProfileKey;
if (rsProfileKey == null)
@@ -657,7 +663,7 @@ public class ConfigManager
.filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class))
.map(m -> new ConfigItemDescriptor(
m.getDeclaredAnnotation(ConfigItem.class),
m.getReturnType(),
m.getGenericReturnType(),
m.getDeclaredAnnotation(Range.class),
m.getDeclaredAnnotation(Alpha.class),
m.getDeclaredAnnotation(Units.class)
@@ -714,7 +720,7 @@ public class ConfigManager
{
// This checks if it is set and is also unmarshallable to the correct type; so
// we will overwrite invalid config values with the default
Object current = getConfiguration(group.value(), item.keyName(), method.getReturnType());
Object current = getConfiguration(group.value(), item.keyName(), method.getGenericReturnType());
if (current != null)
{
continue; // something else is already set
@@ -748,7 +754,7 @@ public class ConfigManager
}
}
static Object stringToObject(String str, Class<?> type)
Object stringToObject(String str, Type type)
{
if (type == boolean.class || type == Boolean.class)
{
@@ -789,7 +795,7 @@ public class ConfigManager
int height = Integer.parseInt(splitStr[3]);
return new Rectangle(x, y, width, height);
}
if (type.isEnum())
if (type instanceof Class && ((Class<?>) type).isEnum())
{
return Enum.valueOf((Class<? extends Enum>) type, str);
}
@@ -824,11 +830,19 @@ public class ConfigManager
{
return Base64.getUrlDecoder().decode(str);
}
if (type instanceof ParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType() == Set.class)
{
return gson.fromJson(str, parameterizedType);
}
}
return str;
}
@Nullable
static String objectToString(Object object)
String objectToString(Object object)
{
if (object instanceof Color)
{
@@ -875,6 +889,10 @@ public class ConfigManager
{
return Base64.getUrlEncoder().encodeToString((byte[]) object);
}
if (object instanceof Set)
{
return gson.toJson(object, Set.class);
}
return object == null ? null : object.toString();
}

View File

@@ -24,8 +24,10 @@
*/
package net.runelite.client.plugins.config;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
import java.awt.BorderLayout;
import java.awt.Color;
@@ -37,8 +39,12 @@ import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.inject.Inject;
import javax.swing.BorderFactory;
@@ -49,6 +55,7 @@ import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@@ -56,6 +63,8 @@ import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
@@ -97,6 +106,7 @@ import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
import net.runelite.client.util.Text;
import org.apache.commons.lang3.ArrayUtils;
@Slf4j
class ConfigPanel extends PluginPanel
@@ -111,27 +121,6 @@ class ConfigPanel extends PluginPanel
private static final Map<ConfigSectionDescriptor, Boolean> sectionExpandStates = new HashMap<>();
private final FixedWidthPanel mainPanel;
private final JLabel title;
private final PluginToggleButton pluginToggle;
@Inject
private PluginListPanel pluginList;
@Inject
private ConfigManager configManager;
@Inject
private PluginManager pluginManager;
@Inject
private ExternalPluginManager externalPluginManager;
@Inject
private ColorPickerManager colorPickerManager;
private PluginConfigurationDescriptor pluginConfig = null;
static
{
final BufferedImage backIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_back_icon.png");
@@ -147,10 +136,32 @@ class ConfigPanel extends PluginPanel
SECTION_RETRACT_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(sectionExpandIcon, -100));
}
public ConfigPanel()
private final PluginListPanel pluginList;
private final ConfigManager configManager;
private final PluginManager pluginManager;
private final ExternalPluginManager externalPluginManager;
private final ColorPickerManager colorPickerManager;
private final ListCellRenderer<Enum<?>> listCellRenderer = new ComboBoxListRenderer<>();
private final FixedWidthPanel mainPanel;
private final JLabel title;
private final PluginToggleButton pluginToggle;
private PluginConfigurationDescriptor pluginConfig = null;
@Inject
private ConfigPanel(PluginListPanel pluginList, ConfigManager configManager, PluginManager pluginManager,
ExternalPluginManager externalPluginManager, ColorPickerManager colorPickerManager)
{
super(false);
this.pluginList = pluginList;
this.configManager = configManager;
this.pluginManager = pluginManager;
this.externalPluginManager = externalPluginManager;
this.colorPickerManager = colorPickerManager;
setLayout(new BorderLayout());
setBackground(ColorScheme.DARK_GRAY_COLOR);
@@ -359,7 +370,7 @@ class ConfigPanel extends PluginPanel
{
item.add(createDimension(cd, cid), BorderLayout.EAST);
}
else if (cid.getType().isEnum())
else if (cid.getType() instanceof Class && ((Class<?>) cid.getType()).isEnum())
{
item.add(createComboBox(cd, cid), BorderLayout.EAST);
}
@@ -367,6 +378,14 @@ class ConfigPanel extends PluginPanel
{
item.add(createKeybind(cd, cid), BorderLayout.EAST);
}
else if (cid.getType() instanceof ParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType) cid.getType();
if (parameterizedType.getRawType() == Set.class)
{
item.add(createList(cd, cid), BorderLayout.EAST);
}
}
JPanel section = sectionWidgets.get(cid.getItem().section());
if (section == null)
@@ -581,7 +600,7 @@ class ConfigPanel extends PluginPanel
// set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer
// to build components for each combobox element in order to compute the display size of the
// combobox
box.setRenderer(new ComboBoxListRenderer<>());
box.setRenderer(listCellRenderer);
box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25));
box.setForeground(Color.WHITE);
box.setFocusable(false);
@@ -594,7 +613,7 @@ class ConfigPanel extends PluginPanel
}
catch (IllegalArgumentException ex)
{
log.debug("invalid seleced item", ex);
log.debug("invalid selected item", ex);
}
box.addItemListener(e ->
{
@@ -628,6 +647,34 @@ class ConfigPanel extends PluginPanel
return button;
}
private JList<Enum<?>> createList(ConfigDescriptor cd, ConfigItemDescriptor cid)
{
ParameterizedType parameterizedType = (ParameterizedType) cid.getType();
Class<? extends Enum> type = (Class<? extends Enum>) parameterizedType.getActualTypeArguments()[0];
Set<? extends Enum> set = configManager.getConfiguration(cd.getGroup().value(), null,
cid.getItem().keyName(), parameterizedType);
JList<Enum<?>> list = new JList<Enum<?>>(type.getEnumConstants()); // NOPMD: UseDiamondOperator
list.setCellRenderer(listCellRenderer);
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
list.setLayoutOrientation(JList.VERTICAL);
list.setSelectedIndices(
MoreObjects.firstNonNull(set, Collections.emptySet())
.stream()
.mapToInt(e -> ArrayUtils.indexOf(type.getEnumConstants(), e))
.toArray());
list.addFocusListener(new FocusAdapter()
{
@Override
public void focusLost(FocusEvent e)
{
changeConfiguration(list, cd, cid);
}
});
return list;
}
private void changeConfiguration(Component component, ConfigDescriptor cd, ConfigItemDescriptor cid)
{
final ConfigItem configItem = cid.getItem();
@@ -675,6 +722,13 @@ class ConfigPanel extends PluginPanel
HotkeyButton hotkeyButton = (HotkeyButton) component;
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), hotkeyButton.getValue());
}
else if (component instanceof JList)
{
JList<?> list = (JList<?>) component;
List<?> selectedValues = list.getSelectedValuesList();
configManager.setConfiguration(cd.getGroup().value(), cid.getItem().keyName(), Sets.newHashSet(selectedValues));
}
}
@Override

View File

@@ -59,9 +59,9 @@ public final class ComboBoxListRenderer<T> extends JLabel implements ListCellRen
setBorder(new EmptyBorder(5, 5, 5, 0));
String text;
if (o instanceof Enum)
if (o instanceof Enum<?>)
{
text = Text.titleCase((Enum) o);
text = Text.titleCase((Enum<?>) o);
}
else
{