File size: 2,184 Bytes
3883c60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
class CallBack:
    def __init__(self, value, priority=0):
        self.priority = priority
        self.callback = value

    def call(self, *args, **kwargs):
        return self.callback(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        return self.call(*args, **kwargs)


class CallBackManager:
    def __init__(self, name):
        self.name = name
        self.callbacks: list[CallBack] = []

    def register(self, callback: CallBack):
        self.callbacks.append(callback)
        self.callbacks.sort(key=lambda c: c.priority, reverse=True)

    def unregister(self, callback: CallBack):
        if callback in self.callbacks:
            self.callbacks.remove(callback)
            return True
        return False

    def call(self, *args, **kwargs):
        return [cb(*args, **kwargs) for cb in self.callbacks]

    def __call__(self, *args, **kwargs):
        return self.call(*args, **kwargs)


callbacks: list[CallBackManager] = []


def get_manager(name) -> CallBackManager | None:
    """Get a callback manager by its registered name. (case insensitive)"""
    matches = [callback for callback in callbacks if callback.name.casefold() == name.casefold()]
    if len(matches) == 0:
        return register_new(name)
    return matches[0]


def register_by_name(name: str, callback, priority: int = 0) -> CallBack | None:
    """Get and register a callback."""
    callback = CallBack(callback, priority)
    manager = get_manager(name)
    if not manager:
        return None
    manager.register(callback)
    return callback


def unregister_by_name(name: str, callback: CallBack) -> bool:
    """Unregister a callback based on its name."""
    manager = get_manager(name)
    if not manager:
        return False
    return manager.unregister(callback)


def register_new(name: str) -> CallBackManager:
    """
    Please don't use duplicates.

    Please use "." to split your callback names instead of spaces.
    """
    callback = CallBackManager(name)
    callbacks.append(callback)
    return callback


def get_callbacks() -> list[str]:
    """Returns a list of all callback names."""
    return [callback.name for callback in callbacks]