mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-06 00:56:58 +08:00

2、删除了ring_av,AVRing的读写逻辑分离,增加了AVRingReader结构体 3、AVFrame去除泛型,音视频数据由数组改为链表 4、去除PlayContext结构体,由AVRingReader代替 5、增加通用的内存池和可回收元素的泛型链表实现
171 lines
3.3 KiB
Go
171 lines
3.3 KiB
Go
package util
|
|
|
|
// 带回收功能的泛型双向链表
|
|
|
|
type IList[T any] interface {
|
|
Push(*ListItem[T])
|
|
Shift() *ListItem[T]
|
|
Clear()
|
|
}
|
|
|
|
type ListItem[T any] struct {
|
|
Value T
|
|
Next, Pre *ListItem[T]
|
|
Pool *List[T] // 回收池
|
|
list *List[T]
|
|
}
|
|
|
|
func (item *ListItem[T]) InsertBefore(insert *ListItem[T]) {
|
|
if insert.list != nil {
|
|
panic("item already in list")
|
|
}
|
|
item.Pre.InsertAfter(insert)
|
|
}
|
|
func (item *ListItem[T]) InsertBeforeValue(value T) (result *ListItem[T]) {
|
|
result = &ListItem[T]{Value: value}
|
|
item.InsertBefore(result)
|
|
return
|
|
}
|
|
func (item *ListItem[T]) InsertAfter(insert *ListItem[T]) {
|
|
if insert.list != nil {
|
|
panic("item already in list")
|
|
}
|
|
insert.list = item.list
|
|
insert.Next = item.Next
|
|
insert.Pre = item
|
|
item.Next.Pre = insert
|
|
item.Next = insert
|
|
item.list.Length++
|
|
}
|
|
|
|
func (item *ListItem[T]) InsertAfterValue(value T) (result *ListItem[T]) {
|
|
result = &ListItem[T]{Value: value}
|
|
item.InsertAfter(result)
|
|
return
|
|
}
|
|
|
|
func (item *ListItem[T]) IsRoot() bool {
|
|
return &item.list.ListItem == item
|
|
}
|
|
|
|
func (item *ListItem[T]) Recycle() {
|
|
if item.list != item.Pool && item.Pool != nil {
|
|
item.Pool.Push(item)
|
|
}
|
|
}
|
|
|
|
func (item *ListItem[T]) Range(do func(value T) bool) {
|
|
item.RangeItem(func(item *ListItem[T]) bool {
|
|
return do(item.Value)
|
|
})
|
|
}
|
|
|
|
func (item *ListItem[T]) RangeItem(do func(*ListItem[T]) bool) {
|
|
for ; item != nil && item.list != nil && !item.IsRoot() && do(item); item = item.Next {
|
|
}
|
|
}
|
|
|
|
type List[T any] struct {
|
|
ListItem[T]
|
|
Length int
|
|
}
|
|
|
|
func (p *List[T]) PushValue(value T) {
|
|
p.Push(&ListItem[T]{Value: value})
|
|
}
|
|
|
|
func (p *List[T]) Push(item *ListItem[T]) {
|
|
if item.list != nil {
|
|
panic("item already in list")
|
|
}
|
|
if p.Length == 0 {
|
|
p.Next = &p.ListItem
|
|
p.Pre = &p.ListItem
|
|
p.ListItem.list = p
|
|
}
|
|
p.Pre.InsertAfter(item)
|
|
}
|
|
|
|
func (p *List[T]) UnshiftValue(value T) {
|
|
p.Unshift(&ListItem[T]{Value: value})
|
|
}
|
|
|
|
func (p *List[T]) Unshift(item *ListItem[T]) {
|
|
if item.list != nil {
|
|
panic("item already in list")
|
|
}
|
|
if p.Length == 0 {
|
|
p.Next = &p.ListItem
|
|
p.Pre = &p.ListItem
|
|
p.ListItem.list = p
|
|
}
|
|
p.Next.InsertBefore(item)
|
|
}
|
|
|
|
func (p *List[T]) ShiftValue() T {
|
|
return p.Shift().Value
|
|
}
|
|
|
|
func (p *List[T]) PoolShift() (head *ListItem[T]) {
|
|
if head = p.Shift(); head == nil {
|
|
head = &ListItem[T]{Pool: p}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (p *List[T]) Shift() (head *ListItem[T]) {
|
|
if p.Length == 0 {
|
|
return
|
|
}
|
|
head = p.Next
|
|
p.Next = head.Next
|
|
head.Pre = nil
|
|
head.Next = nil
|
|
head.list = nil
|
|
p.Length--
|
|
return
|
|
}
|
|
|
|
func (p *List[T]) Clear() {
|
|
p.Next = &p.ListItem
|
|
p.Pre = &p.ListItem
|
|
p.Length = 0
|
|
}
|
|
|
|
func (p *List[T]) Range(do func(value T) bool) {
|
|
if p.Length > 0 {
|
|
p.Next.Range(do)
|
|
}
|
|
}
|
|
|
|
func (p *List[T]) RangeItem(do func(*ListItem[T]) bool) {
|
|
if p.Length > 0 {
|
|
p.Next.RangeItem(do)
|
|
}
|
|
}
|
|
|
|
func (p *List[T]) Recycle() {
|
|
for item := p.Shift(); item != nil; item = p.Shift() {
|
|
item.Recycle()
|
|
}
|
|
if p.Length != 0 {
|
|
panic("recycle list error")
|
|
}
|
|
// for item := p.Next; item != nil && item.list != nil && !item.IsRoot(); {
|
|
// next := item.Next
|
|
// item.Recycle()
|
|
// item = next
|
|
// }
|
|
// p.Clear()
|
|
}
|
|
|
|
// Transfer 把链表中的所有元素转移到另一个链表中
|
|
func (p *List[T]) Transfer(target IList[T]) {
|
|
for item := p.Shift(); item != nil; item = p.Shift() {
|
|
target.Push(item)
|
|
}
|
|
if p.Length != 0 {
|
|
panic("transfer list error")
|
|
}
|
|
}
|