mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-05 16:46:58 +08:00
121 lines
2.3 KiB
Go
121 lines
2.3 KiB
Go
package engine
|
|
|
|
import (
|
|
"container/ring"
|
|
"reflect"
|
|
"sync"
|
|
// "time"
|
|
)
|
|
|
|
type RingItem struct {
|
|
Value interface{}
|
|
sync.WaitGroup
|
|
}
|
|
|
|
type RingBuffer struct {
|
|
*ring.Ring
|
|
}
|
|
|
|
// TODO: 池化,泛型
|
|
|
|
func NewRingBuffer(n int) (r *RingBuffer) {
|
|
r = new(RingBuffer)
|
|
r.Init(n)
|
|
return
|
|
}
|
|
|
|
func (r *RingBuffer) Init(n int) {
|
|
r.Ring = ring.New(n)
|
|
for x := r.Ring; x.Value == nil; x = x.Next() {
|
|
x.Value = new(RingItem)
|
|
}
|
|
r.Current().Add(1)
|
|
}
|
|
|
|
func (rb RingBuffer) Clone() *RingBuffer {
|
|
return &rb
|
|
}
|
|
|
|
func (r RingBuffer) SubRing(rr *ring.Ring) *RingBuffer {
|
|
r.Ring = rr
|
|
return &r
|
|
}
|
|
|
|
func (r *RingBuffer) Write(value interface{}) {
|
|
last := r.Current()
|
|
last.Value = value
|
|
r.GetNext().Add(1)
|
|
last.Done()
|
|
}
|
|
|
|
func (r *RingBuffer) read() reflect.Value {
|
|
current := r.Current()
|
|
current.Wait()
|
|
return reflect.ValueOf(current.Value)
|
|
}
|
|
|
|
func (r *RingBuffer) nextRead() reflect.Value {
|
|
r.MoveNext()
|
|
return r.read()
|
|
}
|
|
|
|
func (r *RingBuffer) CurrentValue() interface{} {
|
|
return r.Current().Value
|
|
}
|
|
|
|
func (r *RingBuffer) NextValue() interface{} {
|
|
return r.Next().Value.(*RingItem).Value
|
|
}
|
|
|
|
func (r *RingBuffer) Current() *RingItem {
|
|
return r.Ring.Value.(*RingItem)
|
|
}
|
|
|
|
func (r *RingBuffer) MoveNext() {
|
|
r.Ring = r.Next()
|
|
}
|
|
|
|
func (r *RingBuffer) NextRead() interface{} {
|
|
r.MoveNext()
|
|
return r.Read()
|
|
}
|
|
|
|
func (r *RingBuffer) GetNext() *RingItem {
|
|
r.MoveNext()
|
|
return r.Current()
|
|
}
|
|
|
|
func (r *RingBuffer) Read() interface{} {
|
|
current := r.Current()
|
|
current.Wait()
|
|
return current.Value
|
|
}
|
|
|
|
// ReadLoop 循环读取,采用了反射机制,不适用高性能场景
|
|
// handler入参可以传入回调函数或者channel
|
|
func (r *RingBuffer) ReadLoop(handler interface{}) {
|
|
switch t := reflect.ValueOf(handler); t.Kind() {
|
|
case reflect.Chan:
|
|
for v := r.read(); ; v = r.nextRead() {
|
|
t.Send(v)
|
|
}
|
|
case reflect.Func:
|
|
for args := []reflect.Value{r.read()}; ; args[0] = r.nextRead() {
|
|
t.Call(args)
|
|
}
|
|
}
|
|
}
|
|
// goon判断函数用来判断是否继续读取,返回false将终止循环
|
|
func (r *RingBuffer) ReadLoopConditional(handler interface{}, goon func() bool) {
|
|
switch t := reflect.ValueOf(handler); t.Kind() {
|
|
case reflect.Chan:
|
|
for v := r.read(); goon(); v = r.nextRead() {
|
|
t.Send(v)
|
|
}
|
|
case reflect.Func:
|
|
for args := []reflect.Value{r.read()}; goon(); args[0] = r.nextRead() {
|
|
t.Call(args)
|
|
}
|
|
}
|
|
}
|