mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-05 16:46:58 +08:00
124 lines
2.4 KiB
Go
124 lines
2.4 KiB
Go
package engine
|
||
|
||
import (
|
||
"bytes"
|
||
"sync"
|
||
"sync/atomic"
|
||
"time"
|
||
)
|
||
|
||
type RingItem_Audio struct {
|
||
AudioPack
|
||
sync.WaitGroup
|
||
*bytes.Buffer
|
||
UpdateTime time.Time
|
||
}
|
||
|
||
// Ring 环形缓冲,使用数组实现
|
||
type Ring_Audio struct {
|
||
Current *RingItem_Audio
|
||
buffer []RingItem_Audio
|
||
Index byte
|
||
Flag int32 // 0:不在写入,1:正在写入,2:已销毁
|
||
}
|
||
|
||
func (r *Ring_Audio) SubRing(index byte) *Ring_Audio {
|
||
result := &Ring_Audio{
|
||
buffer: r.buffer,
|
||
}
|
||
result.GoTo(index)
|
||
return result
|
||
}
|
||
|
||
// NewRing 创建Ring
|
||
func NewRing_Audio() (r *Ring_Audio) {
|
||
r = &Ring_Audio{
|
||
buffer: make([]RingItem_Audio, 256),
|
||
}
|
||
r.GoTo(0)
|
||
r.Current.Add(1)
|
||
return
|
||
}
|
||
|
||
// GoTo 移动到指定索引处
|
||
func (r *Ring_Audio) GoTo(index byte) {
|
||
r.Index = index
|
||
r.Current = &r.buffer[index]
|
||
}
|
||
|
||
// GetAt 获取指定索引处的引用
|
||
func (r *Ring_Audio) GetAt(index byte) *RingItem_Audio {
|
||
return &r.buffer[index]
|
||
}
|
||
|
||
// GetNext 获取下一个位置的引用
|
||
func (r *Ring_Audio) GetNext() *RingItem_Audio {
|
||
return &r.buffer[r.Index+1]
|
||
}
|
||
|
||
// GetLast 获取上一个位置的引用
|
||
func (r *Ring_Audio) GetLast() *RingItem_Audio {
|
||
return &r.buffer[r.Index-1]
|
||
}
|
||
|
||
// GoNext 移动到下一个位置
|
||
func (r *Ring_Audio) GoNext() {
|
||
r.Index = r.Index + 1
|
||
r.Current = &r.buffer[r.Index]
|
||
}
|
||
|
||
// GoBack 移动到上一个位置
|
||
func (r *Ring_Audio) GoBack() {
|
||
r.Index = r.Index - 1
|
||
r.Current = &r.buffer[r.Index]
|
||
}
|
||
|
||
// NextW 写下一个
|
||
func (r *Ring_Audio) NextW() {
|
||
item := r.Current
|
||
item.UpdateTime = time.Now()
|
||
if atomic.CompareAndSwapInt32(&r.Flag, 0, 1) {
|
||
r.GoNext()
|
||
r.Current.Add(1)
|
||
item.Done()
|
||
if !atomic.CompareAndSwapInt32(&r.Flag, 1, 0) {
|
||
r.Current.Done()
|
||
}
|
||
}
|
||
}
|
||
|
||
func (r *Ring_Audio) Dispose() {
|
||
if atomic.CompareAndSwapInt32(&r.Flag, 0, 2) {
|
||
r.Current.Done()
|
||
} else if atomic.CompareAndSwapInt32(&r.Flag, 1, 2) {
|
||
} else if atomic.CompareAndSwapInt32(&r.Flag, 0, 2) {
|
||
r.Current.Done()
|
||
}
|
||
}
|
||
|
||
// NextR 读下一个
|
||
func (r *Ring_Audio) NextR() bool {
|
||
r.GoNext()
|
||
r.Current.Wait()
|
||
return r.Flag != 2 // 2代表已经销毁
|
||
}
|
||
|
||
func (r *Ring_Audio) GetBuffer() *bytes.Buffer {
|
||
if r.Current.Buffer == nil {
|
||
r.Current.Payload = []byte{}
|
||
r.Current.Buffer = bytes.NewBuffer(r.Current.Payload)
|
||
} else {
|
||
r.Current.Reset()
|
||
}
|
||
return r.Current.Buffer
|
||
}
|
||
|
||
// Timeout 发布者是否超时了
|
||
func (r *Ring_Audio) Timeout(t time.Duration) bool {
|
||
// 如果设置为0则表示永不超时
|
||
if t == 0 {
|
||
return false
|
||
}
|
||
return time.Since(r.Current.UpdateTime) > t
|
||
}
|