How to use a variable name that's stored inside the variable? Reflection?

I’m trying to control a sketch through OSC from another application (SuperCollider). I want to be able to pass control data (integers) to various variables in the sketch by naming them in the OSC message.

For example I want to send an OSC message /var/backgroundHue/123 upon which the sketch would directly assign integer 123 to a variable backgroundHue.

I want to avoid specifying each variable like this:

if(theOscMessage.checkAddrPattern("/var")==true) {
    if(oscVal1.equals( "backgroundHue")) { 
        backgroundHue = oscVal2; 
    }
}

Is this possible? I found something about reflection as a way to get information about a variable, but not sure how to use that.

1 Like

can not help with this, but a other way to deal with incoming ?lists?
would be JSON

JSONArray OSCvalues;
JSONObject setting;

//test data
String OSCval1="backgroundHue";
int OSCval2=123;


void setup() {
  OSCvalues = new JSONArray();
  setting = new JSONObject();
  incoming();
}

void incoming() {
  //  setting.setInt("id",1);
  setting.setString("parameter", OSCval1);
  setting.setInt("value", OSCval2);

  OSCvalues.setJSONObject(0, setting);

  saveJSONArray(OSCvalues, "data/OSC.json");

  println(OSCvalues);
}


putting aside that there’s no added value in storing incoming data - they are better off being sent immediately to the function that is animating stuff in realtime - but even if stored, how do you interpret the “parameter” string from JSON file, as variable name so that you could assign a value vrom OSCval2 to it? like

${parameter} = value;

(${} syntax is invented here as a pseudo code)

can a string be interpreted as variable name?

Reflection is not an easy topic to implement. An easier solution might be to use a hashmap to create a dictionary of ‘pseudo variables’. The following sketch shows how this might be done with mixed data types. Simply click the mouse to change the pseudo-variable values.

HashMap<String, Object> variables = new HashMap<String, Object>();

void setup() {
  size(400, 400);
  changeVariables();
}

void draw() {
  background(32);
  float x0 = (float) variables.get("x0");
  float y0 = (float) variables.get("y0");
  float x1 = (float) variables.get("x1");
  float y1 = (float) variables.get("y1");
  float strokeWeight = (float) variables.get("weight");
  int colour = (int) variables.get("colour");
  String label0 = (String) variables.get("label0");
  String label1 = (String) variables.get("label1");
  strokeWeight(strokeWeight);
  stroke(colour);
  line(x0, y0, x1, y1);
  fill(255);
  text(label0, x0+6, y0-10);
  text(label1, x1+6, y1-10);
}

void mouseClicked() {
  changeVariables();
}

void changeVariables() {
  float x0 = random(width);
  float y0 = random(height);
  float x1 = random(width);
  float y1 = random(height);
  String label0 = "[" + round(x0) + "," + round(y0) + "]";
  String label1 = "[" + round(x1) + "," + round(y1) + "]";

  variables.put("x0", x0);
  variables.put("y0", y0);
  variables.put("x1", x1);
  variables.put("y1", y1);
  variables.put("weight", 1 + random(4));
  variables.put("colour", randomColor());
  variables.put("label0", label0);
  variables.put("label1", label1);
}

int randomColor() {
  int r = 100 + int(random(156));
  int g = 100 + int(random(156));
  int b = 100 + int(random(156));
  return color(r, g, b);
}
1 Like

@quark thank you for your answer!

It doesn’t really solve my idea to optimise the flow. I will probably use if sentences like before just to change from numbers to variable names. So instead of

  // /ctlin - Renoise-midi > SuperCollider-OSC
  if(theOscMessage.checkAddrPattern("/ctlin")==true) {
    // screenClean
    if(oscVal1.equals( "10" )) {  screenCleanHue = oscVal2 ; }
    if(oscVal1.equals( "11" )) {  screenCleanSaturation = oscVal2 ; }
    if(oscVal1.equals( "12" )) {  screenCleanBrightness = oscVal2 ; }
    if(oscVal1.equals( "13" )) {  screenCleanAlpha = oscVal2 ; }
    if(oscVal1.equals( "14" )) {  screenCleanFlickrAmount = oscVal2 ; }
    if(oscVal1.equals( "15" )) {  screenCleanFlickrSpeed = oscVal2 ; }
....

I will write:

    // screenClean
    if(oscVal1.equals( "screenCleanHue" )) {  screenCleanHue = oscVal2 ; }
    if(oscVal1.equals( "screenCleanSaturation" )) {  screenCleanSaturation = oscVal2 ; }
    if(oscVal1.equals( "screenCleanBrightness" )) {  screenCleanBrightness = oscVal2 ; }
    if(oscVal1.equals( "screenCleanAlpha" )) { screenCleanAlpha  = oscVal2 ; }
    if(oscVal1.equals( "screenCleanFlickrAmount" )) {  screenCleanFlickrAmount = oscVal2 ; }
    if(oscVal1.equals( "screenCleanFlickrSpeed" )) {  screenCleanFlickrSpeed = oscVal2 ;
....
 }

I am not convinced that your approach will be quicker than using a HashMap, especially if you have a large number of variables because the String equals method is slow whereas the HashMap does not perform string comparisons.

You can improve you approach by using else-if like this

// screenClean
    if(oscVal1.equals( "screenCleanHue" )) {  screenCleanHue = oscVal2 ; }
    else if(oscVal1.equals( "screenCleanSaturation" )) {  screenCleanSaturation = oscVal2 ; }
    else if(oscVal1.equals( "screenCleanBrightness" )) {  screenCleanBrightness = oscVal2 ; }
    else if(oscVal1.equals( "screenCleanAlpha" )) { screenCleanAlpha  = oscVal2 ; }
    else if(oscVal1.equals( "screenCleanFlickrAmount" )) {  screenCleanFlickrAmount = oscVal2 ; }
    else if(oscVal1.equals( "screenCleanFlickrSpeed" )) {  screenCleanFlickrSpeed = oscVal2 ;

if oscVal1 == “screenCleanHue” then in your code there will be 6 comparisons even though it matches the first one. Using else-if there is just 1 comparison the last 5 statements being ignored.

The problem is if oscVal1 == “screenCleanFlickrSpeed” then both codes need to perform 6 comparisons to find the match. This is where the HashMap is likely beat the multiple if and multiple else-if statements.

1 Like

Yes, in terms of speed this is another question and pretty good answer. If i’ll see things getting slow because of that I might definitely try the HashMap approach. However I’m wondering how does HashMap find the right key and how quickly? Probably there are optimised and memory efficient sorting algorithms there?

In Java the key is passed through a hashing function to create a 32 bit integer. You can see this yourself assume you have created an object of some class (doesn’t matter which one) we can see the hashcode using myobject.hashCode(). A 32bit integer has over 4 billion possible values and the best hashing algorithms provide an even distribution over this range.

OK so we have the original “key-value pair” and the “key-hashcode” these are stored in a tree structure using the “key-hashcode” as the key and the “key-value pair” as the value.

So if we provide a key then the hashmap will generate the hashcode then search the tree* and return with the key-value pair then simply returns the value part.

  • searching a binary tree is exceptionally fast - O(log2 N) performance where log2 is the logarithm to base 2

If you know the range and maximum number of keys to be stored it is possible to design and implement a hashmap that works even faster - O(1) performance

2 Likes