From 0191cfdcac908480434d0eb4f1181a2c29d330fe Mon Sep 17 00:00:00 2001 From: Maftei Albert-Alexandru Date: Sun, 5 Nov 2023 01:56:22 +0200 Subject: [PATCH] Add array config support (#144) Add support for using fixed-size arrays in configuration variables. --- .../config/reflection/ArrayProvider.java | 54 +++++++++++++ .../config/reflection/ReflectionConfig.java | 78 +++++++++++++++++-- .../ftc/teamcode/ArrayTestOpMode.java | 34 ++++++++ 3 files changed, 158 insertions(+), 8 deletions(-) create mode 100644 DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ArrayProvider.java create mode 100644 TeamCode/src/main/java/org/firstinspires/ftc/teamcode/ArrayTestOpMode.java diff --git a/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ArrayProvider.java b/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ArrayProvider.java new file mode 100644 index 000000000..74420ecf1 --- /dev/null +++ b/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ArrayProvider.java @@ -0,0 +1,54 @@ +package com.acmerobotics.dashboard.config.reflection; + +import com.acmerobotics.dashboard.config.ValueProvider; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; + +public class ArrayProvider implements ValueProvider { + private final Field field; + private final Object parent; + private final int[] indices; + public ArrayProvider(Field field, Object parent, int... indices) { + this.field = field; + this.parent = parent; + this.indices = indices; + } + @SuppressWarnings("unchecked") + @Override + public T get() { + try { + return (T) getArrayRecursive(field.get(parent), indices); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch(ArrayIndexOutOfBoundsException e) + { + return null; + } + } + @Override + public void set(T value) { + try { + setArrayRecursive(field.get(parent), value, indices); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + }catch(ArrayIndexOutOfBoundsException ignored) { } + } + + + public static Object getArrayRecursive(Object object, int[] indices) throws ArrayIndexOutOfBoundsException, IllegalAccessException + { + for (int index : indices) { + object = Array.get(object, index); + } + return object; + } + public static void setArrayRecursive(Object object, Object value, int[] indices) + { + for(int i=0;i< indices.length-1;i++) + { + object=Array.get(object,indices[i]); + } + Array.set(object,indices[indices.length-1], value); + } +} diff --git a/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ReflectionConfig.java b/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ReflectionConfig.java index b52d158ec..73fe6b791 100644 --- a/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ReflectionConfig.java +++ b/DashboardCore/src/main/java/com/acmerobotics/dashboard/config/reflection/ReflectionConfig.java @@ -5,8 +5,10 @@ import com.acmerobotics.dashboard.config.variable.CustomVariable; import com.acmerobotics.dashboard.config.variable.VariableType; +import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Arrays; public class ReflectionConfig { private ReflectionConfig() {} @@ -24,7 +26,60 @@ public static CustomVariable createVariableFromClass(Class configClass) { return customVariable; } + private static ConfigVariable createVariableFromArrayField(Field field, Class fieldClass, Object parent, int[] indices) { + VariableType type = VariableType.fromClass(fieldClass); + switch (type) { + case BOOLEAN: + case INT: + case DOUBLE: + case STRING: + case ENUM: + return new BasicVariable<>(type, new ArrayProvider(field, parent,Arrays.copyOf(indices, indices.length))); + case CUSTOM: + try { + Object value = null; + try { + value = ArrayProvider.getArrayRecursive(field.get(parent), indices); + }catch (ArrayIndexOutOfBoundsException ignored ) + { + } + + if (value == null) { + return new CustomVariable(null); + } + CustomVariable customVariable = new CustomVariable(); + if(fieldClass.isArray()) + { + int[] newIndices = Arrays.copyOf(indices, indices.length+1); + + for(int i = 0; i createVariableFromField(Field field, Object parent) { Class fieldClass = field.getType(); VariableType type = VariableType.fromClass(fieldClass); @@ -41,18 +96,25 @@ private static ConfigVariable createVariableFromField(Field field, Object par if (value == null) { return new CustomVariable(null); } - CustomVariable customVariable = new CustomVariable(); - for (Field nestedField : fieldClass.getFields()) { - if (Modifier.isFinal(field.getModifiers())) { - continue; + if(fieldClass.isArray()) + { + for(int i = 0; i