|
||
---|---|---|
.. | ||
README.md | ||
client.go | ||
evnets.go | ||
lockstep.go | ||
lockstep_options.go | ||
lockstep_test.go |
README.md
Lockstep
暂无介绍...
目录导航
列出了该 package
下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
展开 / 折叠目录导航
包级函数定义
函数名称 | 描述 |
---|---|
NewLockstep | 创建一个锁步(帧)同步默认实现的组件(Lockstep)进行返回 |
WithFrameLimit | 通过特定逻辑帧上限创建锁步(帧)同步组件 |
WithFrameRate | 通过特定逻辑帧率创建锁步(帧)同步组件 |
WithSerialization | 通过特定的序列化方式将每一帧的数据进行序列化 |
WithInitFrame | 通过特定的初始帧创建锁步(帧)同步组件 |
类型定义
类型 | 名称 | 描述 |
---|---|---|
INTERFACE |
Client | 帧同步客户端接口定义 |
STRUCT |
StoppedEventHandle | 暂无描述... |
STRUCT |
Lockstep | 锁步(帧)同步默认实现 |
STRUCT |
Option | 暂无描述... |
详情信息
func NewLockstep[ClientID comparable, Command any](options ...Option[ClientID, Command]) *Lockstep[ClientID, Command]
创建一个锁步(帧)同步默认实现的组件(Lockstep)进行返回
查看 / 收起单元测试
func TestNewLockstep(t *testing.T) {
ls := lockstep.NewLockstep[string, int](lockstep.WithInitFrame[string, int](1))
ls.JoinClient(&Cli{id: "player_1"})
ls.JoinClient(&Cli{id: "player_2"})
count := 0
ls.StartBroadcast()
endChan := make(chan bool)
go func() {
for {
ls.AddCommand(random.Int(1, 9999))
count++
if count >= 10 {
break
}
time.Sleep(time.Millisecond * time.Duration(random.Int(10, 200)))
}
ls.StopBroadcast()
endChan <- true
}()
<-endChan
time.Sleep(time.Second)
fmt.Println("end")
}
func WithFrameLimit[ClientID comparable, Command any](frameLimit int64) Option[ClientID, Command]
通过特定逻辑帧上限创建锁步(帧)同步组件
- 当达到上限时将停止广播
func WithFrameRate[ClientID comparable, Command any](frameRate int64) Option[ClientID, Command]
通过特定逻辑帧率创建锁步(帧)同步组件
- 默认情况下为 15/s
func WithSerialization[ClientID comparable, Command any](handle func (frame int64, commands []Command) []byte) Option[ClientID, Command]
通过特定的序列化方式将每一帧的数据进行序列化
默认情况下为将被序列化为以下结构体的JSON字符串
type Frame struct { Frame int
json:"frame"
Commands []Commandjson:"commands"
}
func WithInitFrame[ClientID comparable, Command any](initFrame int64) Option[ClientID, Command]
通过特定的初始帧创建锁步(帧)同步组件
- 默认情况下为 0,即第一帧索引为 0
Client INTERFACE
帧同步客户端接口定义
- 客户端应该具备ID及写入数据包的实现
type Client[ID comparable] interface {
GetID() ID
Write(packet []byte, callback ...func(err error))
}
StoppedEventHandle STRUCT
type StoppedEventHandle[ClientID comparable, Command any] func(lockstep *Lockstep[ClientID, Command])
Lockstep STRUCT
锁步(帧)同步默认实现
- 支持最大帧上限 WithFrameLimit
- 自定逻辑帧频率,默认为每秒15帧(帧/66ms) WithFrameRate
- 自定帧序列化方式 WithSerialization
- 从特定帧开始追帧
- 兼容各种基于TCP/UDP/Unix的网络类型,可通过客户端实现其他网络类型同步
type Lockstep[ClientID comparable, Command any] struct {
running bool
runningLock sync.RWMutex
initFrame int64
frameRate int64
frameLimit int64
serialization func(frame int64, commands []Command) []byte
clients map[ClientID]Client[ClientID]
clientFrame map[ClientID]int64
clientLock sync.RWMutex
currentFrame int64
currentCommands []Command
currentFrameLock sync.RWMutex
frameCache map[int64][]byte
frameCacheLock sync.RWMutex
ticker *time.Ticker
lockstepStoppedEventHandles []StoppedEventHandle[ClientID, Command]
}
func (*Lockstep) JoinClient(client Client[ClientID])
将客户端加入到广播队列中,通常在开始广播前使用
- 如果客户端在开始广播后加入,将丢失之前的帧数据,如要从特定帧开始追帧请使用 JoinClientWithFrame
func (*Lockstep) JoinClientWithFrame(client Client[ClientID], frameIndex int64)
加入客户端到广播队列中,并从特定帧开始追帧
- 可用于重连及状态同步、帧同步混用的情况
- 混用:服务端记录指令时同时做一次状态计算,新客户端加入时直接同步当前状态,之后从特定帧开始广播
func (*Lockstep) GetClientCount() int
获取客户端数量
func (*Lockstep) DropCache(handler func (frame int64) bool)
丢弃特定帧的缓存,当 handler 返回 true 时将丢弃缓存
func (*Lockstep) LeaveClient(clientId ClientID)
将客户端从广播队列中移除
func (*Lockstep) StartBroadcast()
开始广播
- 在开始广播后将持续按照设定的帧率进行帧数推进,并在每一帧推进时向客户端进行同步,需提前将客户端加入广播队列 JoinClient
- 广播过程中使用 AddCommand 将该帧数据追加到当前帧中
func (*Lockstep) StopBroadcast()
停止广播
func (*Lockstep) IsRunning() bool
是否正在广播
func (*Lockstep) AddCommand(command Command)
添加命令到当前帧
func (*Lockstep) AddCommands(commands []Command)
添加命令到当前帧
func (*Lockstep) GetCurrentFrame() int64
获取当前帧
func (*Lockstep) GetClientCurrentFrame(clientId ClientID) int64
获取客户端当前帧
func (*Lockstep) GetFrameLimit() int64
获取帧上限
- 未设置时将返回0
func (*Lockstep) GetCurrentCommands() []Command
获取当前帧还未结束时的所有指令
func (*Lockstep) RegLockstepStoppedEvent(handle StoppedEventHandle[ClientID, Command])
当广播停止时将触发被注册的事件处理函数
func (*Lockstep) OnLockstepStoppedEvent()
Option STRUCT
type Option[ClientID comparable, Command any] func(lockstep *Lockstep[ClientID, Command])