Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
diamondburned
GitHub Repository: diamondburned/gtkcord4
Path: blob/main/internal/signaling/signaler.go
366 views
1
package signaling
2
3
type callback func()
4
5
// Signaler manages signaling events to callbacks.
6
// A zero-value Signaler is ready to use.
7
type Signaler struct {
8
callbacks map[*callback]struct{}
9
}
10
11
// Connect connects a callback to the signaler. The returned function
12
// disconnects the callback.
13
func (s *Signaler) Connect(f func()) func() {
14
if s.callbacks == nil {
15
s.callbacks = make(map[*callback]struct{})
16
}
17
18
cb := (*callback)(&f)
19
s.callbacks[cb] = struct{}{}
20
21
return func() {
22
delete(s.callbacks, cb)
23
}
24
}
25
26
// Signal signals all callbacks.
27
func (s *Signaler) Signal() {
28
for cb := range s.callbacks {
29
(*cb)()
30
}
31
}
32
33
// Disconnect disconnects all callbacks.
34
func (s *Signaler) Disconnect() {
35
for cb := range s.callbacks {
36
delete(s.callbacks, cb)
37
}
38
}
39
40
// DisconnectStack is a stack of disconnect functions.
41
// Use it to defer disconnecting callbacks.
42
type DisconnectStack struct {
43
funcs []func()
44
}
45
46
// Push pushes a disconnect function to the stack.
47
func (d *DisconnectStack) Push(funcs ...func()) {
48
d.funcs = append(d.funcs, funcs...)
49
}
50
51
// Connect connects a callback to the stack.
52
func (d *DisconnectStack) Connect(s *Signaler, f func()) {
53
d.Push(s.Connect(f))
54
}
55
56
// Pop pops a disconnect function from the stack.
57
func (d *DisconnectStack) Pop() {
58
if len(d.funcs) == 0 {
59
return
60
}
61
62
f := d.funcs[len(d.funcs)-1]
63
d.funcs[len(d.funcs)-1] = nil
64
d.funcs = d.funcs[:len(d.funcs)-1]
65
f()
66
}
67
68
// Disconnect disconnects all callbacks.
69
func (d *DisconnectStack) Disconnect() {
70
for _, f := range d.funcs {
71
f()
72
}
73
d.funcs = nil
74
}
75
76