How to access object by using it's name in string format?

Hello, In the following example:
I want to get the p2.y using str.
I searched a lot but couldn’t find how to do this. (I am new to java)
Please Help.

void setup(){
 cord p1 = new cord(2,3);
 cord p2 = new cord(77,88);
 String str = "p2";
 
 //int value = p2.y;  //This the basic way
 int value = someFunction(str); //I want to get p2.y using str
println(value);
}

void draw(){}


class cord {
  int x;
  int y;
  
  cord(int x, int y){
    this.x=x;
    this.y=y;
  }
}

Hi @Ghostsss,

First question would be is it really needed or can it be done another way ?

But there are several methods this can be achieved. I’ve expanded your code to demonstrate.
I would prefer the HashMap version, as it could be easily changed to register all sorts of object types.

Cheers
— mnse

import java.lang.reflect.Field;

final HashMap<String, Coord> registeredCoordObjects = new HashMap<String, Coord>();
Coord p2;

void setup() {
  Coord p1 = new Coord(2, 3);
  p2 = new Coord(77, 88);

  registeredCoordObjects.put("p1", p1);
  registeredCoordObjects.put("p2", p2);
  
  String str = "p2";

  //int value = p2.y;  //This the basic way
  //I want to get p2.y using str
  println("Regular: " + p2.y);
  println("Hash: " + someFunctionHash(str));  
  // only if class member not available if local Variable
  println("Reflection: " + someFunctionReflection(str));
}

void draw() {
}

Coord getCoordObjectByNameViaHashmap(String name) {
  if (registeredCoordObjects.containsKey(name)) {
    return registeredCoordObjects.get(name);
  } else {
    println("Object with ("+name+") not registered!");
    return null;
  }
}

Coord getCoordObjectByNameViaReflection(String name) {
  try {
    Field field = this.getClass().getDeclaredField(name);    
    field.setAccessible(true);
    return (Coord) field.get(this);
  } 
  catch(Exception e) {
    println("Object with ("+name+") not found as class member or wrong type etc!");
    return null;
  }
}

int someFunctionHash(String name) {
  Coord obj = getCoordObjectByNameViaHashmap(name); 
  if (obj != null) {
    return obj.y;
  }
  // object not found
  return Integer.MIN_VALUE; // or whatever indicates not found
}

int someFunctionReflection(String name) {
  Coord obj = getCoordObjectByNameViaReflection(name); 
  if (obj != null) {
    return obj.y;
  }
  // object not found or not initialized
  return Integer.MIN_VALUE; // or whatever indicates not found
}

class Coord {
  int x;
  int y;

  Coord(int x, int y) {
    this.x=x;
    this.y=y;
  }
}

prints out:

Regular: 88
Hash: 88
Reflection: 88

PS: Still another way would be to apply a name variable to your coord class and add all coord objects to a List which you can iterate and search by class member way for the name.

1 Like

Hello mnse,

Thank you very much.

Let me explain why I feel I need to do this. Maybe you can point me towards a better way of doing this.

Background is: I am making a class called IC, it contains an array of registers (8 bit each).
Now these registers stores variables used by IC for its operation. A register can store multiple variables.
So I made a class ICvariables which stores parameters of a variable, like register in which it is stored, position in register, data of variable, etc.
So my class IC will have an int register array and variables of ICVariable type.

And since both register and variables store same data but in different format, thus if data in one is updated then other needs to be updated too.
So I wrote setReg() and setVar() methods.

I successfully wrote method setVar() as in this I update the variable data and also update the corresponding register.

But I am having problem in setReg() because setting register is easy but setting variables corresponding to that register is difficult. I need to access the corresponding variable.
I though I would add an string array “regContent” to store the names of variables for each register. (given below following code)
Thus I need to use these varaiable names in string to update variables.

//////////
class IC{ 
  //Registers of IC
  int[] register = new int[2]; // used to store register values corresponding to IC
    

  //Variables of IC
  //Register 0
  ICVariable cp_low = new ICVariable("cp_low", 0, 7, 5,0,0);
  ICVariable tsd = new ICVariable("tsd", 0, 4, 0,0,0);
  //Register 1
  ICVariable userid = new ICVariable("userid", 1, 7, 0,0,0);


  //Functions for general use
  int getReg(int index){ //returns registerData
    return register[index];
  }
  
  void setReg(int index, int data){ //set the registerData and update corresponding variables
    //Setting register data
    register[index] = data;
    //Updating variable data
          // Pending
  }
  
