mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2024-11-15 13:41:23 +08:00
51 lines
910 B
Go
51 lines
910 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.RLock()
|
||
|
defer c.mutex.RUnlock()
|
||
|
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
|
||
|
}
|