帧同步支持从特定帧开始接收

This commit is contained in:
kercylan98 2023-05-19 15:53:46 +08:00
parent 3650a89294
commit 7bd9f904fc
2 changed files with 18 additions and 8 deletions

View File

@ -23,7 +23,7 @@ func NewLockstep[ClientID comparable, Command any](options ...LockstepOption[Cli
data, _ := json.Marshal(frameStruct) data, _ := json.Marshal(frameStruct)
return data return data
}, },
clientCurrentFrame: map[ClientID]int{}, clientCurrentFrame: synchronization.NewMap[ClientID, int](),
} }
for _, option := range options { for _, option := range options {
option(lockstep) option(lockstep)
@ -37,7 +37,7 @@ type Lockstep[ClientID comparable, Command any] struct {
ticker *timer.Ticker // 定时器 ticker *timer.Ticker // 定时器
frameMutex sync.Mutex // 帧锁 frameMutex sync.Mutex // 帧锁
currentFrame int // 当前帧 currentFrame int // 当前帧
clientCurrentFrame map[ClientID]int // 客户端当前帧数 clientCurrentFrame *synchronization.Map[ClientID, int] // 客户端当前帧数
frameRate int // 帧率每秒N帧 frameRate int // 帧率每秒N帧
serialization func(frame int, commands []Command) []byte // 序列化函数 serialization func(frame int, commands []Command) []byte // 序列化函数
@ -47,9 +47,17 @@ func (slf *Lockstep[ClientID, Command]) JoinClient(client component.LockstepClie
slf.clients.Set(client.GetID(), client) slf.clients.Set(client.GetID(), client)
} }
func (slf *Lockstep[ClientID, Command]) JoinClientWithFrame(client component.LockstepClient[ClientID], frameIndex int) {
slf.clients.Set(client.GetID(), client)
if frameIndex > slf.currentFrame {
frameIndex = slf.currentFrame
}
slf.clientCurrentFrame.Set(client.GetID(), frameIndex)
}
func (slf *Lockstep[ClientID, Command]) LeaveClient(clientId ClientID) { func (slf *Lockstep[ClientID, Command]) LeaveClient(clientId ClientID) {
slf.clients.Delete(clientId) slf.clients.Delete(clientId)
delete(slf.clientCurrentFrame, clientId) slf.clientCurrentFrame.Delete(clientId)
} }
func (slf *Lockstep[ClientID, Command]) StartBroadcast() { func (slf *Lockstep[ClientID, Command]) StartBroadcast() {
@ -62,11 +70,11 @@ func (slf *Lockstep[ClientID, Command]) StartBroadcast() {
frames := slf.frames.Map() frames := slf.frames.Map()
for clientId, client := range slf.clients.Map() { for clientId, client := range slf.clients.Map() {
var i = slf.clientCurrentFrame[clientId] var i = slf.clientCurrentFrame.Get(clientId)
for ; i < currentFrame; i++ { for ; i < currentFrame; i++ {
client.Send(slf.serialization(i, frames[i])) client.Send(slf.serialization(i, frames[i]))
} }
slf.clientCurrentFrame[clientId] = i slf.clientCurrentFrame.Set(clientId, i)
} }
}) })
@ -76,9 +84,7 @@ func (slf *Lockstep[ClientID, Command]) Stop() {
slf.ticker.StopTimer("lockstep") slf.ticker.StopTimer("lockstep")
slf.frameMutex.Lock() slf.frameMutex.Lock()
slf.currentFrame = 0 slf.currentFrame = 0
for key := range slf.clientCurrentFrame { slf.clientCurrentFrame.Clear()
delete(slf.clientCurrentFrame, key)
}
slf.frames.Clear() slf.frames.Clear()
slf.frameMutex.Unlock() slf.frameMutex.Unlock()
} }

View File

@ -3,10 +3,14 @@ package component
type Lockstep[ClientID comparable, Command any] interface { type Lockstep[ClientID comparable, Command any] interface {
// JoinClient 加入客户端 // JoinClient 加入客户端
JoinClient(client LockstepClient[ClientID]) JoinClient(client LockstepClient[ClientID])
// JoinClientWithFrame 加入客户端,并且指定从特定帧开始
JoinClientWithFrame(client LockstepClient[ClientID], frameIndex int)
// LeaveClient 离开客户端 // LeaveClient 离开客户端
LeaveClient(clientId ClientID) LeaveClient(clientId ClientID)
// StartBroadcast 开始广播 // StartBroadcast 开始广播
StartBroadcast() StartBroadcast()
// Stop 停止广播
Stop()
// AddCommand 增加指令 // AddCommand 增加指令
AddCommand(command Command) AddCommand(command Command)
} }