  int getVar(ICVariable var){ //returns variableData
    return var.data;
  }
  
  void setVar(ICVariable variable, int data){ //set the variableData and update corresponding register
    if(data < (int)Math.pow(2,(variable.MSB - variable.LSB + 1))){  // checking if input data is less than max variable size
      // Setting variable data
      variable.data = data;
      // Updating register data
      int temp = register[variable.REGISTER];
      temp = temp & (~mask(variable.MSB, variable.LSB));  //clearing the space of variable in register
      temp = temp | (data << variable.LSB); //setting the varaible data in register.
      register[variable.REGISTER] = temp;
    } else {
      println("setVar(" + variable.NAME + ", " + data + ") ERROR: input data larger than variable size");
    }
  }
}

////////
class ICVariable { 
  //Variables of IC
    //Fixed parameters
    final String NAME;   //Name of string
    final int REGISTER;  //Register of this variable
    final int MSB;       //MSB of this variable in above register
    final int LSB;       //LSB of this variable in above register
    final int REMAINING; //if a variable is divided in two bytes, then how many REMAINING bits it has in it's lower section
    //Variable parameter
    int data;           //data of this variable
  
  ICVariable(String NAME, int REGISTER, int MSB, int LSB, int REMAINING, int value){ //intializes all variable parameters with provided data
    this.NAME = NAME;
    this.REGISTER = REGISTER;
    this.MSB = MSB;
    this.LSB = LSB;
    this.REMAINING = REMAINING;
    this.data = value;
  }
}

