How to pass a function/method as a parameter to another function/method (callback function)

_vk_vk
edited February 2016 in How To...

How can i make a function that gets a call back function to execute as, for example, selectFolder()

Answers

  • edited October 2013 Answer ✓

    Firstly, this is a typical How to... question and thus has been moved to the correct category...

    The method that Processing uses to call a custom function is Java Reflection, which would be quite complicated and unnecessary to implement in a Processing sketch. If you want similar functionality, there are probably shortcuts to implementing it that aren't quite as pretty. The method required would depend largely on what code you have so far...

  • Thanks @calsign that's exactly what I was looking for. It's not a concrete question, I mean no code needing it now (that's why I opened the forum guidelines and... chose badly :P ). It's just that I'm digging into javaScript now and loved this kind of functionality. The article you pointed is what I need now.

  • edited October 2013

    It may seem not, but you gotta be more specific than that! :-SS
    BtW, Java can't store method references in variables like most script programming languages do. Perhaps Java 8 will? 8-X
    Most we can do is create a class to wrap a method; instantiate that and store its reference in a variable! >-)
    Not very flexible though, since a function signature will demand its class type in order to use a fix-named method! :o3

    And as calsign hinted about Java reflexion, know that Processing got 2 undocumented methods to call a function by its name:
    * method("")
    * thread("")!

    This way, we can use a String as identifier to invoke any top-class Processing's method! :-bd
    But we can't pass nor receive parameters though! :-S

  • _vk_vk
    edited October 2013

    I see, one of the first phrases in the article:

    If it is possible to perform an operation without using reflection, then it is preferable to avoid using it

    8-X

    I didn't really understood you @GoToLoop

    It may seem not, but you gotta be more specific than that!

    Thanks for pointing the undocumented functions. (:

  • calsign was able to understand what you were asking for? I didn't! :(

  • edited October 2013

    I've got some examples about class wrapped methods: o->

    import java.io.FilenameFilter;
    
    final static String[] exts = {
      ".gif", ".png", ".jpeg", ".jpg"
    };
    
    final static FilenameFilter pictsFilter = new FilenameFilter() {
      boolean accept(File dir, String name) {
        name = name.toLowerCase();
        for (int i = exts.length; i-- != 0;)  if (name.endsWith(exts[i]))  return true;
        return false;
      }
    };
    
    final static File[] getFolderContent(File dir) {
      return dir.listFiles(pictsFilter);
    }
    
  • import java.util.Arrays;
    import java.util.Comparator;
    
    final static Comparator lastModifiedComparator = new Comparator<File>() {
      int compare(File f1, File f2) {
        //return Long.signum(lastModifiedCache.get(f2) - lastModifiedCache.get(f1));
        return 1 | (int) (lastModifiedCache.get(f2) - lastModifiedCache.get(f1) >> 63);
      }
    };
    
    Arrays.sort(files, lastModifiedComparator);
    
  • _vk_vk
    edited October 2013

    I think he did, as the answer was what I wanted. But I'll try to make it more clear.

    First, I have no need to use it in anything I'm working on now. It's more a generic question. I didn't now but I was looking for Reflection. This comes to my attention studying javaScript where you could do something like.

    javaScript code:

    var calc = function (a, b, operation){
        return operation(a, b)
    };
    
    function add(a, b){return a+b;};
    
    
    function sub(a, b){return a-b;};
    
    var sum = calc(2,2,add);
    

    @ jsfiddle

    So the question was: how to make same thing in Java, as I see being done in the selectFolder() method. From @calsign 's answer and the article he pointed I got that this is to be avoided unless unavoidable (: As I don't have a real case, that's it :P And thanks for the wrapped method examples. Your code is a bit cryptic to me sometimes... But always helps anyway. And well... my question was much beyond my skills so far

  • edited October 2013

    Your code is a bit cryptic to me sometimes...

    Yea, I know! /:)

    Even though you haven't grasped it yet; but those 2 examples above are as close as current Java can get
    to a JavaScript or Lua code w/o using "java.lang.reflect" like you did just now w/ your calc() function! [..]

    In my 1st example, File.listFiles() wants to use accept() method. But we can't pass methods as arguments in Java!
    So, the trick is having a wrapper class for method accept() and instantiate it.
    Then pass that reference as parameter to listFiles(); so the latter can invoke the former! <):)
    The same is the case at the 2nd example. It gotta pass compare() to Arrays.sort() via a Comparator object! B-)

    Of course that strategy is atrocious in terms of flexibility. Gotta be a specific class/interface wrapper w/ a specific method calling!

  • edited October 2013 Answer ✓

    My miserable attempt to mirror the JS code using Processing's method(""). :-$
    We gotta use "global" variables as call & return parameters! :((

    // forum.processing.org/two/discussion/570/
    // how-to-pass-a-functionmethod-as-a-parameter-to-another-
    // functionmethod-call-back-function
    
    static int a, b, result;
    
    void setup() {
      final int addition = calc(5, 2, "add");
      final int subtraction = calc(5, 2, "sub");
    
      println("Add: " + addition + "\tSub: " + subtraction);
      exit();
    }
    
    int calc(int operandA, int operandB, String operator) {
      a = operandA;
      b = operandB;
    
      method(operator);
    
      return result;
    }
    
    static final void add() {
      result = a + b;
    }
    
    static final void sub() {
      result = a - b;
    }
    
  • _vk_vk
    edited June 2014

    @GoToLoop got it, a late thanks : )

  • You didn't know how long I have been searching for that! Thank you a lot guys!!!

  • And I should think that when you call the function within "method", all its local variables become local variables of the "bigger" function, "melting" with the varibles with the same name, right?!

  • Given that only "sketch" top functions are eligible to be invoked via method() & thread(), and we can't pass anything to them, the only variables accessible within them are "global" 1s.

  • And I should think that when you call the function within "method", all its local variables become local variables of the "bigger" function, "melting" with the variables with the same name, right?!

    No.

Sign In or Register to comment.