summaryrefslogtreecommitdiff
path: root/dicore3/core/src/main/java/io/dico/dicore/event/HandlerList.java
blob: fa290c077813865dd146d2d221306755c89137c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package io.dico.dicore.event;

import org.bukkit.event.Cancellable;
import org.bukkit.event.EventPriority;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

public final class HandlerList<T> {
    private final List<Listener<T>> source = new ArrayList<>();
    private Listener<T>[] listeners = newArray(0);

    public void refresh() {
        source.sort(Comparator.comparingInt(l -> l.getPriority().ordinal()));
        listeners = source.toArray(newArray(source.size()));
    }

    @SuppressWarnings("unchecked")
    private static <T> Listener<T>[] newArray(int length) {
        return new Listener[length];
    }

    public void register(Listener<T> listener) {
        if (!source.contains(listener) && source.add(listener)) {
            refresh();
        }
    }
    
    public ListenerHandle getListenerHandle(Listener<T> listener) {
        return new ListenerHandle() {
            @Override
            public void register() {
                HandlerList.this.register(listener);
            }
    
            @Override
            public void unregister() {
                HandlerList.this.unregister(listener);
            }
        };
    }

    public void register(EventPriority priority, Consumer<T> listener) {
        register(new Listener<T>() {
            @Override
            public EventPriority getPriority() {
                return priority;
            }

            @Override
            public void accept(T event) {
                listener.accept(event);
            }
        });
    }

    public List<Listener<T>> getRegistrations() {
        return Collections.unmodifiableList(source);
    }

    public void unregister(Listener<T> listener) {
        if (source.remove(listener)) {
            refresh();
        }
    }

    public void callEvent(T event) {
        if (event instanceof Cancellable) {
            Cancellable c = (Cancellable) event;
            boolean cancelled = c.isCancelled();
            for (Listener<T> listener : listeners) {
                if (listener.listensToCancelledState(cancelled)) {
                    //EnchantsPlugin.getInstance().debug("Listener acceptance: " + listener.getClass().getSimpleName());
                    listener.accept(event);
                    cancelled = c.isCancelled();
                } /*else {
                    EnchantsPlugin.getInstance().debug("Listener does not listen to cancelled state of " + cancelled + ": " + listener.getClass().getSimpleName());
                }*/
            }
        } else {
            for (Listener<T> listener : listeners) {
                //EnchantsPlugin.getInstance().debug("Listener acceptance: " + listener.getClass().getSimpleName());
                listener.accept(event);
            }
        }
    }

}