int mask(int msb, int lsb){ //returns the mask value with 1 from msb to lsb
  int mask=0;
  for(int i=lsb; i<=msb; i++){
    mask = mask + (int)Math.pow(2,i);
  }
  return mask;
}
  //Array containing variables of each register
  String[][] regContent = {
    { "cp_low", "tsd" },  //Register  0
    { "userid" },   //Register 1
    { "nostop", "stopduty" },  //Register  2
  };```

If all the variables you need are of int type you can use an IntDict container to store them:

If they’re of mixed types you may try out a JSONObject like this post below:

1 Like

Hi @Ghostsss,

You can do sth. like this, so you can access the corresponding variables for a register by the number of the register.

Cheers
— mnse

//////////
class IC{ 
  //Registers of IC
  int[] register = new int[2]; // used to store register values corresponding to IC
  final HashMap<Integer, ICVariable[]> registeredVariables = new HashMap<Integer,ICVariable[]>();    

  //Variables of IC
  //Register 0
  //ICVariable cp_low = new ICVariable("cp_low", 0, 7, 5,0,0);
  //ICVariable tsd = new ICVariable("tsd", 0, 4, 0,0,0);
  ////Register 1
  //ICVariable userid = new ICVariable("userid", 1, 7, 0,0,0);
  ////Register 2
  //ICVariable nostop = new ICVariable("nostop", 1, 7, 0,0,0);
  //ICVariable stopduty = new ICVariable("stopduty", 1, 7, 0,0,0);

  public IC() {
    registeredVariables.put(0,new ICVariable[] {new ICVariable("cp_low", 0, 7, 5,0,0), new ICVariable("tsd", 0, 4, 0,0,0)});          
    registeredVariables.put(1,new ICVariable[] {new ICVariable("userid", 1, 7, 0,0,0)});          
    registeredVariables.put(2,new ICVariable[] {new ICVariable("nostop", 1, 7, 0,0,0),new ICVariable("stopduty", 1, 7, 0,0,0)});       
    /* how to access ...
      ICVariable[] forRegister0 = registeredVariables.get(0);
      for (ICVariable v:forRegister0) {
        v.data = 12345;//or whatever
      }      
      ICVariable[] forRegister1 = registeredVariables.get(1);
      ... see above
      ICVariable[] forRegister2 = registeredVariables.get(2);
      ... see above
    */        
  }
// ...
1 Like

Thank you very much.

However I have a question.
It might create problem in setVar() function (shown below), as in that function I am setting variable data directly and then setting the corresponding register.

What do you think?

void setVar(ICVariable variable, int data){ //set the variableData and update corresponding register
      // Setting variable data
      variable.data = data;
      // Updating register data
      int temp = register[variable.REGISTER];
      temp = temp & (~mask(variable.MSB, variable.LSB));  //clearing the space of variable in register
      temp = temp | (data << variable.LSB); //setting the varaible data in register.
      register[variable.REGISTER] = temp;
  }

Hi @Ghostsss,

I don’t see the entiry logic of your program, so not really clear what is linked to what…
But if I understand it correct than you want to do sth. like…

  void setReg(int index, int data){ //set the registerData and update corresponding variables
    //Setting register data
    register[index] = data;
    //Updating variable data
    ICVariable[] variables= registeredVariables.get(index);
    for (ICVariable v:variables) {
       setVar(v,data);
    }  
  }
  void setVar(ICVariable variable, int data){ //set the variableData and update corresponding register
        // Setting variable data
        variable.data = data;
        // Updating register data
        int temp = register[variable.REGISTER];
        temp = temp & (~mask(variable.MSB, variable.LSB));  //clearing the space of variable in register
        temp = temp | (data << variable.LSB); //setting the varaible data in register.
        // why you are setting here the register different to setReg ?
        //  which is register[index] = data;
        // so either the method in setReg is correct or the method here, hence one of both can be removed
        register[variable.REGISTER] = temp;
    }
// or change to access var by index and handle both update var and register and remove setReg
  void setVar(int index, int data){ //set the variableData and update corresponding register
    ICVariable[] variables= registeredVariables.get(index);
    for (ICVariable variable:variables) {
        // Setting variable data
        variable.data = data;
        // Updating register data
        int temp = register[variable.REGISTER];
        temp = temp & (~mask(variable.MSB, variable.LSB));  //clearing the space of variable in register
        temp = temp | (data << variable.LSB); //setting the varaible data in register.
        register[variable.REGISTER] = temp;
    }  
  }

Cheers
— mnse

1 Like

Hello mnse,

Thank you very much.
To answer your question about why I want set register in setVar() function is because,
both register data and variable data represent same data in different format. As shown in the image below.
reg

And overall data flow is as shown below:
path

So if one gets updated then other needs to be updated too, because they represent same data.
setReg() // set the register data and corresponding variables.
setVar() // set the variable data and corresponding register.

Although after thinking a little more, there is one another option also, if we store data only in Register, and used the variable data to read/write corresponding data from register.

setReg() // set the register data
setVar() // set the corresponding variable data in register
getReg() // read register data
getVar() // reads the corresponding variable data from register

Now I feel this might be a better approach.
I will try to write code for this.

if you have any suggestions, it would be really helpful.

1 Like

Hi @Ghostsss,

Yup! give it a try!
However as the register and the variables linked to each other and should be consistently updated I would make sure, that there are maybe two functions for updateVarsFromRegister and updateRegisterFromVar which then consistently updates each other…
As from your code the relationship from register to variables are 1:N and from variable to register 1:1, the updateVarsFromRegister should handle the 1:N and the updateRegisterFromVar the 1:1. For knowing the relationShip for 1:N you could use the registeredVariables approach from above to know which variables belongs to the register…

Cheers
— mnse

1 Like

Thank you very much for all the help.

I was storing same data in both register and variable (in different formats), but i figured out that there is no need to do so.

Now I am storing data in register array only.
so setReg(index) and getReg(index) functions are straight forward.

int[] register = new int[2]; // used to store register values corresponding to IC

And for setting and getting variable, I am using the original variable info (register index, MSB, LSB) to read/write data from register array (same as above). So I don’t have to maintain two sets of data, now all data is in register array.

class IC{  
int[] register = new int[2]; // used to store register values corresponding to IC
//Variables of IC
  //Register 0
  ICVariable cp_low = new ICVariable("cp_low", 0, 7, 5); //NAME, REGISTER, MSB, LSB
  ICVariable tsd = new ICVariable("tsd", 0, 4, 0);
  //Register 1
  ICVariable userid = new ICVariable("userid", 1, 7, 0);

void setReg(int index){}  //writes register data of this index
int  getReg(int index){}  //reads register data of this index
void setVar(ICVariable var, data){} //write register data corresponding to this variable
int  getVar(ICVariable var){}       // read register data corresponding to this variable 
}

class ICVariable { 
  //Variables of IC
    //Fixed parameters
    final String NAME;   //Name of string
    final int REGISTER;  //Register of this variable
    final int MSB;       //MSB of this variable in above register
    final int LSB;       //LSB of this variable in above register
  
  ICVariable(String NAME, int REGISTER, int MSB, int LSB, int REMAINING, int value){ //intializes all variable parameters with provided data
    this.NAME = NAME;
    this.REGISTER = REGISTER;
    this.MSB = MSB;
    this.LSB = LSB;
  }
}

Thanks again for all the input.