Skip to content

Commit

Permalink
Add array config support (#144)
Browse files Browse the repository at this point in the history
Add support for using fixed-size arrays in configuration variables.
  • Loading branch information
MafteiAlbert-Alexandru authored Nov 4, 2023
1 parent 42256c7 commit 0191cfd
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -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<T> implements ValueProvider<T> {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Expand All @@ -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<Boolean>(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<Array.getLength(value); i++)
{

newIndices[newIndices.length-1]=i;
customVariable.putVariable(Integer.toString(i), createVariableFromArrayField(field, fieldClass.getComponentType(), parent, newIndices));
}
}
else {
for (Field nestedField : fieldClass.getFields()) {
if (Modifier.isFinal(field.getModifiers())) {
continue;
}

String name = nestedField.getName();
customVariable.putVariable(name,
createVariableFromField(nestedField, value));
}
}
return customVariable;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
default:
throw new RuntimeException("Unsupported field type: " +
fieldClass.getName());
}
}
private static ConfigVariable<?> createVariableFromField(Field field, Object parent) {
Class<?> fieldClass = field.getType();
VariableType type = VariableType.fromClass(fieldClass);
Expand All @@ -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<Array.getLength(value); i++)
{
customVariable.putVariable(Integer.toString(i), createVariableFromArrayField(field, field.getType().getComponentType(), parent, new int[]{i}));
}

String name = nestedField.getName();
customVariable.putVariable(name,
createVariableFromField(nestedField, value));
}
else {
for (Field nestedField : fieldClass.getFields()) {
if (Modifier.isFinal(field.getModifiers())) {
continue;
}

String name = nestedField.getName();
customVariable.putVariable(name,
createVariableFromField(nestedField, value));
}
}
return customVariable;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.firstinspires.ftc.teamcode;

import com.acmerobotics.dashboard.FtcDashboard;
import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.dashboard.telemetry.MultipleTelemetry;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;

@SuppressWarnings("unused")
@Config
@TeleOp
public class ArrayTestOpMode extends LinearOpMode {
public static class NestedClass {
public int a,b;
}
public static int[] array = new int[3];
public static NestedClass[] innerArray = new NestedClass[] { new NestedClass(), new NestedClass(), new NestedClass()};
@Override
public void runOpMode() {
telemetry = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());

waitForStart();
array=new int[2];
while(opModeIsActive())
{
telemetry.addData("array0", array[0]);
telemetry.addData("array1", array[1]);
telemetry.addData("innerArray0A", innerArray[0].a);
telemetry.addData("innerArray1B", innerArray[1].b);
telemetry.addData("innerArray2A", innerArray[2].a);
telemetry.update();
}
}
}

0 comments on commit 0191cfd

Please sign in to comment.