add channel impl PacketQueue

This commit is contained in:
Tnze
2022-12-05 13:31:42 +08:00
parent 018d8e543a
commit b56943122e

View File

@ -4,6 +4,7 @@ import (
"container/list" "container/list"
"strconv" "strconv"
"sync" "sync"
"sync/atomic"
pk "github.com/Tnze/go-mc/net/packet" pk "github.com/Tnze/go-mc/net/packet"
) )
@ -28,21 +29,27 @@ func (s WritePacketError) Unwrap() error {
return s.Err return s.Err
} }
type PacketQueue struct { type PacketQueue interface {
queue *list.List Push(packet pk.Packet)
closed bool Pull() (packet pk.Packet, ok bool)
cond sync.Cond Close()
} }
func NewPacketQueue() (p *PacketQueue) { func NewPacketQueue() (p PacketQueue) {
p = &PacketQueue{ p = &LinkedListPacketQueue{
queue: list.New(), queue: list.New(),
cond: sync.Cond{L: new(sync.Mutex)}, cond: sync.Cond{L: new(sync.Mutex)},
} }
return p return p
} }
func (p *PacketQueue) Push(packet pk.Packet) { type LinkedListPacketQueue struct {
queue *list.List
closed bool
cond sync.Cond
}
func (p *LinkedListPacketQueue) Push(packet pk.Packet) {
p.cond.L.Lock() p.cond.L.Lock()
if !p.closed { if !p.closed {
p.queue.PushBack(packet) p.queue.PushBack(packet)
@ -51,7 +58,7 @@ func (p *PacketQueue) Push(packet pk.Packet) {
p.cond.L.Unlock() p.cond.L.Unlock()
} }
func (p *PacketQueue) Pull() (packet pk.Packet, ok bool) { func (p *LinkedListPacketQueue) Pull() (packet pk.Packet, ok bool) {
p.cond.L.Lock() p.cond.L.Lock()
defer p.cond.L.Unlock() defer p.cond.L.Unlock()
for p.queue.Front() == nil && !p.closed { for p.queue.Front() == nil && !p.closed {
@ -65,9 +72,36 @@ func (p *PacketQueue) Pull() (packet pk.Packet, ok bool) {
return return
} }
func (p *PacketQueue) Close() { func (p *LinkedListPacketQueue) Close() {
p.cond.L.Lock() p.cond.L.Lock()
p.closed = true p.closed = true
p.cond.Broadcast() p.cond.Broadcast()
p.cond.L.Unlock() p.cond.L.Unlock()
} }
type ChannelPacketQueue struct {
c chan pk.Packet
closed atomic.Bool
}
func (c ChannelPacketQueue) Push(packet pk.Packet) {
if c.closed.Load() {
return
}
select {
case c.c <- packet:
default:
c.closed.Store(true)
}
}
func (c ChannelPacketQueue) Pull() (packet pk.Packet, ok bool) {
if !c.closed.Load() {
packet, ok = <-c.c
}
return
}
func (c ChannelPacketQueue) Close() {
c.closed.Store(true)
}