lockstep

package
v0.5.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2024 License: MIT Imports: 3 Imported by: 0

README

Lockstep

Go doc

暂无介绍...

目录导航

列出了该 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 []Command json:"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])

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client[ID comparable] interface {
	// GetID 用户玩家ID
	GetID() ID
	// Write 写入数据包
	Write(packet []byte, callback ...func(err error))
}

Client 帧同步客户端接口定义

  • 客户端应该具备ID及写入数据包的实现

type Lockstep

type Lockstep[ClientID comparable, Command any] struct {
	// contains filtered or unexported fields
}

Lockstep 锁步(帧)同步默认实现

  • 支持最大帧上限 WithFrameLimit
  • 自定逻辑帧频率,默认为每秒15帧(帧/66ms) WithFrameRate
  • 自定帧序列化方式 WithSerialization
  • 从特定帧开始追帧
  • 兼容各种基于TCP/UDP/Unix的网络类型,可通过客户端实现其他网络类型同步

func NewLockstep

func NewLockstep[ClientID comparable, Command any](options ...Option[ClientID, Command]) *Lockstep[ClientID, Command]

NewLockstep 创建一个锁步(帧)同步默认实现的组件(Lockstep)进行返回

func (*Lockstep[ClientID, Command]) AddCommand

func (slf *Lockstep[ClientID, Command]) AddCommand(command Command)

AddCommand 添加命令到当前帧

func (*Lockstep[ClientID, Command]) AddCommands added in v0.2.7

func (slf *Lockstep[ClientID, Command]) AddCommands(commands []Command)

AddCommands 添加命令到当前帧

func (*Lockstep[ClientID, Command]) DropCache added in v0.2.7

func (slf *Lockstep[ClientID, Command]) DropCache(handler func(frame int64) bool)

DropCache 丢弃特定帧的缓存,当 handler 返回 true 时将丢弃缓存

func (*Lockstep[ClientID, Command]) GetClientCount added in v0.2.9

func (slf *Lockstep[ClientID, Command]) GetClientCount() int

GetClientCount 获取客户端数量

func (*Lockstep[ClientID, Command]) GetClientCurrentFrame

func (slf *Lockstep[ClientID, Command]) GetClientCurrentFrame(clientId ClientID) int64

GetClientCurrentFrame 获取客户端当前帧

func (*Lockstep[ClientID, Command]) GetCurrentCommands added in v0.2.7

func (slf *Lockstep[ClientID, Command]) GetCurrentCommands() []Command

GetCurrentCommands 获取当前帧还未结束时的所有指令

func (*Lockstep[ClientID, Command]) GetCurrentFrame

func (slf *Lockstep[ClientID, Command]) GetCurrentFrame() int64

GetCurrentFrame 获取当前帧

func (*Lockstep[ClientID, Command]) GetFrameLimit

func (slf *Lockstep[ClientID, Command]) GetFrameLimit() int64

GetFrameLimit 获取帧上限

  • 未设置时将返回0

func (*Lockstep[ClientID, Command]) IsRunning added in v0.2.7

func (slf *Lockstep[ClientID, Command]) IsRunning() bool

IsRunning 是否正在广播

func (*Lockstep[ClientID, Command]) JoinClient

func (slf *Lockstep[ClientID, Command]) JoinClient(client Client[ClientID])

JoinClient 将客户端加入到广播队列中,通常在开始广播前使用

  • 如果客户端在开始广播后加入,将丢失之前的帧数据,如要从特定帧开始追帧请使用 JoinClientWithFrame

func (*Lockstep[ClientID, Command]) JoinClientWithFrame

func (slf *Lockstep[ClientID, Command]) JoinClientWithFrame(client Client[ClientID], frameIndex int64)

JoinClientWithFrame 加入客户端到广播队列中,并从特定帧开始追帧

  • 可用于重连及状态同步、帧同步混用的情况
  • 混用:服务端记录指令时同时做一次状态计算,新客户端加入时直接同步当前状态,之后从特定帧开始广播

func (*Lockstep[ClientID, Command]) LeaveClient

func (slf *Lockstep[ClientID, Command]) LeaveClient(clientId ClientID)

LeaveClient 将客户端从广播队列中移除

func (*Lockstep[ClientID, Command]) OnLockstepStoppedEvent

func (slf *Lockstep[ClientID, Command]) OnLockstepStoppedEvent()

func (*Lockstep[ClientID, Command]) RegLockstepStoppedEvent

func (slf *Lockstep[ClientID, Command]) RegLockstepStoppedEvent(handle StoppedEventHandle[ClientID, Command])

RegLockstepStoppedEvent 当广播停止时将触发被注册的事件处理函数

func (*Lockstep[ClientID, Command]) StartBroadcast

func (slf *Lockstep[ClientID, Command]) StartBroadcast()

StartBroadcast 开始广播

  • 在开始广播后将持续按照设定的帧率进行帧数推进,并在每一帧推进时向客户端进行同步,需提前将客户端加入广播队列 JoinClient
  • 广播过程中使用 AddCommand 将该帧数据追加到当前帧中

func (*Lockstep[ClientID, Command]) StopBroadcast

func (slf *Lockstep[ClientID, Command]) StopBroadcast()

StopBroadcast 停止广播

type Option

type Option[ClientID comparable, Command any] func(lockstep *Lockstep[ClientID, Command])

func WithFrameLimit

func WithFrameLimit[ClientID comparable, Command any](frameLimit int64) Option[ClientID, Command]

WithFrameLimit 通过特定逻辑帧上限创建锁步(帧)同步组件

  • 当达到上限时将停止广播

func WithFrameRate

func WithFrameRate[ClientID comparable, Command any](frameRate int64) Option[ClientID, Command]

WithFrameRate 通过特定逻辑帧率创建锁步(帧)同步组件

  • 默认情况下为 15/s

func WithInitFrame added in v0.2.7

func WithInitFrame[ClientID comparable, Command any](initFrame int64) Option[ClientID, Command]

WithInitFrame 通过特定的初始帧创建锁步(帧)同步组件

  • 默认情况下为 0,即第一帧索引为 0

func WithSerialization

func WithSerialization[ClientID comparable, Command any](handle func(frame int64, commands []Command) []byte) Option[ClientID, Command]

WithSerialization 通过特定的序列化方式将每一帧的数据进行序列化

  • 默认情况下为将被序列化为以下结构体的JSON字符串

    type Frame struct { Frame int `json:"frame"` Commands []Command `json:"commands"` }

type StoppedEventHandle added in v0.1.0

type StoppedEventHandle[ClientID comparable, Command any] func(lockstep *Lockstep[ClientID, Command])

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL