Search code examples
asynchronouscallbacklibgdx

LibGdx - cross-platform development, waiting for callbacks


I am trying to implement things like Firebase in my app, that are asynchronous.

Now I can write an interface callback like this:

public interface SomeInterface {

    public interface CallBackInterface{
        void getX(X x);
    }

public void getCallBackResult(CallBackInterface callBackInterface);

Which is fine if I have a few methods where I need to wait for callback before proceeding. But if I have 20+ methods where I need callbacks, some of them interacting with each other, it becomes a complete mess and is just really ugly code.

Is there some way I can write "one-fits-all" callback logic? That can be used from the LibGdx Core.

EDIT:

To use the above I need to call this from Core:

game.getInterface().getCallBackResult(new SomeInterface.CallBackInterface() {
            @Override
            public void getX(X x) {

            }
        });

So if I need another callback method, I need to add another interface and another method. And I need to do this for each method I use. It just gets messy. So was wondering if there is any way around it.


Solution

  • Your answer isn't that specific to libGDX in the fact that a "one-fits-all" callback is what you get by moving into Java 8 with some cool features borrowed from functional programming like Lambda expressions that allow you to manipulate functions (including callbacks) in a much nicer way. I'd recommend reading up on learning how to use the Java 8 interface if possible.

    If, however, Java 8 isn't an option (e.g. for backwards compatibility) you can very easily roll up your own generic callback class and then use that within your code.

    This way you won't create a new interface for each type but, this won't be as flexible as lambda expressions because you still need to create an interface for each number of arguments.

    E.g.

    interface MyCallback { void result(); }
    
    interface MyCallback1<X> { void result(X x); }
    
    interface MyCallback2<X,Y> { void result(X x, Y y); }
    
    // And so on for 3 args, 4 args etc...
    

    They can then be used generically whenever needed:

    class SomeFireBaseClass {
        public void addUserCallback(MyCallback1<User> callback) {
            ...
        }
    
        public void addUserEventCallback(MyCallback2<User, String> callback) {
            ...
        }
    }
    
    ...
    
    someFirebaseObject.addUserCallback(new MyCallback1<User> {
        public void result(User user) {
            // Do something.... 
        };
    });
    
    someFirebaseObject.addUserEventCallback(new MyCallback2<User,String> {
        public void result(User user, String event) {
            // Do something.... 
        };
    });