mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2024-11-14 05:11:17 +08:00
51 lines
908 B
Go
51 lines
908 B
Go
package utils
|
|
|
|
import (
|
|
"io"
|
|
"sync"
|
|
|
|
list "github.com/bahlo/generic-list-go"
|
|
)
|
|
|
|
type Callback[T any] struct {
|
|
list list.List[func(T)]
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
func NewCallback[T any]() *Callback[T] {
|
|
return &Callback[T]{}
|
|
}
|
|
|
|
func (c *Callback[T]) Register(item func(T)) io.Closer {
|
|
c.mutex.Lock()
|
|
defer c.mutex.Unlock()
|
|
element := c.list.PushBack(item)
|
|
return &callbackCloser[T]{
|
|
element: element,
|
|
callback: c,
|
|
}
|
|
}
|
|
|
|
func (c *Callback[T]) Emit(item T) {
|
|
c.mutex.RLock()
|
|
defer c.mutex.RUnlock()
|
|
for element := c.list.Front(); element != nil; element = element.Next() {
|
|
go element.Value(item)
|
|
}
|
|
}
|
|
|
|
type callbackCloser[T any] struct {
|
|
element *list.Element[func(T)]
|
|
callback *Callback[T]
|
|
once sync.Once
|
|
}
|
|
|
|
func (c *callbackCloser[T]) Close() error {
|
|
c.once.Do(func() {
|
|
c.callback.mutex.Lock()
|
|
defer c.callback.mutex.Unlock()
|
|
c.callback.list.Remove(c.element)
|
|
})
|
|
return nil
|
|
}
|