How to call function by string content??

Hello I have a question, one class has a field of type String and I want to call a function that is called as the content of this string, someone can help me with the code? I looked reflection and I have recommended it but I can not see anything clear ..

I leave an example of what I want to do but using the content of the string.

//Global var block..
tt myTest;

void setup(){
    size(640, 400, P2D);
    frameRate(60);
    myTest = new tt("function1");
}

//...................................................

void draw(){
  myTest.executeExternalFunctionByName();
}

//...................................................

class tt{
  String name = "";

  // constructor..
    tt(String name_){
      name = name_;
    }

    // internal functions..
    void executeExternalFunctionByName(){
        function1();        // this is the problem!
    }
}


//...................................................


// External funcion..
void function1() {
  println("External function has executed!");
}

Answers

  • edited October 2015 Answer ✓

    http://forum.Processing.org/two/discussion/8045/how-to-format-code-and-text

    Use method("")! Called function gotta reside outside any class though.
    That is, it needs to be a sketch function. :-B

  • OMG!!!! Thank you!!! Thank you!!! Thank you!!!

  • You can pass parameters in this way?

  • edited October 2015 Answer ✓

    Unfortunately neither method("") nor thread("") allow parameters.
    We'd have to rely on "global" variables for it. :-S

  • Thank you man!!

  • edited October 2015

    Unfortunately neither method("") nor thread("") allow parameters.

    Very true, if we want parameters we have to do it ourselves.

    The following code demonstrates one way to do it. If you run the code you will see that it handles parameterless methods as well :)

    Notice that instead of int you have used the class equivalent Integer, this applies to all the primitive types

    int > Integer
    float > Float
    double > Double
    boolean > Boolean
    long > Long
    short > Short
    char > Character
    
    import java.lang.reflect.*;
    
    MethodRelay mr1, mr2, mr3, mr4;
    
    void setup() {
      size(400, 400);
      mr1 = new MethodRelay(this, "greenBox", Integer.class, Integer.class, Integer.class, Integer.class );
      mr2 = new MethodRelay(this, "showText", String.class, Integer.class, Integer.class );
      mr3 = new MethodRelay(this, "centreCircle");
    }
    
    void draw() {
      background(255);
      mr1.execute(30, 40, 100, 20);
      mr2.execute("Quark was here", 20, 20);
      mr2.execute("Until we meet again", 120, height - 50);
      mr3.execute();
    }
    
    void greenBox(Integer x, Integer y, Integer w, Integer h) {
      noStroke();
      fill(100, 220, 100);
      rect(x, y, w, h);
    }
    
    void showText(String s, Integer x, Integer y) {
      fill(0);
      text(s, x, y);
    }
    
    void centreCircle(){
      fill(0, 32);
      ellipse(width/2, height/2, width, height);
    }
    
    /**
     A class that encapsulates a named method to be invoked.
     Quark 2015
     */
    public static class MethodRelay {
    
      /** The object to handle the draw event */
      private Object handlerObject = null;
      /** The method in drawHandlerObject to execute */
      private Method handlerMethod = null;
      /** the name of the method to handle the event */
      private String handlerMethodName;
      /** An array of classes that represent the function
       parameters in order */
      private Class[] parameters = null;
    
      /**
       Register a method that has parameters.
       parameter obj the object that contains the method to invoke
       parameter name the name of the method
       parameter args a comma separated list of  
       */
      MethodRelay(Object obj, String name, Class... args) {
        try {
          handlerMethodName = name;
          parameters = args;
          handlerMethod = obj.getClass().getMethod(handlerMethodName, parameters);
          handlerObject = obj;
        } 
        catch (Exception e) {
          println("Unable to find the function -");
          print(handlerMethodName + "( ");
          if (parameters != null) {
            for (Class c : parameters)
              print(c.getSimpleName() + " ");
            println(")");
          }
        }
      }
    
      /**
       Register a method that has no parameters.
       parameter obj the object that contains the method to invoke
       parameter name the name of the method
       */
      MethodRelay(Object obj, String name) {
        this(obj, name, (Class[])null);
      }
    
      /**
       Execute a paramerterless method
       */
      void execute() {
        execute((Object[])null);
      }
    
      /**
       Execute a method with parameters
       parameter data a comma separated list of values 
       to be passed to the method
       */
      void execute(Object... data) {
        if (handlerObject != null) {
          try {
            handlerMethod.invoke(handlerObject, data);
          } 
          catch (Exception e) {
            println("Error on invoke");
          }
        }
      }
    }
    
  • edited October 2015

    Java has 8 primitive datatypes and 8 corresponding wrappers.
    You've listed 7. But forgotten byte -> Byte. ;;)

  • edited October 2015

    And although it doesn't seem like, we can have Class primitives too! @-)
    Class myPrimitiveInt = int.class;

  • edited October 2015

    @GoToLoop well down on the int.class I had completely forgotten about that.

    So I take back what I said about using the class equivalents for primitives and here is the adapted code

    import java.lang.reflect.*;
    
    MethodRelay mr1, mr2, mr3, mr4;
    
    void setup() {
      size(400, 400);
      mr1 = new MethodRelay(this, "greenBox", int.class, int.class, int.class, int.class );
      mr2 = new MethodRelay(this, "showText", String.class, int.class, int.class );
      mr3 = new MethodRelay(this, "centreCircle");
    }
    
    void draw() {
      background(255);
      mr1.execute(30, 40, 100, 20);
      mr2.execute("Quark was here", 20, 20);
      mr2.execute("Until we meet again", 120, height - 50);
      mr3.execute();
    }
    
    void greenBox(int x, int y, int w, int h) {
      noStroke();
      fill(100, 220, 100);
      rect(x, y, w, h);
    }
    
    void showText(String s, int x, int y) {
      fill(0);
      text(s, x, y);
    }
    
    void centreCircle() {
      fill(0, 32);
      ellipse(width/2, height/2, width, height);
    }
    
    /**
     A class that encapsulates a named method to be invoked.
     Quark 2015
     */
    public static class MethodRelay {
    
      /** The object to handle the draw event */
      private Object handlerObject = null;
      /** The method in drawHandlerObject to execute */
      private Method handlerMethod = null;
      /** the name of the method to handle the event */
      private String handlerMethodName;
      /** An array of classes that represent the function
       parameters in order */
      private Class[] parameters = null;
    
      /**
       Register a method that has parameters.
       parameter obj the object that contains the method to invoke
       parameter name the name of the method
       parameter args a comma separated list of  
       */
      MethodRelay(Object obj, String name, Class... args) {
        try {
          handlerMethodName = name;
          parameters = args;
          handlerMethod = obj.getClass().getMethod(handlerMethodName, parameters);
          handlerObject = obj;
        } 
        catch (Exception e) {
          println("Unable to find the function -");
          print(handlerMethodName + "( ");
          if (parameters != null) {
            for (Class c : parameters)
              print(c.getSimpleName() + " ");
            println(")");
          }
        }
      }
    
      /**
       Register a method that has no parameters.
       parameter obj the object that contains the method to invoke
       parameter name the name of the method
       */
      MethodRelay(Object obj, String name) {
        this(obj, name, (Class[])null);
      }
    
      /**
       Execute a paramerterless method
       */
      void execute() {
        execute((Object[])null);
      }
    
      /**
       Execute a method with parameters
       parameter data a comma separated list of values 
       to be passed to the method
       */
      void execute(Object... data) {
        if (handlerObject != null) {
          try {
            handlerMethod.invoke(handlerObject, data);
          } 
          catch (Exception e) {
            println("Error on invoke");
          }
        }
      }
    }
    
  • edited October 2015

    Congratz! Nice utility class! :-bd
    Just 1 detail more: "parameterless" execute() method isn't necessary at all! >-)
    And of course, it's futile to use private on those field members. >:)

  • Well done again - true on both counts. It was cobbled together from a top-level class I use in G4P hence the private access specifiers.

  • thank you both, this information is very good!

Sign In or Register to comment.