Search code examples
javaminecraftbukkit

Return value from BukkitRunnable


I add values to a map async using a BukkitRunnable and then I want to return the map.

    public Map<String, Object> test() {
    final Map<String, Object> testMap = new HashMap<>();

    new BukkitRunnable() {
        @Override
        public void run() {
            testMap.put("A", 1);
            testMap.put("B", 2);
        }
    }.runTaskAsynchronously(bridge);

    return testMap;
}

If I want to use this map it will always be empty. It is returned before the values are added to the map since I'm adding them in another thread.

I really want to use a BukkitRunnable and not a Future. How can I accomplish that? I'd need to return the map with a delay or, better, return the map, somehow, from the BukkitRunnable.


Solution

  • The problem is that the Map will be returned directly but the task will run async so you will get an empty Map returned. So you should add a Consumer to the method to get the async result.

    Try this:

    public void test(Consumer<Map<String, Object>> callback) {
        final Map<String, Object> yourMap = new HashMap<>();
        new BukkitRunnable() {
            @Override
            public void run() {
                yourMap.put("A", something);
                yourMap.put("B", 1.5);
                callback.accept(yourMap); //here the consumer gets the map
            }
        }.runTaskAsynchronously(bridge);
    }
    

    Usage lambda:

    ...
    referenceToClass.test(map -> { //Lambda
        Object someObject = map.get("A"); 
    });
    

    Usage normal:

    ...
    referenceToClass.test(new Consumer<Map<String, Object>() {
        @Override
        public void accept(Map<String, Object> map) {
            Object someObject = map.get("A"); 
        }
    });