diff --git a/game/activity/README.md b/game/activity/README.md
index 1727523..3156ecc 100644
--- a/game/activity/README.md
+++ b/game/activity/README.md
@@ -201,31 +201,61 @@ type Controller[Type generic.Basic, ID generic.Basic, Data any, EntityID generic
mutex sync.RWMutex
}
```
+
+
#### func (*Controller) GetGlobalData(activityId ID) Data
> 获取特定活动全局数据
+
***
+
+
#### func (*Controller) GetEntityData(activityId ID, entityId EntityID) EntityData
> 获取特定活动实体数据
+
***
+
+
#### func (*Controller) IsOpen(activityId ID) bool
> 活动是否开启
+
***
+
+
#### func (*Controller) IsShow(activityId ID) bool
> 活动是否展示
+
***
+
+
#### func (*Controller) IsOpenOrShow(activityId ID) bool
> 活动是否开启或展示
+
***
+
+
#### func (*Controller) Refresh(activityId ID)
> 刷新活动
+
***
+
+
#### func (*Controller) InitializeNoneData(handler func (activityId ID, data *DataMeta[Data])) NoneDataActivityController[Type, ID, Data, EntityID, EntityData]
+
***
+
+
#### func (*Controller) InitializeGlobalData(handler func (activityId ID, data *DataMeta[Data])) GlobalDataActivityController[Type, ID, Data, EntityID, EntityData]
+
***
+
+
#### func (*Controller) InitializeEntityData(handler func (activityId ID, entityId EntityID, data *EntityDataMeta[EntityData])) EntityDataActivityController[Type, ID, Data, EntityID, EntityData]
+
***
+
+
#### func (*Controller) InitializeGlobalAndEntityData(handler func (activityId ID, data *DataMeta[Data]), entityHandler func (activityId ID, entityId EntityID, data *EntityDataMeta[EntityData])) GlobalAndEntityDataActivityController[Type, ID, Data, EntityID, EntityData]
+
***
### BasicActivityController `INTERFACE`
@@ -313,19 +343,34 @@ type Options struct {
Loop time.Duration
}
```
+
+
#### func (*Options) WithUpcomingTime(t time.Time) *Options
> 设置活动预告时间
+
***
+
+
#### func (*Options) WithStartTime(t time.Time) *Options
> 设置活动开始时间
+
***
+
+
#### func (*Options) WithEndTime(t time.Time) *Options
> 设置活动结束时间
+
***
+
+
#### func (*Options) WithExtendedShowTime(t time.Time) *Options
> 设置延长展示时间
+
***
+
+
#### func (*Options) WithLoop(interval time.Duration) *Options
> 设置活动循环,时间间隔小于等于 0 表示不循环
> - 当活动状态展示结束后,会根据该选项设置的时间间隔重新开始
+
***
diff --git a/game/fight/README.md b/game/fight/README.md
index fa9683d..f052730 100644
--- a/game/fight/README.md
+++ b/game/fight/README.md
@@ -65,18 +65,30 @@ type TurnBased[CampID comparable, EntityID comparable, Camp generic.IdR[CampID],
closed bool
}
```
+
+
#### func (*TurnBased) Close()
> 关闭回合制
+
***
+
+
#### func (*TurnBased) AddCamp(camp Camp, entity Entity, entities ...Entity)
> 添加阵营
+
***
+
+
#### func (*TurnBased) SetActionTimeout(actionTimeoutHandler func ( Camp, Entity) time.Duration)
> 设置行动超时时间处理函数
> - 默认情况下行动超时时间函数将始终返回 0
+
***
+
+
#### func (*TurnBased) Run()
> 运行
+
查看 / 收起单元测试
@@ -154,33 +166,60 @@ type TurnBasedController[CampID comparable, EntityID comparable, Camp generic.Id
tb *TurnBased[CampID, EntityID, Camp, Entity]
}
```
+
+
#### func (*TurnBasedController) GetRound() int
> 获取当前回合数
+
***
+
+
#### func (*TurnBasedController) GetCamp() Camp
> 获取当前操作阵营
+
***
+
+
#### func (*TurnBasedController) GetEntity() Entity
> 获取当前操作实体
+
***
+
+
#### func (*TurnBasedController) GetActionTimeoutDuration() time.Duration
> 获取当前行动超时时长
+
***
+
+
#### func (*TurnBasedController) GetActionStartTime() time.Time
> 获取当前行动开始时间
+
***
+
+
#### func (*TurnBasedController) GetActionEndTime() time.Time
> 获取当前行动结束时间
+
***
+
+
#### func (*TurnBasedController) Finish()
> 结束当前操作,将立即切换到下一个操作实体
+
***
+
+
#### func (*TurnBasedController) Stop()
> 在当前回合执行完毕后停止回合进程
+
***
+
+
#### func (*TurnBasedController) Refresh(duration time.Duration) time.Time
> 刷新当前操作实体的行动超时时间
> - 当不在行动阶段时,将返回 time.Time 零值
+
***
### TurnBasedEntitySwitchEventHandler `STRUCT`
diff --git a/game/space/README.md b/game/space/README.md
index e93b2f7..84f0f65 100644
--- a/game/space/README.md
+++ b/game/space/README.md
@@ -70,131 +70,245 @@ type RoomController[EntityID comparable, RoomID comparable, Entity generic.IdR[E
owner *EntityID
}
```
+
+
#### func (*RoomController) HasOwner() bool
> 判断是否有房主
+
***
+
+
#### func (*RoomController) IsOwner(entityId EntityID) bool
> 判断是否为房主
+
***
+
+
#### func (*RoomController) GetOwner() Entity
> 获取房主
+
***
+
+
#### func (*RoomController) GetOwnerID() EntityID
> 获取房主 ID
+
***
+
+
#### func (*RoomController) GetOwnerExist() ( Entity, bool)
> 获取房间,并返回房主是否存在的状态
+
***
+
+
#### func (*RoomController) SetOwner(entityId EntityID)
> 设置房主
+
***
+
+
#### func (*RoomController) DelOwner()
> 删除房主,将房间设置为无主的状态
+
***
+
+
#### func (*RoomController) JoinSeat(entityId EntityID, seat ...int) error
> 设置特定对象加入座位,当具体的座位不存在的时候,将会自动分配座位
> - 当目标座位存在玩家或未添加到房间中的时候,将会返回错误
+
***
+
+
#### func (*RoomController) LeaveSeat(entityId EntityID)
> 离开座位
+
***
+
+
#### func (*RoomController) GetSeat(entityId EntityID) int
> 获取座位
+
***
+
+
#### func (*RoomController) GetFirstNotEmptySeat() int
> 获取第一个非空座位号,如果没有非空座位,将返回 UnknownSeat
+
***
+
+
#### func (*RoomController) GetFirstEmptySeatEntity() (entity Entity)
> 获取第一个空座位上的实体,如果没有空座位,将返回空实体
+
***
+
+
#### func (*RoomController) GetRandomEntity() (entity Entity)
> 获取随机实体,如果房间中没有实体,将返回空实体
+
***
+
+
#### func (*RoomController) GetNotEmptySeat() []int
> 获取非空座位
+
***
+
+
#### func (*RoomController) GetEmptySeat() []int
> 获取空座位
> - 空座位需要在有对象离开座位后才可能出现
+
***
+
+
#### func (*RoomController) HasSeat(entityId EntityID) bool
> 判断是否有座位
+
***
+
+
#### func (*RoomController) GetSeatEntityCount() int
> 获取座位上的实体数量
+
***
+
+
#### func (*RoomController) GetSeatEntities() map[EntityID]Entity
> 获取座位上的实体
+
***
+
+
#### func (*RoomController) GetSeatEntitiesByOrdered() []Entity
> 有序的获取座位上的实体
+
***
+
+
#### func (*RoomController) GetSeatEntitiesByOrderedAndContainsEmpty() []Entity
> 获取有序的座位上的实体,包含空座位
+
***
+
+
#### func (*RoomController) GetSeatEntity(seat int) (entity Entity)
> 获取座位上的实体
+
***
+
+
#### func (*RoomController) ContainEntity(id EntityID) bool
> 房间内是否包含实体
+
***
+
+
#### func (*RoomController) GetRoom() Room
> 获取原始房间实例,该实例为被接管的房间的原始实例
+
***
+
+
#### func (*RoomController) GetEntities() map[EntityID]Entity
> 获取所有实体
+
***
+
+
#### func (*RoomController) HasEntity(id EntityID) bool
> 判断是否有实体
+
***
+
+
#### func (*RoomController) GetEntity(id EntityID) Entity
> 获取实体
+
***
+
+
#### func (*RoomController) GetEntityExist(id EntityID) ( Entity, bool)
> 获取实体,并返回实体是否存在的状态
+
***
+
+
#### func (*RoomController) GetEntityIDs() []EntityID
> 获取所有实体ID
+
***
+
+
#### func (*RoomController) GetEntityCount() int
> 获取实体数量
+
***
+
+
#### func (*RoomController) ChangePassword(password *string)
> 修改房间密码
> - 当房间密码为 nil 时,将会取消密码
+
***
+
+
#### func (*RoomController) AddEntity(entity Entity) error
> 添加实体,如果房间存在密码,应使用 AddEntityByPassword 函数进行添加,否则将始终返回 ErrRoomPasswordNotMatch 错误
> - 当房间已满时,将会返回 ErrRoomFull 错误
+
***
+
+
#### func (*RoomController) AddEntityByPassword(entity Entity, password string) error
> 通过房间密码添加实体到该房间中
> - 当未设置房间密码时,password 参数将会被忽略
> - 当房间密码不匹配时,将会返回 ErrRoomPasswordNotMatch 错误
> - 当房间已满时,将会返回 ErrRoomFull 错误
+
***
+
+
#### func (*RoomController) RemoveEntity(id EntityID)
> 移除实体
> - 当实体被移除时如果实体在座位上,将会自动离开座位
> - 如果实体为房主,将会根据 RoomControllerOptions.WithOwnerInherit 函数的设置进行继承
+
***
+
+
#### func (*RoomController) RemoveAllEntities()
> 移除该房间中的所有实体
> - 当实体被移除时如果实体在座位上,将会自动离开座位
> - 如果实体为房主,将会根据 RoomControllerOptions.WithOwnerInherit 函数的设置进行继承
+
***
+
+
#### func (*RoomController) Destroy()
> 销毁房间,房间会从 RoomManager 中移除,同时所有房间的实体、座位等数据都会被清空
> - 该函数与 RoomManager.DestroyRoom 相同,RoomManager.DestroyRoom 函数为该函数的快捷方式
+
***
+
+
#### func (*RoomController) GetRoomManager() *RoomManager[EntityID, RoomID, Entity, Room]
> 获取该房间控制器所属的房间管理器
+
***
+
+
#### func (*RoomController) GetRoomID() RoomID
> 获取房间 ID
+
***
+
+
#### func (*RoomController) Broadcast(handler func ( Entity), conditions ...func ( Entity) bool)
> 广播,该函数会将所有房间中满足 conditions 的对象传入 handler 中进行处理
+
***
### RoomManager `STRUCT`
@@ -207,10 +321,13 @@ type RoomManager[EntityID comparable, RoomID comparable, Entity generic.IdR[Enti
rooms map[RoomID]*RoomController[EntityID, RoomID, Entity, Room]
}
```
+
+
#### func (*RoomManager) AssumeControl(room Room, options ...*RoomControllerOptions[EntityID, RoomID, Entity, Room]) *RoomController[EntityID, RoomID, Entity, Room]
> 将房间控制权交由 RoomManager 接管,返回 RoomController 实例
> - 当任何房间需要被 RoomManager 管理时,都应该调用该方法获取到 RoomController 实例后进行操作
> - 房间被接管后需要在释放房间控制权时调用 RoomController.Destroy 方法,否则将会导致 RoomManager 一直持有房间资源
+
**示例代码:**
```go
@@ -228,31 +345,55 @@ func ExampleRoomManager_AssumeControl() {
```
***
+
+
#### func (*RoomManager) DestroyRoom(id RoomID)
> 销毁房间,该函数为 RoomController.Destroy 的快捷方式
+
***
+
+
#### func (*RoomManager) GetRoom(id RoomID) *RoomController[EntityID, RoomID, Entity, Room]
> 通过房间 ID 获取对应房间的控制器 RoomController,当房间不存在时将返回 nil
+
***
+
+
#### func (*RoomManager) GetRooms() map[RoomID]*RoomController[EntityID, RoomID, Entity, Room]
> 获取包含所有房间 ID 到对应控制器 RoomController 的映射
> - 返回值的 map 为拷贝对象,可安全的对其进行增删等操作
+
***
+
+
#### func (*RoomManager) GetRoomCount() int
> 获取房间管理器接管的房间数量
+
***
+
+
#### func (*RoomManager) GetRoomIDs() []RoomID
> 获取房间管理器接管的所有房间 ID
+
***
+
+
#### func (*RoomManager) HasEntity(entityId EntityID) bool
> 判断特定对象是否在任一房间中,当对象不在任一房间中时将返回 false
+
***
+
+
#### func (*RoomManager) GetEntityRooms(entityId EntityID) map[RoomID]*RoomController[EntityID, RoomID, Entity, Room]
> 获取特定对象所在的房间,返回值为房间 ID 到对应控制器 RoomController 的映射
> - 由于一个对象可能在多个房间中,因此返回值为 map 类型
+
***
+
+
#### func (*RoomManager) Broadcast(handler func ( Entity), conditions ...func ( Entity) bool)
> 向所有房间对象广播消息,该方法将会遍历所有房间控制器并调用 RoomController.Broadcast 方法
+
***
### RoomAssumeControlEventHandle `STRUCT`
@@ -271,14 +412,23 @@ type RoomControllerOptions[EntityID comparable, RoomID comparable, Entity generi
ownerInheritHandler func(controller *RoomController[EntityID, RoomID, Entity, Room]) *EntityID
}
```
+
+
#### func (*RoomControllerOptions) WithOwnerInherit(inherit bool, inheritHandler ...func (controller *RoomController[EntityID, RoomID, Entity, Room]) *EntityID) *RoomControllerOptions[EntityID, RoomID, Entity, Room]
> 设置房间所有者是否继承,默认为 false
> - inherit: 是否继承,当未设置 inheritHandler 且 inherit 为 true 时,将会按照随机或根据座位号顺序继承房间所有者
> - inheritHandler: 继承处理函数,当 inherit 为 true 时,该函数将会被调用,传入当前房间中的所有实体,返回值为新的房间所有者
+
***
+
+
#### func (*RoomControllerOptions) WithMaxEntityCount(maxEntityCount int) *RoomControllerOptions[EntityID, RoomID, Entity, Room]
> 设置房间最大实体数量
+
***
+
+
#### func (*RoomControllerOptions) WithPassword(password string) *RoomControllerOptions[EntityID, RoomID, Entity, Room]
> 设置房间密码
+
***
diff --git a/game/task/README.md b/game/task/README.md
index 58902de..fe0196e 100644
--- a/game/task/README.md
+++ b/game/task/README.md
@@ -156,71 +156,137 @@ func TestCond(t *testing.T) {
```go
type Condition map[any]any
```
+
+
#### func (Condition) Cond(k any, v any) Condition
> 创建任务条件
+
***
+
+
#### func (Condition) GetString(key any) string
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetInt(key any) int
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetInt8(key any) int8
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetInt16(key any) int16
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetInt32(key any) int32
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetInt64(key any) int64
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetUint(key any) uint
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetUint8(key any) uint8
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetUint16(key any) uint16
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetUint32(key any) uint32
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetUint64(key any) uint64
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetFloat32(key any) float32
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetFloat64(key any) float64
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetBool(key any) bool
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetTime(key any) time.Time
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetDuration(key any) time.Duration
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetByte(key any) byte
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetBytes(key any) []byte
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetRune(key any) rune
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetRunes(key any) []rune
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
+
+
#### func (Condition) GetAny(key any) any
> 获取特定类型的任务条件值,该值必须与预期类型一致,否则返回零值
+
***
### RefreshTaskCounterEventHandler `STRUCT`
@@ -240,7 +306,10 @@ type Option func(task *Task)
```go
type Status byte
```
+
+
#### func (Status) String() string
+
***
### Task `STRUCT`
@@ -259,33 +328,60 @@ type Task struct {
LimitedDuration time.Duration
}
```
+
+
#### func (*Task) IsComplete() bool
> 判断任务是否已完成
+
***
+
+
#### func (*Task) IsFailed() bool
> 判断任务是否已失败
+
***
+
+
#### func (*Task) IsReward() bool
> 判断任务是否已领取奖励
+
***
+
+
#### func (*Task) ReceiveReward() bool
> 领取任务奖励,当任务状态为已完成时,才能领取奖励,此时返回 true,并且任务状态变更为已领取奖励
+
***
+
+
#### func (*Task) IncrementCounter(incr int64) *Task
> 增加计数器的值,当 incr 为负数时,计数器的值不会发生变化
> - 如果需要溢出计数器,可通过 WithOverflowCounter 设置可溢出的任务计数器
+
***
+
+
#### func (*Task) DecrementCounter(decr int64) *Task
> 减少计数器的值,当 decr 为负数时,计数器的值不会发生变化
+
***
+
+
#### func (*Task) AssignConditionValueAndRefresh(key any, value any) *Task
> 分配条件值并刷新任务状态
+
***
+
+
#### func (*Task) AssignConditionValueAndRefreshByCondition(condition Condition) *Task
> 分配条件值并刷新任务状态
+
***
+
+
#### func (*Task) ResetStatus() *Task
> 重置任务状态
> - 该函数会将任务状态重置为已接受状态后,再刷新任务状态
> - 当任务条件变更,例如任务计数要求为 10,已经完成的情况下,将任务计数要求变更为 5 或 20,此时任务状态由于是已完成或已领取状态,不会自动刷新,需要调用该函数刷新任务状态
+
***
diff --git a/notify/README.md b/notify/README.md
index ea293bb..91b960f 100644
--- a/notify/README.md
+++ b/notify/README.md
@@ -47,11 +47,17 @@ type Manager struct {
closeChannel chan struct{}
}
```
+
+
#### func (*Manager) PushNotify(notify Notify)
> 推送通知
+
***
+
+
#### func (*Manager) Release()
> 释放通知管理器
+
***
### Notify `INTERFACE`
diff --git a/notify/notifies/README.md b/notify/notifies/README.md
index 17c6322..eb15f92 100644
--- a/notify/notifies/README.md
+++ b/notify/notifies/README.md
@@ -156,8 +156,11 @@ type FeiShu struct {
MsgType string
}
```
+
+
#### func (*FeiShu) Format() ( string, error)
> 格式化通知内容
+
***
### FeiShuMessage `STRUCT`
@@ -173,8 +176,11 @@ type FeiShuRichText struct {
content map[string]*FeiShuRichTextContent
}
```
+
+
#### func (*FeiShuRichText) Create(lang string, title string) *FeiShuRichTextContent
> 创建一个特定语言和标题的富文本内容
+
***
### FeiShuRichTextContent `STRUCT`
@@ -186,45 +192,75 @@ type FeiShuRichTextContent struct {
Content [][]map[string]any
}
```
+
+
#### func (*FeiShuRichTextContent) AddText(text string, styles ...string) *FeiShuRichTextContent
> 添加文本
+
***
+
+
#### func (*FeiShuRichTextContent) AddUnescapeText(text string, styles ...string) *FeiShuRichTextContent
> 添加 unescape 解码的文本
+
***
+
+
#### func (*FeiShuRichTextContent) AddLink(text string, href string, styles ...string) *FeiShuRichTextContent
> 添加超链接文本
> - 请确保链接地址的合法性,否则消息会发送失败
+
***
+
+
#### func (*FeiShuRichTextContent) AddAt(userId string, styles ...string) *FeiShuRichTextContent
> 添加@的用户
> - @单个用户时,userId 字段必须是有效值
> - @所有人填"all"。
+
***
+
+
#### func (*FeiShuRichTextContent) AddAtWithUsername(userId string, username string, styles ...string) *FeiShuRichTextContent
> 添加包含用户名的@用户
> - @单个用户时,userId 字段必须是有效值
> - @所有人填"all"。
+
***
+
+
#### func (*FeiShuRichTextContent) AddImg(imageKey string) *FeiShuRichTextContent
> 添加图片
> - imageKey 表示图片的唯一标识,可通过上传图片接口获取
+
***
+
+
#### func (*FeiShuRichTextContent) AddMedia(fileKey string) *FeiShuRichTextContent
> 添加视频
> - fileKey 表示视频文件的唯一标识,可通过上传文件接口获取
+
***
+
+
#### func (*FeiShuRichTextContent) AddMediaWithCover(fileKey string, imageKey string) *FeiShuRichTextContent
> 添加包含封面的视频
> - fileKey 表示视频文件的唯一标识,可通过上传文件接口获取
> - imageKey 表示图片的唯一标识,可通过上传图片接口获取
+
***
+
+
#### func (*FeiShuRichTextContent) AddEmotion(emojiType string) *FeiShuRichTextContent
> 添加表情
> - emojiType 表示表情类型,部分可选值请参见表情文案。
>
> 表情文案:https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce
+
***
+
+
#### func (*FeiShuRichTextContent) Ok() *FeiShuRichText
> 确认完成,将返回 FeiShuRichText 可继续创建多语言富文本
+
***
diff --git a/notify/senders/README.md b/notify/senders/README.md
index 593f597..3045153 100644
--- a/notify/senders/README.md
+++ b/notify/senders/README.md
@@ -44,8 +44,11 @@ type FeiShu struct {
webhook string
}
```
+
+
#### func (*FeiShu) Push(notify notify.Notify) error
> 推送通知
+
查看 / 收起单元测试
@@ -53,7 +56,7 @@ type FeiShu struct {
```go
func TestFeiShu_Push(t *testing.T) {
- fs := NewFeiShu("https://open.feishu.cn/open-apis/bot/v2/hook/d886f30f-814c-47b1-aeb0-b508da0f7f22")
+ fs := NewFeiShu("https://open.feishu.cn/open-apis/bot/v2/hook/bid")
rt := notifies.NewFeiShu(notifies.FeiShuMessageWithRichText(notifies.NewFeiShuRichText().Create("zh_cn", "标题咯").AddText("哈哈哈").Ok()))
if err := fs.Push(rt); err != nil {
panic(err)
diff --git a/planner/pce/README.md b/planner/pce/README.md
index 485242c..cf4d54b 100644
--- a/planner/pce/README.md
+++ b/planner/pce/README.md
@@ -135,11 +135,17 @@ type DataTmpl interface {
```go
type Exporter struct{}
```
+
+
#### func (*Exporter) ExportStruct(tmpl Tmpl, tmplStruct ...*TmplStruct) ( []byte, error)
> 导出结构
+
***
+
+
#### func (*Exporter) ExportData(tmpl DataTmpl, data map[any]any) ( []byte, error)
> 导出数据
+
***
### Field `INTERFACE`
@@ -157,11 +163,20 @@ type Field interface {
```go
type Int int
```
+
+
#### func (Int) TypeName() string
+
***
+
+
#### func (Int) Zero() any
+
***
+
+
#### func (Int) Parse(value string) any
+
***
### Int8 `STRUCT`
@@ -169,11 +184,20 @@ type Int int
```go
type Int8 int8
```
+
+
#### func (Int8) TypeName() string
+
***
+
+
#### func (Int8) Zero() any
+
***
+
+
#### func (Int8) Parse(value string) any
+
***
### Int16 `STRUCT`
@@ -181,11 +205,20 @@ type Int8 int8
```go
type Int16 int16
```
+
+
#### func (Int16) TypeName() string
+
***
+
+
#### func (Int16) Zero() any
+
***
+
+
#### func (Int16) Parse(value string) any
+
***
### Int32 `STRUCT`
@@ -193,11 +226,20 @@ type Int16 int16
```go
type Int32 int32
```
+
+
#### func (Int32) TypeName() string
+
***
+
+
#### func (Int32) Zero() any
+
***
+
+
#### func (Int32) Parse(value string) any
+
***
### Int64 `STRUCT`
@@ -205,11 +247,20 @@ type Int32 int32
```go
type Int64 int64
```
+
+
#### func (Int64) TypeName() string
+
***
+
+
#### func (Int64) Zero() any
+
***
+
+
#### func (Int64) Parse(value string) any
+
***
### Uint `STRUCT`
@@ -217,11 +268,20 @@ type Int64 int64
```go
type Uint uint
```
+
+
#### func (Uint) TypeName() string
+
***
+
+
#### func (Uint) Zero() any
+
***
+
+
#### func (Uint) Parse(value string) any
+
***
### Uint8 `STRUCT`
@@ -229,11 +289,20 @@ type Uint uint
```go
type Uint8 uint8
```
+
+
#### func (Uint8) TypeName() string
+
***
+
+
#### func (Uint8) Zero() any
+
***
+
+
#### func (Uint8) Parse(value string) any
+
***
### Uint16 `STRUCT`
@@ -241,11 +310,20 @@ type Uint8 uint8
```go
type Uint16 uint16
```
+
+
#### func (Uint16) TypeName() string
+
***
+
+
#### func (Uint16) Zero() any
+
***
+
+
#### func (Uint16) Parse(value string) any
+
***
### Uint32 `STRUCT`
@@ -253,11 +331,20 @@ type Uint16 uint16
```go
type Uint32 uint32
```
+
+
#### func (Uint32) TypeName() string
+
***
+
+
#### func (Uint32) Zero() any
+
***
+
+
#### func (Uint32) Parse(value string) any
+
***
### Uint64 `STRUCT`
@@ -265,11 +352,20 @@ type Uint32 uint32
```go
type Uint64 uint64
```
+
+
#### func (Uint64) TypeName() string
+
***
+
+
#### func (Uint64) Zero() any
+
***
+
+
#### func (Uint64) Parse(value string) any
+
***
### Float32 `STRUCT`
@@ -277,11 +373,20 @@ type Uint64 uint64
```go
type Float32 float32
```
+
+
#### func (Float32) TypeName() string
+
***
+
+
#### func (Float32) Zero() any
+
***
+
+
#### func (Float32) Parse(value string) any
+
***
### Float64 `STRUCT`
@@ -289,11 +394,20 @@ type Float32 float32
```go
type Float64 float64
```
+
+
#### func (Float64) TypeName() string
+
***
+
+
#### func (Float64) Zero() any
+
***
+
+
#### func (Float64) Parse(value string) any
+
***
### String `STRUCT`
@@ -301,11 +415,20 @@ type Float64 float64
```go
type String string
```
+
+
#### func (String) TypeName() string
+
***
+
+
#### func (String) Zero() any
+
***
+
+
#### func (String) Parse(value string) any
+
***
### Bool `STRUCT`
@@ -313,11 +436,20 @@ type String string
```go
type Bool bool
```
+
+
#### func (Bool) TypeName() string
+
***
+
+
#### func (Bool) Zero() any
+
***
+
+
#### func (Bool) Parse(value string) any
+
***
### Byte `STRUCT`
@@ -325,11 +457,20 @@ type Bool bool
```go
type Byte byte
```
+
+
#### func (Byte) TypeName() string
+
***
+
+
#### func (Byte) Zero() any
+
***
+
+
#### func (Byte) Parse(value string) any
+
***
### Rune `STRUCT`
@@ -337,11 +478,20 @@ type Byte byte
```go
type Rune rune
```
+
+
#### func (Rune) TypeName() string
+
***
+
+
#### func (Rune) Zero() any
+
***
+
+
#### func (Rune) Parse(value string) any
+
***
### Complex64 `STRUCT`
@@ -349,11 +499,20 @@ type Rune rune
```go
type Complex64 complex64
```
+
+
#### func (Complex64) TypeName() string
+
***
+
+
#### func (Complex64) Zero() any
+
***
+
+
#### func (Complex64) Parse(value string) any
+
***
### Complex128 `STRUCT`
@@ -361,11 +520,20 @@ type Complex64 complex64
```go
type Complex128 complex128
```
+
+
#### func (Complex128) TypeName() string
+
***
+
+
#### func (Complex128) Zero() any
+
***
+
+
#### func (Complex128) Parse(value string) any
+
***
### Uintptr `STRUCT`
@@ -373,11 +541,20 @@ type Complex128 complex128
```go
type Uintptr uintptr
```
+
+
#### func (Uintptr) TypeName() string
+
***
+
+
#### func (Uintptr) Zero() any
+
***
+
+
#### func (Uintptr) Parse(value string) any
+
***
### Double `STRUCT`
@@ -385,11 +562,20 @@ type Uintptr uintptr
```go
type Double float64
```
+
+
#### func (Double) TypeName() string
+
***
+
+
#### func (Double) Zero() any
+
***
+
+
#### func (Double) Parse(value string) any
+
***
### Float `STRUCT`
@@ -397,11 +583,20 @@ type Double float64
```go
type Float float32
```
+
+
#### func (Float) TypeName() string
+
***
+
+
#### func (Float) Zero() any
+
***
+
+
#### func (Float) Parse(value string) any
+
***
### Long `STRUCT`
@@ -409,11 +604,20 @@ type Float float32
```go
type Long int64
```
+
+
#### func (Long) TypeName() string
+
***
+
+
#### func (Long) Zero() any
+
***
+
+
#### func (Long) Parse(value string) any
+
***
### Short `STRUCT`
@@ -421,11 +625,20 @@ type Long int64
```go
type Short int16
```
+
+
#### func (Short) TypeName() string
+
***
+
+
#### func (Short) Zero() any
+
***
+
+
#### func (Short) Parse(value string) any
+
***
### Char `STRUCT`
@@ -433,11 +646,20 @@ type Short int16
```go
type Char int8
```
+
+
#### func (Char) TypeName() string
+
***
+
+
#### func (Char) Zero() any
+
***
+
+
#### func (Char) Parse(value string) any
+
***
### Number `STRUCT`
@@ -445,11 +667,20 @@ type Char int8
```go
type Number float64
```
+
+
#### func (Number) TypeName() string
+
***
+
+
#### func (Number) Zero() any
+
***
+
+
#### func (Number) Parse(value string) any
+
***
### Integer `STRUCT`
@@ -457,11 +688,20 @@ type Number float64
```go
type Integer int64
```
+
+
#### func (Integer) TypeName() string
+
***
+
+
#### func (Integer) Zero() any
+
***
+
+
#### func (Integer) Parse(value string) any
+
***
### Boolean `STRUCT`
@@ -469,11 +709,20 @@ type Integer int64
```go
type Boolean bool
```
+
+
#### func (Boolean) TypeName() string
+
***
+
+
#### func (Boolean) Zero() any
+
***
+
+
#### func (Boolean) Parse(value string) any
+
***
### Loader `STRUCT`
@@ -483,11 +732,17 @@ type Loader struct {
fields map[string]Field
}
```
+
+
#### func (*Loader) LoadStruct(config Config) *TmplStruct
> 加载结构
+
***
+
+
#### func (*Loader) LoadData(config Config) map[any]any
> 加载配置并得到配置数据
+
***
### DataInfo `STRUCT`
@@ -532,14 +787,23 @@ type TmplField struct {
isIndex bool
}
```
+
+
#### func (*TmplField) IsIndex() bool
> 是否是索引字段
+
***
+
+
#### func (*TmplField) IsStruct() bool
> 是否是结构类型
+
***
+
+
#### func (*TmplField) IsSlice() bool
> 是否是切片类型
+
***
### TmplStruct `STRUCT`
@@ -552,6 +816,9 @@ type TmplStruct struct {
IndexCount int
}
```
+
+
#### func (*TmplStruct) AllChildren() []*TmplStruct
> 获取所有子结构
+
***
diff --git a/planner/pce/cs/README.md b/planner/pce/cs/README.md
index 4c9d347..1af49eb 100644
--- a/planner/pce/cs/README.md
+++ b/planner/pce/cs/README.md
@@ -50,15 +50,33 @@ type Xlsx struct {
exportType XlsxExportType
}
```
+
+
#### func (*Xlsx) GetConfigName() string
+
***
+
+
#### func (*Xlsx) GetDisplayName() string
+
***
+
+
#### func (*Xlsx) GetDescription() string
+
***
+
+
#### func (*Xlsx) GetIndexCount() int
+
***
+
+
#### func (*Xlsx) GetFields() []pce.DataField
+
***
+
+
#### func (*Xlsx) GetData() [][]pce.DataInfo
+
***
diff --git a/planner/pce/tmpls/README.md b/planner/pce/tmpls/README.md
index ac56c86..cd38f58 100644
--- a/planner/pce/tmpls/README.md
+++ b/planner/pce/tmpls/README.md
@@ -50,13 +50,25 @@ type Golang struct {
Templates []*pce.TmplStruct
}
```
+
+
#### func (*Golang) Render(templates ...*pce.TmplStruct) ( string, error)
+
***
+
+
#### func (*Golang) GetVariable(config *pce.TmplStruct) string
+
***
+
+
#### func (*Golang) GetConfigName(config *pce.TmplStruct) string
+
***
+
+
#### func (*Golang) HasIndex(config *pce.TmplStruct) bool
+
***
### JSON `STRUCT`
@@ -66,5 +78,8 @@ type JSON struct {
jsonIter.API
}
```
+
+
#### func (*JSON) Render(data map[any]any) ( string, error)
+
***
diff --git a/server/README.md b/server/README.md
index fe320bc..bb0d216 100644
--- a/server/README.md
+++ b/server/README.md
@@ -70,10 +70,10 @@ server 提供了包含多种网络类型的服务器实现
|`STRUCT`|[MessageType](#struct_MessageType)|暂无描述...
|`STRUCT`|[Message](#struct_Message)|服务器消息
|`STRUCT`|[MultipleServer](#struct_MultipleServer)|暂无描述...
-|`STRUCT`|[Network](#struct_Network)|暂无描述...
+|`STRUCT`|[Network](#struct_Network)|服务器运行的网络模式
|`STRUCT`|[Option](#struct_Option)|暂无描述...
|`STRUCT`|[Server](#struct_Server)|网络服务器
-|`INTERFACE`|[Service](#struct_Service)|兼容传统 service 设计模式的接口
+|`INTERFACE`|[Service](#struct_Service)|兼容传统 service 设计模式的接口,通过该接口可以实现更简洁、更具有可读性的服务绑定
@@ -174,6 +174,84 @@ func TestNewBot(t *testing.T) {
> - 默认值为 DefaultLowMessageDuration
> - 当 duration <= 0 时,表示关闭慢消息检测
+**示例代码:**
+
+服务器在启动时将阻塞 1s,模拟了慢消息的过程,这时候如果通过 RegMessageLowExecEvent 函数注册过慢消息事件,将会收到该事件的消息
+ - 该示例中,将在收到慢消息时关闭服务器
+
+
+```go
+
+func ExampleWithLowMessageDuration() {
+ srv := server.New(server.NetworkNone, server.WithLowMessageDuration(time.Second))
+ srv.RegStartFinishEvent(func(srv *server.Server) {
+ time.Sleep(time.Second)
+ })
+ srv.RegMessageLowExecEvent(func(srv *server.Server, message *server.Message, cost time.Duration) {
+ srv.Shutdown()
+ fmt.Println(times.GetSecond(cost))
+ })
+ if err := srv.RunNone(); err != nil {
+ panic(err)
+ }
+}
+
+```
+
+
+查看 / 收起单元测试
+
+
+```go
+
+func TestWithLowMessageDuration(t *testing.T) {
+ var cases = []struct {
+ name string
+ duration time.Duration
+ }{{name: "TestWithLowMessageDuration", duration: server.DefaultLowMessageDuration}, {name: "TestWithLowMessageDuration_Zero", duration: 0}, {name: "TestWithLowMessageDuration_Negative", duration: -server.DefaultAsyncLowMessageDuration}}
+ for _, c := range cases {
+ c := c
+ t.Run(c.name, func(t *testing.T) {
+ networks := server.GetNetworks()
+ for i := 0; i < len(networks); i++ {
+ low := false
+ network := networks[i]
+ srv := server.New(network, server.WithLowMessageDuration(c.duration))
+ srv.RegMessageLowExecEvent(func(srv *server.Server, message *server.Message, cost time.Duration) {
+ low = true
+ srv.Shutdown()
+ })
+ srv.RegStartFinishEvent(func(srv *server.Server) {
+ if c.duration <= 0 {
+ srv.Shutdown()
+ return
+ }
+ time.Sleep(server.DefaultLowMessageDuration)
+ })
+ var lis string
+ switch network {
+ case server.NetworkNone, server.NetworkUnix:
+ lis = "addr"
+ default:
+ lis = fmt.Sprintf(":%d", random.UsablePort())
+ }
+ if err := srv.Run(lis); err != nil {
+ t.Fatalf("%s run error: %s", network, err)
+ }
+ if !low && c.duration > 0 {
+ t.Fatalf("%s low message not exec", network)
+ }
+ }
+ })
+ }
+}
+
+```
+
+
+
+
+
***
#### func WithAsyncLowMessageDuration(duration time.Duration) Option
@@ -181,6 +259,89 @@ func TestNewBot(t *testing.T) {
> - 默认值为 DefaultAsyncLowMessageDuration
> - 当 duration <= 0 时,表示关闭慢消息检测
+**示例代码:**
+
+服务器在启动时将发布一条阻塞 1s 的异步消息,模拟了慢消息的过程,这时候如果通过 RegMessageLowExecEvent 函数注册过慢消息事件,将会收到该事件的消息
+ - 该示例中,将在收到慢消息时关闭服务器
+
+
+```go
+
+func ExampleWithAsyncLowMessageDuration() {
+ srv := server.New(server.NetworkNone, server.WithAsyncLowMessageDuration(time.Second))
+ srv.RegStartFinishEvent(func(srv *server.Server) {
+ srv.PushAsyncMessage(func() error {
+ time.Sleep(time.Second)
+ return nil
+ }, nil)
+ })
+ srv.RegMessageLowExecEvent(func(srv *server.Server, message *server.Message, cost time.Duration) {
+ srv.Shutdown()
+ fmt.Println(times.GetSecond(cost))
+ })
+ if err := srv.RunNone(); err != nil {
+ panic(err)
+ }
+}
+
+```
+
+
+查看 / 收起单元测试
+
+
+```go
+
+func TestWithAsyncLowMessageDuration(t *testing.T) {
+ var cases = []struct {
+ name string
+ duration time.Duration
+ }{{name: "TestWithAsyncLowMessageDuration", duration: time.Millisecond * 100}, {name: "TestWithAsyncLowMessageDuration_Zero", duration: 0}, {name: "TestWithAsyncLowMessageDuration_Negative", duration: -server.DefaultAsyncLowMessageDuration}}
+ for _, c := range cases {
+ t.Run(c.name, func(t *testing.T) {
+ networks := server.GetNetworks()
+ for i := 0; i < len(networks); i++ {
+ low := false
+ network := networks[i]
+ srv := server.New(network, server.WithAsyncLowMessageDuration(c.duration))
+ srv.RegMessageLowExecEvent(func(srv *server.Server, message *server.Message, cost time.Duration) {
+ low = true
+ srv.Shutdown()
+ })
+ srv.RegStartFinishEvent(func(srv *server.Server) {
+ if c.duration <= 0 {
+ srv.Shutdown()
+ return
+ }
+ srv.PushAsyncMessage(func() error {
+ time.Sleep(c.duration)
+ return nil
+ }, nil)
+ })
+ var lis string
+ switch network {
+ case server.NetworkNone, server.NetworkUnix:
+ lis = fmt.Sprintf("%s%d", "addr", random.Int(0, 9999))
+ default:
+ lis = fmt.Sprintf(":%d", random.UsablePort())
+ }
+ if err := srv.Run(lis); err != nil {
+ t.Fatalf("%s run error: %s", network, err)
+ }
+ if !low && c.duration > 0 {
+ t.Fatalf("%s low message not exec", network)
+ }
+ }
+ })
+ }
+}
+
+```
+
+
+
+
+
***
#### func WithWebsocketConnInitializer(initializer func (writer http.ResponseWriter, request *http.Request, conn *websocket.Conn) error) Option
@@ -302,16 +463,17 @@ func TestNewBot(t *testing.T) {
**示例代码:**
+该案例将创建一个简单的 WebSocket 服务器,如果需要更多的服务器类型可参考 [` Network `](#struct_Network) 部分
+ - server.WithLimitLife(time.Millisecond) 通常不是在正常开发应该使用的,在这里只是为了让服务器在启动完成后的 1 毫秒后自动关闭
+
+该案例的输出结果为 true
+
+
```go
func ExampleNew() {
srv := server.New(server.NetworkWebsocket, server.WithLimitLife(time.Millisecond))
- srv.RegConnectionReceivePacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte) {
- conn.Write(packet)
- })
- if err := srv.Run(":9999"); err != nil {
- panic(err)
- }
+ fmt.Println(srv != nil)
}
```
@@ -320,24 +482,30 @@ func ExampleNew() {
查看 / 收起单元测试
+该单元测试用于测试以不同的基本参数创建服务器是否存在异常
+
+
```go
func TestNew(t *testing.T) {
- srv := server.New(server.NetworkWebsocket, server.WithPProf())
- srv.RegStartBeforeEvent(func(srv *server.Server) {
- fmt.Println("启动前")
- })
- srv.RegStartFinishEvent(func(srv *server.Server) {
- fmt.Println("启动完成")
- })
- srv.RegConnectionClosedEvent(func(srv *server.Server, conn *server.Conn, err any) {
- fmt.Println("关闭", conn.GetID(), err, "IncrCount", srv.GetOnlineCount())
- })
- srv.RegConnectionReceivePacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte) {
- conn.Write(packet)
- })
- if err := srv.Run(":9999"); err != nil {
- panic(err)
+ var cases = []struct {
+ name string
+ network server.Network
+ addr string
+ shouldPanic bool
+ }{{name: "TestNew_Unknown", addr: "", network: "Unknown", shouldPanic: true}, {name: "TestNew_None", addr: "", network: server.NetworkNone, shouldPanic: false}, {name: "TestNew_None_Addr", addr: "addr", network: server.NetworkNone, shouldPanic: false}, {name: "TestNew_Tcp_AddrEmpty", addr: "", network: server.NetworkTcp, shouldPanic: true}, {name: "TestNew_Tcp_AddrIllegal", addr: "addr", network: server.NetworkTcp, shouldPanic: true}, {name: "TestNew_Tcp_Addr", addr: ":9999", network: server.NetworkTcp, shouldPanic: false}, {name: "TestNew_Tcp4_AddrEmpty", addr: "", network: server.NetworkTcp4, shouldPanic: true}, {name: "TestNew_Tcp4_AddrIllegal", addr: "addr", network: server.NetworkTcp4, shouldPanic: true}, {name: "TestNew_Tcp4_Addr", addr: ":9999", network: server.NetworkTcp4, shouldPanic: false}, {name: "TestNew_Tcp6_AddrEmpty", addr: "", network: server.NetworkTcp6, shouldPanic: true}, {name: "TestNew_Tcp6_AddrIllegal", addr: "addr", network: server.NetworkTcp6, shouldPanic: true}, {name: "TestNew_Tcp6_Addr", addr: ":9999", network: server.NetworkTcp6, shouldPanic: false}, {name: "TestNew_Udp_AddrEmpty", addr: "", network: server.NetworkUdp, shouldPanic: true}, {name: "TestNew_Udp_AddrIllegal", addr: "addr", network: server.NetworkUdp, shouldPanic: true}, {name: "TestNew_Udp_Addr", addr: ":9999", network: server.NetworkUdp, shouldPanic: false}, {name: "TestNew_Udp4_AddrEmpty", addr: "", network: server.NetworkUdp4, shouldPanic: true}, {name: "TestNew_Udp4_AddrIllegal", addr: "addr", network: server.NetworkUdp4, shouldPanic: true}, {name: "TestNew_Udp4_Addr", addr: ":9999", network: server.NetworkUdp4, shouldPanic: false}, {name: "TestNew_Udp6_AddrEmpty", addr: "", network: server.NetworkUdp6, shouldPanic: true}, {name: "TestNew_Udp6_AddrIllegal", addr: "addr", network: server.NetworkUdp6, shouldPanic: true}, {name: "TestNew_Udp6_Addr", addr: ":9999", network: server.NetworkUdp6, shouldPanic: false}, {name: "TestNew_Unix_AddrEmpty", addr: "", network: server.NetworkUnix, shouldPanic: true}, {name: "TestNew_Unix_AddrIllegal", addr: "addr", network: server.NetworkUnix, shouldPanic: true}, {name: "TestNew_Unix_Addr", addr: "addr", network: server.NetworkUnix, shouldPanic: false}, {name: "TestNew_Websocket_AddrEmpty", addr: "", network: server.NetworkWebsocket, shouldPanic: true}, {name: "TestNew_Websocket_AddrIllegal", addr: "addr", network: server.NetworkWebsocket, shouldPanic: true}, {name: "TestNew_Websocket_Addr", addr: ":9999/ws", network: server.NetworkWebsocket, shouldPanic: false}, {name: "TestNew_Http_AddrEmpty", addr: "", network: server.NetworkHttp, shouldPanic: true}, {name: "TestNew_Http_AddrIllegal", addr: "addr", network: server.NetworkHttp, shouldPanic: true}, {name: "TestNew_Http_Addr", addr: ":9999", network: server.NetworkHttp, shouldPanic: false}, {name: "TestNew_Kcp_AddrEmpty", addr: "", network: server.NetworkKcp, shouldPanic: true}, {name: "TestNew_Kcp_AddrIllegal", addr: "addr", network: server.NetworkKcp, shouldPanic: true}, {name: "TestNew_Kcp_Addr", addr: ":9999", network: server.NetworkKcp, shouldPanic: false}, {name: "TestNew_GRPC_AddrEmpty", addr: "", network: server.NetworkGRPC, shouldPanic: true}, {name: "TestNew_GRPC_AddrIllegal", addr: "addr", network: server.NetworkGRPC, shouldPanic: true}, {name: "TestNew_GRPC_Addr", addr: ":9999", network: server.NetworkGRPC, shouldPanic: false}}
+ for _, c := range cases {
+ t.Run(c.name, func(t *testing.T) {
+ defer func() {
+ if err := super.RecoverTransform(recover()); err != nil && !c.shouldPanic {
+ debug.PrintStack()
+ t.Fatal("not should panic, err:", err)
+ }
+ }()
+ if err := server.New(c.network, server.WithLimitLife(time.Millisecond*10)).Run(""); err != nil {
+ panic(err)
+ }
+ })
}
}
@@ -354,6 +522,34 @@ func TestNew(t *testing.T) {
**示例代码:**
+这个案例中我们将 `TestService` 绑定到了 `srv` 服务器中,当服务器启动时,将会对 `TestService` 进行初始化
+
+其中 `TestService` 的定义如下:
+```go
+
+ type TestService struct{}
+
+ func (ts *TestService) OnInit(srv *server.Server) {
+ srv.RegStartFinishEvent(onStartFinish)
+
+ srv.RegStopEvent(func(srv *server.Server) {
+ fmt.Println("server stop")
+ })
+ }
+
+ func (ts *TestService) onStartFinish(srv *server.Server) {
+ fmt.Println("server start finish")
+ }
+
+```
+
+可以看出,在服务初始化时,该服务向服务器注册了启动完成事件及停止事件。这是我们推荐的编码方式,这样编码有以下好处:
+ - 具备可控制的初始化顺序,避免 init 产生的各种顺序导致的问题,如配置还未加载完成,即开始进行数据库连接等操作
+ - 可以方便的将不同的服务拆分到不同的包中进行管理
+ - 当不需要某个服务时,可以直接删除该服务的绑定,而不需要修改其他代码
+ - ...
+
+
```go
func ExampleBindService() {
@@ -373,10 +569,15 @@ func ExampleBindService() {
```go
func TestBindService(t *testing.T) {
- srv := server.New(server.NetworkNone, server.WithLimitLife(time.Second))
- server.BindService(srv, new(TestService))
- if err := srv.RunNone(); err != nil {
- t.Fatal(err)
+ var cases = []struct{ name string }{{name: "TestBindService"}}
+ for _, c := range cases {
+ t.Run(c.name, func(t *testing.T) {
+ srv := server.New(server.NetworkNone, server.WithLimitLife(time.Millisecond))
+ server.BindService(srv, new(TestService))
+ if err := srv.RunNone(); err != nil {
+ t.Fatal(err)
+ }
+ })
}
}
@@ -396,25 +597,43 @@ type Bot struct {
joined atomic.Bool
}
```
+
+
#### func (*Bot) JoinServer()
> 加入服务器
+
***
+
+
#### func (*Bot) LeaveServer()
> 离开服务器
+
***
+
+
#### func (*Bot) SetNetworkDelay(delay time.Duration, fluctuation time.Duration)
> 设置网络延迟和波动范围
> - delay 延迟
> - fluctuation 波动范围
+
***
+
+
#### func (*Bot) SetWriter(writer io.Writer)
> 设置写入器
+
***
+
+
#### func (*Bot) SendPacket(packet []byte)
> 发送数据包到服务器
+
***
+
+
#### func (*Bot) SendWSPacket(wst int, packet []byte)
> 发送 WebSocket 数据包到服务器
+
***
### BotOption `STRUCT`
@@ -432,79 +651,148 @@ type Conn struct {
ctx context.Context
}
```
+
+
#### func (*Conn) Ticker() *timer.Ticker
> 获取定时器
+
***
+
+
#### func (*Conn) GetServer() *Server
> 获取服务器
+
***
+
+
#### func (*Conn) GetOpenTime() time.Time
> 获取连接打开时间
+
***
+
+
#### func (*Conn) GetOnlineTime() time.Duration
> 获取连接在线时长
+
***
+
+
#### func (*Conn) GetWebsocketRequest() *http.Request
> 获取websocket请求
+
***
+
+
#### func (*Conn) IsBot() bool
> 是否是机器人连接
+
***
+
+
#### func (*Conn) RemoteAddr() net.Addr
> 获取远程地址
+
***
+
+
#### func (*Conn) GetID() string
> 获取连接ID
> - 为远程地址的字符串形式
+
***
+
+
#### func (*Conn) GetIP() string
> 获取连接IP
+
***
+
+
#### func (*Conn) IsClosed() bool
> 是否已经关闭
+
***
+
+
#### func (*Conn) SetData(key any, value any) *Conn
> 设置连接数据,该数据将在连接关闭前始终存在
+
***
+
+
#### func (*Conn) GetData(key any) any
> 获取连接数据
+
***
+
+
#### func (*Conn) ViewData() map[any]any
> 查看只读的连接数据
+
***
+
+
#### func (*Conn) SetMessageData(key any, value any) *Conn
> 设置消息数据,该数据将在消息处理完成后释放
+
***
+
+
#### func (*Conn) GetMessageData(key any) any
> 获取消息数据
+
***
+
+
#### func (*Conn) ReleaseData() *Conn
> 释放数据
+
***
+
+
#### func (*Conn) IsWebsocket() bool
> 是否是websocket连接
+
***
+
+
#### func (*Conn) GetWST() int
> 获取本次 websocket 消息类型
> - 默认将与发送类型相同
+
***
+
+
#### func (*Conn) SetWST(wst int) *Conn
> 设置本次 websocket 消息类型
+
***
+
+
#### func (*Conn) PushAsyncMessage(caller func () error, callback func (err error), mark ...log.Field)
> 推送异步消息,该消息将通过 Server.PushShuntAsyncMessage 函数推送
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
+
***
+
+
#### func (*Conn) PushUniqueAsyncMessage(name string, caller func () error, callback func (err error), mark ...log.Field)
> 推送唯一异步消息,该消息将通过 Server.PushUniqueShuntAsyncMessage 函数推送
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
> - 不同的是当上一个相同的 unique 消息未执行完成时,将会忽略该消息
+
***
+
+
#### func (*Conn) Write(packet []byte, callback ...func (err error))
> 向连接中写入数据
+
***
+
+
#### func (*Conn) Close(err ...error)
> 关闭连接
+
***
### ConsoleParams `STRUCT`
@@ -512,26 +800,47 @@ type Conn struct {
```go
type ConsoleParams map[string][]string
```
+
+
#### func (ConsoleParams) Get(key string) string
> 获取参数值
+
***
+
+
#### func (ConsoleParams) GetValues(key string) []string
> 获取参数值
+
***
+
+
#### func (ConsoleParams) GetValueNum(key string) int
> 获取参数值数量
+
***
+
+
#### func (ConsoleParams) Has(key string) bool
> 是否存在参数
+
***
+
+
#### func (ConsoleParams) Add(key string, value string)
> 添加参数
+
***
+
+
#### func (ConsoleParams) Del(key string)
> 删除参数
+
***
+
+
#### func (ConsoleParams) Clear()
> 清空参数
+
***
### MessageReadyEventHandler `STRUCT`
@@ -549,7 +858,10 @@ type Http[Context any] struct {
*HttpRouter[Context]
}
```
+
+
#### func (*Http) Gin() *gin.Engine
+
***
### HttpContext `STRUCT`
@@ -559,11 +871,17 @@ type HttpContext struct {
*gin.Context
}
```
+
+
#### func (*HttpContext) Gin() *gin.Context
> 获取 gin.Context
+
***
+
+
#### func (*HttpContext) ReadTo(dest any) error
> 读取请求数据到指定结构体,如果失败则返回错误
+
***
### HandlerFunc `STRUCT`
@@ -587,69 +905,123 @@ type HttpRouter[Context any] struct {
packer ContextPacker[Context]
}
```
+
+
#### func (*HttpRouter) Handle(httpMethod string, relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 使用给定的路径和方法注册新的请求句柄和中间件
> - 最后一个处理程序应该是真正的处理程序,其他处理程序应该是可以而且应该在不同路由之间共享的中间件。
+
***
+
+
#### func (*HttpRouter) POST(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("POST", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) GET(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("GET", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) DELETE(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("DELETE", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) PATCH(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("PATCH", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) PUT(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("PUT", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) OPTIONS(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("OPTIONS", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) HEAD(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("HEAD", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) CONNECT(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("CONNECT", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) TRACE(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 是 Handle("TRACE", path, handlers) 的快捷方式
+
***
+
+
#### func (*HttpRouter) Any(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 注册一个匹配所有 HTTP 方法的路由
> - GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
+
***
+
+
#### func (*HttpRouter) Match(methods []string, relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 注册一个匹配指定 HTTP 方法的路由
> - GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
+
***
+
+
#### func (*HttpRouter) StaticFile(relativePath string, filepath string) *HttpRouter[Context]
> 注册单个路由以便为本地文件系统的单个文件提供服务。
> - 例如: StaticFile("favicon.ico", "./resources/favicon.ico")
+
***
+
+
#### func (*HttpRouter) StaticFileFS(relativePath string, filepath string, fs http.FileSystem) *HttpRouter[Context]
> 与 `StaticFile` 类似,但可以使用自定义的 `http.FileSystem` 代替。
> - 例如: StaticFileFS("favicon.ico", "./resources/favicon.ico", Dir{".", false})
> - 由于依赖于 gin.Engine 默认情况下使用:gin.Dir
+
***
+
+
#### func (*HttpRouter) Static(relativePath string, root string) *HttpRouter[Context]
> 提供来自给定文件系统根目录的文件。
> - 例如: Static("/static", "/var/www")
+
***
+
+
#### func (*HttpRouter) StaticFS(relativePath string, fs http.FileSystem) *HttpRouter[Context]
> 与 `Static` 类似,但可以使用自定义的 `http.FileSystem` 代替。
> - 例如: StaticFS("/static", Dir{"/var/www", false})
> - 由于依赖于 gin.Engine 默认情况下使用:gin.Dir
+
***
+
+
#### func (*HttpRouter) Group(relativePath string, handlers ...HandlerFunc[Context]) *HttpRouter[Context]
> 创建一个新的路由组。您应该添加所有具有共同中间件的路由。
> - 例如: v1 := slf.Group("/v1")
+
***
+
+
#### func (*HttpRouter) Use(middleware ...HandlerFunc[Context]) *HttpRouter[Context]
> 将中间件附加到路由组。
+
***
### HttpWrapperHandleFunc `STRUCT`
@@ -666,56 +1038,107 @@ type HttpWrapper[CTX any] struct {
packHandle func(ctx *gin.Context) CTX
}
```
+
+
#### func (*HttpWrapper) Handle(httpMethod string, relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 处理请求
+
***
+
+
#### func (*HttpWrapper) Use(middleware ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 使用中间件
+
***
+
+
#### func (*HttpWrapper) GET(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 GET 请求
+
***
+
+
#### func (*HttpWrapper) POST(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 POST 请求
+
***
+
+
#### func (*HttpWrapper) DELETE(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 DELETE 请求
+
***
+
+
#### func (*HttpWrapper) PATCH(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 PATCH 请求
+
***
+
+
#### func (*HttpWrapper) PUT(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 PUT 请求
+
***
+
+
#### func (*HttpWrapper) OPTIONS(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 OPTIONS 请求
+
***
+
+
#### func (*HttpWrapper) HEAD(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 HEAD 请求
+
***
+
+
#### func (*HttpWrapper) Trace(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 Trace 请求
+
***
+
+
#### func (*HttpWrapper) Connect(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 Connect 请求
+
***
+
+
#### func (*HttpWrapper) Any(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册 Any 请求
+
***
+
+
#### func (*HttpWrapper) Match(methods []string, relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapper[CTX]
> 注册与您声明的指定方法相匹配的路由。
+
***
+
+
#### func (*HttpWrapper) StaticFile(relativePath string, filepath string) *HttpWrapper[CTX]
> 注册 StaticFile 请求
+
***
+
+
#### func (*HttpWrapper) Static(relativePath string, root string) *HttpWrapper[CTX]
> 注册 Static 请求
+
***
+
+
#### func (*HttpWrapper) StaticFS(relativePath string, fs http.FileSystem) *HttpWrapper[CTX]
> 注册 StaticFS 请求
+
***
+
+
#### func (*HttpWrapper) Group(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 创建一个新的路由组。您应该添加所有具有共同中间件的路由。
+
***
### HttpWrapperGroup `STRUCT`
@@ -726,32 +1149,59 @@ type HttpWrapperGroup[CTX any] struct {
group *gin.RouterGroup
}
```
+
+
#### func (*HttpWrapperGroup) Handle(httpMethod string, relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 处理请求
+
***
+
+
#### func (*HttpWrapperGroup) Use(middleware ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 使用中间件
+
***
+
+
#### func (*HttpWrapperGroup) GET(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 注册 GET 请求
+
***
+
+
#### func (*HttpWrapperGroup) POST(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 注册 POST 请求
+
***
+
+
#### func (*HttpWrapperGroup) DELETE(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 注册 DELETE 请求
+
***
+
+
#### func (*HttpWrapperGroup) PATCH(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 注册 PATCH 请求
+
***
+
+
#### func (*HttpWrapperGroup) PUT(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 注册 PUT 请求
+
***
+
+
#### func (*HttpWrapperGroup) OPTIONS(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 注册 OPTIONS 请求
+
***
+
+
#### func (*HttpWrapperGroup) Group(relativePath string, handlers ...HttpWrapperHandleFunc[CTX]) *HttpWrapperGroup[CTX]
> 创建分组
+
***
### MessageType `STRUCT`
@@ -759,8 +1209,11 @@ type HttpWrapperGroup[CTX any] struct {
```go
type MessageType byte
```
+
+
#### func (MessageType) String() string
> 返回消息类型的字符串表示
+
***
### Message `STRUCT`
@@ -780,13 +1233,22 @@ type Message struct {
t MessageType
}
```
+
+
#### func (*Message) GetProducer() string
+
***
+
+
#### func (*Message) MessageType() MessageType
> 返回消息类型
+
***
+
+
#### func (*Message) String() string
> 返回消息的字符串表示
+
***
### MultipleServer `STRUCT`
@@ -798,21 +1260,57 @@ type MultipleServer struct {
exitEventHandles []func()
}
```
+
+
#### func (*MultipleServer) Run()
+
***
+
+
#### func (*MultipleServer) RegExitEvent(handle func ())
> 注册退出事件
+
***
+
+
#### func (*MultipleServer) OnExitEvent()
+
***
### Network `STRUCT`
+服务器运行的网络模式
+ - 根据不同的网络模式,服务器将会产生不同的行为,该类型将在服务器创建时候指定
+服务器支持的网络模式如下:
+ - NetworkNone 该模式下不监听任何网络端口,仅开启消息队列,适用于纯粹的跨服服务器等情况
+ - NetworkTcp 该模式下将会监听 TCP 协议的所有地址,包括 IPv4 和 IPv6
+ - NetworkTcp4 该模式下将会监听 TCP 协议的 IPv4 地址
+ - NetworkTcp6 该模式下将会监听 TCP 协议的 IPv6 地址
+ - NetworkUdp 该模式下将会监听 UDP 协议的所有地址,包括 IPv4 和 IPv6
+ - NetworkUdp4 该模式下将会监听 UDP 协议的 IPv4 地址
+ - NetworkUdp6 该模式下将会监听 UDP 协议的 IPv6 地址
+ - NetworkUnix 该模式下将会监听 Unix 协议的地址
+ - NetworkHttp 该模式下将会监听 HTTP 协议的地址
+ - NetworkWebsocket 该模式下将会监听 Websocket 协议的地址
+ - NetworkKcp 该模式下将会监听 KCP 协议的地址
+ - NetworkGRPC 该模式下将会监听 GRPC 协议的地址
```go
type Network string
```
+
+
#### func (Network) IsSocket() bool
-> 返回当前服务器的网络模式是否为 Socket 模式
+> 返回当前服务器的网络模式是否为 Socket 模式,目前为止仅有如下几种模式为 Socket 模式:
+> - NetworkTcp
+> - NetworkTcp4
+> - NetworkTcp6
+> - NetworkUdp
+> - NetworkUdp4
+> - NetworkUdp6
+> - NetworkUnix
+> - NetworkKcp
+> - NetworkWebsocket
+
***
### Option `STRUCT`
@@ -849,6 +1347,8 @@ type Server struct {
services []func()
}
```
+
+
#### func (*Server) Run(addr string) (err error)
> 使用特定地址运行服务器
> - server.NetworkTcp (addr:":8888")
@@ -862,15 +1362,18 @@ type Server struct {
> - server.NetworkWebsocket (addr:":8888/ws")
> - server.NetworkKcp (addr:":8888")
> - server.NetworkNone (addr:"")
+
**示例代码:**
+该案例将创建一个简单的 WebSocket 服务器并启动监听 `:9999/` 作为 WebSocket 监听地址,如果需要更多的服务器类型可参考 [` Network `](#struct_Network) 部分
+ - 当服务器启动失败后,将会返回错误信息并触发 panic
+ - server.WithLimitLife(time.Millisecond) 通常不是在正常开发应该使用的,在这里只是为了让服务器在启动完成后的 1 毫秒后自动关闭
+
+
```go
func ExampleServer_Run() {
srv := server.New(server.NetworkWebsocket, server.WithLimitLife(time.Millisecond))
- srv.RegConnectionReceivePacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte) {
- conn.Write(packet)
- })
if err := srv.Run(":9999"); err != nil {
panic(err)
}
@@ -879,76 +1382,199 @@ func ExampleServer_Run() {
```
***
+
+
#### func (*Server) IsSocket() bool
-> 是否是 Socket 模式
+> 通过执行 Network.IsSocket 函数检查该服务器是否是 Socket 模式
+
+**示例代码:**
+
+该案例将创建两个不同类型的服务器,其中 WebSocket 是一个 Socket 服务器,而 Http 是一个非 Socket 服务器
+
+可知案例输出结果为:
+ - true
+ - false
+
+
+```go
+
+func ExampleServer_IsSocket() {
+ srv1 := server.New(server.NetworkWebsocket)
+ fmt.Println(srv1.IsSocket())
+ srv2 := server.New(server.NetworkHttp)
+ fmt.Println(srv2.IsSocket())
+}
+
+```
+
+
+查看 / 收起单元测试
+
+
+这个测试检查了各个类型的服务器是否为 Socket 模式。如需查看为 Socket 模式的网络类型,请参考 [` Network.IsSocket` ](#struct_Network_IsSocket)
+
+
+```go
+
+func TestServer_IsSocket(t *testing.T) {
+ var cases = []struct {
+ name string
+ network server.Network
+ expect bool
+ }{{name: "TestServer_IsSocket_None", network: server.NetworkNone, expect: false}, {name: "TestServer_IsSocket_Tcp", network: server.NetworkTcp, expect: true}, {name: "TestServer_IsSocket_Tcp4", network: server.NetworkTcp4, expect: true}, {name: "TestServer_IsSocket_Tcp6", network: server.NetworkTcp6, expect: true}, {name: "TestServer_IsSocket_Udp", network: server.NetworkUdp, expect: true}, {name: "TestServer_IsSocket_Udp4", network: server.NetworkUdp4, expect: true}, {name: "TestServer_IsSocket_Udp6", network: server.NetworkUdp6, expect: true}, {name: "TestServer_IsSocket_Unix", network: server.NetworkUnix, expect: true}, {name: "TestServer_IsSocket_Http", network: server.NetworkHttp, expect: false}, {name: "TestServer_IsSocket_Websocket", network: server.NetworkWebsocket, expect: true}, {name: "TestServer_IsSocket_Kcp", network: server.NetworkKcp, expect: true}, {name: "TestServer_IsSocket_GRPC", network: server.NetworkGRPC, expect: false}}
+ for _, c := range cases {
+ t.Run(c.name, func(t *testing.T) {
+ s := server.New(c.network)
+ if s.IsSocket() != c.expect {
+ t.Fatalf("expect: %v, got: %v", c.expect, s.IsSocket())
+ }
+ })
+ }
+}
+
+```
+
+
+
+
+
***
+
+
#### func (*Server) RunNone() error
> 是 Run("") 的简写,仅适用于运行 NetworkNone 服务器
+
+**示例代码:**
+
+RunNone 函数并没有特殊的意义,该函数内部调用了 `srv.Run("")` 函数,仅是一个语法糖,用来表示服务器不需要监听任何地址
+
+
+```go
+
+func ExampleServer_RunNone() {
+ srv := server.New(server.NetworkNone)
+ if err := srv.RunNone(); err != nil {
+ panic(err)
+ }
+}
+
+```
+
***
+
+
#### func (*Server) Context() context.Context
> 获取服务器上下文
+
***
+
+
#### func (*Server) TimeoutContext(timeout time.Duration) ( context.Context, context.CancelFunc)
> 获取服务器超时上下文,context.WithTimeout 的简写
+
***
+
+
#### func (*Server) Ticker() *timer.Ticker
> 获取服务器定时器
+
***
+
+
#### func (*Server) Shutdown()
> 主动停止运行服务器
+
***
+
+
#### func (*Server) GRPCServer() *grpc.Server
> 当网络类型为 NetworkGRPC 时将被允许获取 grpc 服务器,否则将会发生 panic
+
***
+
+
#### func (*Server) HttpRouter() gin.IRouter
> 当网络类型为 NetworkHttp 时将被允许获取路由器进行路由注册,否则将会发生 panic
> - 通过该函数注册的路由将无法在服务器关闭时正常等待请求结束
>
> Deprecated: 从 Minotaur 0.0.29 开始,由于设计原因已弃用,该函数将直接返回 *gin.Server 对象,导致无法正常的对请求结束时进行处理
+
***
+
+
#### func (*Server) HttpServer() *Http[*HttpContext]
> 替代 HttpRouter 的函数,返回一个 *Http[*HttpContext] 对象
> - 通过该函数注册的路由将在服务器关闭时正常等待请求结束
> - 如果需要自行包装 Context 对象,可以使用 NewHttpHandleWrapper 方法
+
***
+
+
#### func (*Server) GetMessageCount() int64
> 获取当前服务器中消息的数量
+
***
+
+
#### func (*Server) UseShunt(conn *Conn, name string)
> 切换连接所使用的消息分流渠道,当分流渠道 name 不存在时将会创建一个新的分流渠道,否则将会加入已存在的分流渠道
> - 默认情况下,所有连接都使用系统通道进行消息分发,当指定消息分流渠道且为分流消息类型时,将会使用指定的消息分流渠道进行消息分发
> - 分流渠道会在连接断开时标记为驱逐状态,当分流渠道中的所有消息处理完毕且没有新连接使用时,将会被清除
+
***
+
+
#### func (*Server) HasShunt(name string) bool
> 检查特定消息分流渠道是否存在
+
***
+
+
#### func (*Server) GetConnCurrShunt(conn *Conn) string
> 获取连接当前所使用的消息分流渠道
+
***
+
+
#### func (*Server) GetShuntNum() int
> 获取消息分流渠道数量
+
***
+
+
#### func (*Server) PushSystemMessage(handler func (), mark ...log.Field)
> 向服务器中推送 MessageTypeSystem 消息
> - 系统消息仅包含一个可执行函数,将在系统分发器中执行
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
+
***
+
+
#### func (*Server) PushAsyncMessage(caller func () error, callback func (err error), mark ...log.Field)
> 向服务器中推送 MessageTypeAsync 消息
> - 异步消息将在服务器的异步消息队列中进行处理,处理完成 caller 的阻塞操作后,将会通过系统消息执行 callback 函数
> - callback 函数将在异步消息处理完成后进行调用,无论过程是否产生 err,都将被执行,允许为 nil
> - 需要注意的是,为了避免并发问题,caller 函数请仅处理阻塞操作,其他操作应该在 callback 函数中进行
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
+
***
+
+
#### func (*Server) PushShuntAsyncMessage(conn *Conn, caller func () error, callback func (err error), mark ...log.Field)
> 向特定分发器中推送 MessageTypeAsync 消息,消息执行与 MessageTypeAsync 一致
> - 需要注意的是,当未指定 UseShunt 时,将会通过 PushAsyncMessage 进行转发
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
+
***
+
+
#### func (*Server) PushPacketMessage(conn *Conn, wst int, packet []byte, mark ...log.Field)
> 向服务器中推送 MessageTypePacket 消息
> - 当存在 UseShunt 的选项时,将会根据选项中的 shuntMatcher 进行分发,否则将在系统分发器中处理消息
+
***
+
+
#### func (*Server) PushTickerMessage(name string, caller func (), mark ...log.Field)
> 向服务器中推送 MessageTypeTicker 消息
> - 通过该函数推送定时消息,当消息触发时将在系统分发器中处理消息
@@ -957,40 +1583,66 @@ func ExampleServer_Run() {
>
> 定时消息执行不会有特殊的处理,仅标记为定时任务,也就是允许将各类函数通过该消息发送处理,但是并不建议
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
+
***
+
+
#### func (*Server) PushShuntTickerMessage(conn *Conn, name string, caller func (), mark ...log.Field)
> 向特定分发器中推送 MessageTypeTicker 消息,消息执行与 MessageTypeTicker 一致
> - 需要注意的是,当未指定 UseShunt 时,将会通过 PushTickerMessage 进行转发
> - mark 为可选的日志标记,当发生异常时,将会在日志中进行体现
+
***
+
+
#### func (*Server) PushUniqueAsyncMessage(unique string, caller func () error, callback func (err error), mark ...log.Field)
> 向服务器中推送 MessageTypeAsync 消息,消息执行与 MessageTypeAsync 一致
> - 不同的是当上一个相同的 unique 消息未执行完成时,将会忽略该消息
+
***
+
+
#### func (*Server) PushUniqueShuntAsyncMessage(conn *Conn, unique string, caller func () error, callback func (err error), mark ...log.Field)
> 向特定分发器中推送 MessageTypeAsync 消息,消息执行与 MessageTypeAsync 一致
> - 需要注意的是,当未指定 UseShunt 时,将会通过系统分流渠道进行转发
> - 不同的是当上一个相同的 unique 消息未执行完成时,将会忽略该消息
+
***
+
+
#### func (*Server) PushShuntMessage(conn *Conn, caller func (), mark ...log.Field)
> 向特定分发器中推送 MessageTypeShunt 消息,消息执行与 MessageTypeSystem 一致,不同的是将会在特定分发器中执行
+
***
+
+
#### func (*Server) GetDurationMessageCount() int64
> 获取当前 WithMessageStatistics 设置的 duration 期间的消息量
+
***
+
+
#### func (*Server) GetDurationMessageCountByOffset(offset int) int64
> 获取特定偏移次数的 WithMessageStatistics 设置的 duration 期间的消息量
> - 该值小于 0 时,将与 GetDurationMessageCount 无异,否则将返回 +n 个期间的消息量,例如 duration 为 1 分钟,limit 为 10,那么 offset 为 1 的情况下,获取的则是上一分钟消息量
+
***
+
+
#### func (*Server) GetAllDurationMessageCount() []int64
> 获取所有 WithMessageStatistics 设置的 duration 期间的消息量
+
***
+
+
#### func (*Server) HasMessageStatistics() bool
> 是否了开启消息统计
+
***
### Service `INTERFACE`
-兼容传统 service 设计模式的接口
+兼容传统 service 设计模式的接口,通过该接口可以实现更简洁、更具有可读性的服务绑定
+ - 在这之前,我们在实现功能上会将 Server 进行全局存储,之后通过 init 函数进行初始化,这样的顺序是不可控的。
```go
type Service interface {
OnInit(srv *Server)
diff --git a/server/client/README.md b/server/client/README.md
index 1d7658e..25293ce 100644
--- a/server/client/README.md
+++ b/server/client/README.md
@@ -78,23 +78,38 @@ type Client struct {
block chan struct{}
}
```
+
+
#### func (*Client) Run(block ...bool) error
> 运行客户端,当客户端已运行时,会先关闭客户端再重新运行
> - block 以阻塞方式运行
+
***
+
+
#### func (*Client) RunByBufferSize(size int, block ...bool) error
> 指定写入循环缓冲区大小运行客户端,当客户端已运行时,会先关闭客户端再重新运行
> - block 以阻塞方式运行
+
***
+
+
#### func (*Client) IsConnected() bool
> 是否已连接
+
***
+
+
#### func (*Client) Close(err ...error)
> 关闭
+
***
+
+
#### func (*Client) WriteWS(wst int, packet []byte, callback ...func (err error))
> 向连接中写入指定 websocket 数据类型
> - wst: websocket模式中指定消息类型
+
查看 / 收起单元测试
@@ -133,11 +148,17 @@ func TestClient_WriteWS(t *testing.T) {
***
+
+
#### func (*Client) Write(packet []byte, callback ...func (err error))
> 向连接中写入数据
+
***
+
+
#### func (*Client) GetServerAddr() string
> 获取服务器地址
+
***
### Core `INTERFACE`
@@ -177,15 +198,30 @@ type TCP struct {
closed bool
}
```
+
+
#### func (*TCP) Run(runState chan error, receive func (wst int, packet []byte))
+
***
+
+
#### func (*TCP) Write(packet *Packet) error
+
***
+
+
#### func (*TCP) Close()
+
***
+
+
#### func (*TCP) GetServerAddr() string
+
***
+
+
#### func (*TCP) Clone() Core
+
***
### UnixDomainSocket `STRUCT`
@@ -197,9 +233,15 @@ type UnixDomainSocket struct {
closed bool
}
```
+
+
#### func (*UnixDomainSocket) Run(runState chan error, receive func (wst int, packet []byte))
+
***
+
+
#### func (*UnixDomainSocket) Write(packet *Packet) error
+
查看 / 收起单元测试
@@ -243,11 +285,20 @@ func TestUnixDomainSocket_Write(t *testing.T) {
***
+
+
#### func (*UnixDomainSocket) Close()
+
***
+
+
#### func (*UnixDomainSocket) GetServerAddr() string
+
***
+
+
#### func (*UnixDomainSocket) Clone() Core
+
***
### Websocket `STRUCT`
@@ -260,13 +311,28 @@ type Websocket struct {
mu sync.Mutex
}
```
+
+
#### func (*Websocket) Run(runState chan error, receive func (wst int, packet []byte))
+
***
+
+
#### func (*Websocket) Write(packet *Packet) error
+
***
+
+
#### func (*Websocket) Close()
+
***
+
+
#### func (*Websocket) GetServerAddr() string
+
***
+
+
#### func (*Websocket) Clone() Core
+
***
diff --git a/server/gateway/README.md b/server/gateway/README.md
index e647ee3..a0b776b 100644
--- a/server/gateway/README.md
+++ b/server/gateway/README.md
@@ -129,18 +129,30 @@ type Endpoint struct {
cps int
}
```
+
+
#### func (*Endpoint) GetName() string
> 获取端点名称
+
***
+
+
#### func (*Endpoint) GetAddress() string
> 获取端点地址
+
***
+
+
#### func (*Endpoint) GetState() float64
> 获取端点健康值
+
***
+
+
#### func (*Endpoint) Forward(conn *server.Conn, packet []byte, callback ...func (err error))
> 转发数据包到该端点
> - 端点在处理数据包时,应区分数据包为普通直连数据包还是网关数据包。可通过 UnmarshalGatewayOutPacket 进行数据包解析,当解析失败且无其他数据包协议时,可认为该数据包为普通直连数据包。
+
***
### EndpointOption `STRUCT`
@@ -186,8 +198,11 @@ type Gateway struct {
cceLock sync.RWMutex
}
```
+
+
#### func (*Gateway) Run(addr string) error
> 运行网关
+
查看 / 收起单元测试
@@ -217,23 +232,38 @@ func TestGateway_Run(t *testing.T) {
***
+
+
#### func (*Gateway) Shutdown()
> 关闭网关
+
***
+
+
#### func (*Gateway) Server() *server.Server
> 获取网关服务器核心
+
***
+
+
#### func (*Gateway) GetEndpoint(name string) ( *Endpoint, error)
> 获取一个可用的端点
> - name: 端点名称
+
***
+
+
#### func (*Gateway) GetConnEndpoint(name string, conn *server.Conn) ( *Endpoint, error)
> 获取一个可用的端点,如果客户端已经连接到了某个端点,将优先返回该端点
> - 当连接到的端点不可用或没有连接记录时,效果同 GetEndpoint 相同
> - 当连接行为为有状态时,推荐使用该方法
+
***
+
+
#### func (*Gateway) SwitchEndpoint(source *Endpoint, dest *Endpoint)
> 将端点端点的所有连接切换到另一个端点
+
***
### Option `STRUCT`
@@ -250,7 +280,13 @@ type Scanner interface {
GetInterval() time.Duration
}
```
+
+
#### func (*Scanner) GetEndpoints() ( []*gateway.Endpoint, error)
+
***
+
+
#### func (*Scanner) GetInterval() time.Duration
+
***
diff --git a/server/internal/dispatcher/README.md b/server/internal/dispatcher/README.md
index 4325cdf..bda4852 100644
--- a/server/internal/dispatcher/README.md
+++ b/server/internal/dispatcher/README.md
@@ -176,14 +176,23 @@ type Action[P Producer, M Message[P]] struct {
d *Dispatcher[P, M]
}
```
+
+
#### func (*Action) Name() string
> 获取消息分发器名称
+
***
+
+
#### func (*Action) UnExpel()
> 取消特定生产者的驱逐计划
+
***
+
+
#### func (*Action) Expel()
> 设置该消息分发器即将被驱逐,当消息分发器中没有任何消息时,会自动关闭
+
***
### Handler `STRUCT`
@@ -221,11 +230,12 @@ type Dispatcher[P Producer, M Message[P]] struct {
abort chan struct{}
}
```
+
+
#### func (*Dispatcher) SetProducerDoneHandler(p P, handler func (p P, dispatcher *Action[P, M])) *Dispatcher[P, M]
-> 设置特定生产者所有消息处理完成时的回调函数
+> 设置特定生产者的所有消息处理完成时的回调函数
> - 如果 handler 为 nil,则会删除该生产者的回调函数
->
-> 需要注意的是,该 handler 中
+
查看 / 收起单元测试
@@ -271,8 +281,11 @@ func TestDispatcher_SetProducerDoneHandler(t *testing.T) {
***
+
+
#### func (*Dispatcher) SetClosedHandler(handler func (dispatcher *Action[P, M])) *Dispatcher[P, M]
> 设置消息分发器关闭时的回调函数
+
查看 / 收起单元测试
@@ -319,8 +332,11 @@ func TestDispatcher_SetClosedHandler(t *testing.T) {
***
+
+
#### func (*Dispatcher) Name() string
> 获取消息分发器名称
+
查看 / 收起单元测试
@@ -348,14 +364,23 @@ func TestDispatcher_Name(t *testing.T) {
***
+
+
#### func (*Dispatcher) Unique(name string) bool
> 设置唯一消息键,返回是否已存在
+
***
+
+
#### func (*Dispatcher) AntiUnique(name string)
> 取消唯一消息键
+
***
+
+
#### func (*Dispatcher) Expel()
> 设置该消息分发器即将被驱逐,当消息分发器中没有任何消息时,会自动关闭
+
查看 / 收起单元测试
@@ -402,8 +427,11 @@ func TestDispatcher_Expel(t *testing.T) {
***
+
+
#### func (*Dispatcher) UnExpel()
> 取消特定生产者的驱逐计划
+
查看 / 收起单元测试
@@ -452,12 +480,18 @@ func TestDispatcher_UnExpel(t *testing.T) {
***
+
+
#### func (*Dispatcher) IncrCount(producer P, i int64)
> 主动增量设置特定生产者的消息计数,这在等待异步消息完成后再关闭消息分发器时非常有用
> - 如果 i 为负数,则会减少消息计数
+
***
+
+
#### func (*Dispatcher) Put(message M)
> 将消息放入分发器
+
查看 / 收起单元测试
@@ -498,8 +532,11 @@ func TestDispatcher_Put(t *testing.T) {
***
+
+
#### func (*Dispatcher) Start() *Dispatcher[P, M]
> 以非阻塞的方式开始进行消息分发,当消息分发器中没有任何消息并且处于驱逐计划 Expel 时,将会自动关闭
+
查看 / 收起单元测试
@@ -540,8 +577,11 @@ func TestDispatcher_Start(t *testing.T) {
***
+
+
#### func (*Dispatcher) Closed() bool
> 判断消息分发器是否已关闭
+
查看 / 收起单元测试
@@ -594,11 +634,17 @@ type Manager[P Producer, M Message[P]] struct {
createdHandler func(name string)
}
```
+
+
#### func (*Manager) Wait()
> 等待所有消息分发器关闭
+
***
+
+
#### func (*Manager) SetDispatcherClosedHandler(handler func (name string)) *Manager[P, M]
> 设置消息分发器关闭时的回调函数
+
查看 / 收起单元测试
@@ -637,8 +683,11 @@ func TestManager_SetDispatcherClosedHandler(t *testing.T) {
***
+
+
#### func (*Manager) SetDispatcherCreatedHandler(handler func (name string)) *Manager[P, M]
> 设置消息分发器创建时的回调函数
+
查看 / 收起单元测试
@@ -677,8 +726,11 @@ func TestManager_SetDispatcherCreatedHandler(t *testing.T) {
***
+
+
#### func (*Manager) HasDispatcher(name string) bool
> 检查是否存在指定名称的消息分发器
+
查看 / 收起单元测试
@@ -714,8 +766,11 @@ func TestManager_HasDispatcher(t *testing.T) {
***
+
+
#### func (*Manager) GetDispatcherNum() int
> 获取当前正在工作的消息分发器数量
+
查看 / 收起单元测试
@@ -758,8 +813,11 @@ func TestManager_GetDispatcherNum(t *testing.T) {
***
+
+
#### func (*Manager) GetSystemDispatcher() *Dispatcher[P, M]
> 获取系统消息分发器
+
查看 / 收起单元测试
@@ -786,8 +844,11 @@ func TestManager_GetSystemDispatcher(t *testing.T) {
***
+
+
#### func (*Manager) GetDispatcher(p P) *Dispatcher[P, M]
> 获取生产者正在使用的消息分发器,如果生产者没有绑定消息分发器,则会返回系统消息分发器
+
查看 / 收起单元测试
@@ -818,8 +879,11 @@ func TestManager_GetDispatcher(t *testing.T) {
***
+
+
#### func (*Manager) BindProducer(p P, name string)
> 绑定生产者使用特定的消息分发器,如果生产者已经绑定了消息分发器,则会先解绑
+
查看 / 收起单元测试
@@ -850,8 +914,11 @@ func TestManager_BindProducer(t *testing.T) {
***
+
+
#### func (*Manager) UnBindProducer(p P)
> 解绑生产者使用特定的消息分发器
+
查看 / 收起单元测试
diff --git a/server/internal/logger/README.md b/server/internal/logger/README.md
index ca79363..4b644d8 100644
--- a/server/internal/logger/README.md
+++ b/server/internal/logger/README.md
@@ -30,7 +30,10 @@
```go
type Ants struct{}
```
+
+
#### func (*Ants) Printf(format string, args ...interface {})
+
***
### GNet `STRUCT`
@@ -38,13 +41,28 @@ type Ants struct{}
```go
type GNet struct{}
```
+
+
#### func (*GNet) Debugf(format string, args ...interface {})
+
***
+
+
#### func (*GNet) Infof(format string, args ...interface {})
+
***
+
+
#### func (*GNet) Warnf(format string, args ...interface {})
+
***
+
+
#### func (*GNet) Errorf(format string, args ...interface {})
+
***
+
+
#### func (*GNet) Fatalf(format string, args ...interface {})
+
***
diff --git a/server/lockstep/README.md b/server/lockstep/README.md
index 3452107..7c74cfc 100644
--- a/server/lockstep/README.md
+++ b/server/lockstep/README.md
@@ -152,58 +152,106 @@ type Lockstep[ClientID comparable, Command any] struct {
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`
diff --git a/server/router/README.md b/server/router/README.md
index 993cbc5..f248399 100644
--- a/server/router/README.md
+++ b/server/router/README.md
@@ -60,8 +60,11 @@ func ExampleNewMultistage() {
```go
type MultistageBind[HandleFunc any] func(HandleFunc)
```
+
+
#### func (MultistageBind) Bind(handleFunc HandleFunc)
> 将处理函数绑定到预设的路由中
+
***
### Multistage `STRUCT`
@@ -74,9 +77,12 @@ type Multistage[HandleFunc any] struct {
trim func(route any) any
}
```
+
+
#### func (*Multistage) Register(routes ...any) MultistageBind[HandleFunc]
> 注册路由是结合 Sub 和 Route 的快捷方式,用于一次性注册多级路由
> - 该函数将返回一个注册函数,可通过调用其将路由绑定到特定处理函数,例如:router.Register("a", "b").Bind(onExec())
+
**示例代码:**
```go
@@ -90,8 +96,11 @@ func ExampleMultistage_Register() {
```
***
+
+
#### func (*Multistage) Route(route any, handleFunc HandleFunc)
> 为特定路由绑定处理函数,被绑定的处理函数将可以通过 Match 函数进行匹配
+
**示例代码:**
```go
@@ -105,9 +114,12 @@ func ExampleMultistage_Route() {
```
***
+
+
#### func (*Multistage) Match(routes ...any) HandleFunc
> 匹配已绑定处理函数的路由,返回处理函数
> - 如果未找到将会返回空指针
+
**示例代码:**
```go
@@ -156,8 +168,11 @@ func TestMultistage_Match(t *testing.T) {
***
+
+
#### func (*Multistage) Sub(route any) *Multistage[HandleFunc]
> 获取子路由器
+
**示例代码:**
```go
diff --git a/server/writeloop/README.md b/server/writeloop/README.md
index 3395e2d..649cb94 100644
--- a/server/writeloop/README.md
+++ b/server/writeloop/README.md
@@ -115,11 +115,17 @@ type Channel[T any] struct {
c chan T
}
```
+
+
#### func (*Channel) Put(message T)
> 将数据放入写循环,message 应该来源于 hub.ObjectPool
+
***
+
+
#### func (*Channel) Close()
> 关闭写循环
+
***
### Unbounded `STRUCT`
@@ -130,8 +136,11 @@ type Unbounded[Message any] struct {
buf *buffer.Unbounded[Message]
}
```
+
+
#### func (*Unbounded) Put(message Message)
> 将数据放入写循环,message 应该来源于 hub.ObjectPool
+
查看 / 收起单元测试
@@ -189,8 +198,11 @@ func BenchmarkUnbounded_Put(b *testing.B) {
***
+
+
#### func (*Unbounded) Close()
> 关闭写循环
+
查看 / 收起单元测试
diff --git a/utils/aoi/README.md b/utils/aoi/README.md
index b710b34..eb25601 100644
--- a/utils/aoi/README.md
+++ b/utils/aoi/README.md
@@ -83,17 +83,35 @@ type TwoDimensional[EID generic.Basic, PosType generic.SignedNumber, E TwoDimens
repartitionQueue []func()
}
```
+
+
#### func (*TwoDimensional) AddEntity(entity E)
+
***
+
+
#### func (*TwoDimensional) DeleteEntity(entity E)
+
***
+
+
#### func (*TwoDimensional) Refresh(entity E)
+
***
+
+
#### func (*TwoDimensional) GetFocus(id EID) map[EID]E
+
***
+
+
#### func (*TwoDimensional) SetSize(width int, height int)
+
***
+
+
#### func (*TwoDimensional) SetAreaSize(width int, height int)
+
***
### TwoDimensionalEntity `INTERFACE`
diff --git a/utils/arrangement/README.md b/utils/arrangement/README.md
index e6fb97d..6694668 100644
--- a/utils/arrangement/README.md
+++ b/utils/arrangement/README.md
@@ -127,24 +127,42 @@ type Area[ID comparable, AreaInfo any] struct {
evaluate AreaEvaluateHandle[ID, AreaInfo]
}
```
+
+
#### func (*Area) GetAreaInfo() AreaInfo
> 获取编排区域的信息
+
***
+
+
#### func (*Area) GetItems() map[ID]Item[ID]
> 获取编排区域中的所有成员
+
***
+
+
#### func (*Area) IsAllow(item Item[ID]) (constraintErr error, conflictItems map[ID]Item[ID], allow bool)
> 检测一个成员是否可以被添加到该编排区域中
+
***
+
+
#### func (*Area) IsConflict(item Item[ID]) bool
> 检测一个成员是否会造成冲突
+
***
+
+
#### func (*Area) GetConflictItems(item Item[ID]) map[ID]Item[ID]
> 获取与一个成员产生冲突的所有其他成员
+
***
+
+
#### func (*Area) GetScore(extra ...Item[ID]) float64
> 获取该编排区域的评估分数
> - 当 extra 不为空时,将会将 extra 中的内容添加到 items 中进行评估
+
***
### AreaOption `STRUCT`
@@ -176,14 +194,23 @@ type Arrangement[ID comparable, AreaInfo any] struct {
conflictHandles []ConflictHandle[ID, AreaInfo]
}
```
+
+
#### func (*Arrangement) AddArea(areaInfo AreaInfo, options ...AreaOption[ID, AreaInfo])
> 添加一个编排区域
+
***
+
+
#### func (*Arrangement) AddItem(item Item[ID])
> 添加一个成员
+
***
+
+
#### func (*Arrangement) Arrange() (areas []*Area[ID, AreaInfo], noSolution map[ID]Item[ID])
> 编排
+
查看 / 收起单元测试
@@ -247,47 +274,89 @@ type Editor[ID comparable, AreaInfo any] struct {
retryCount int
}
```
+
+
#### func (*Editor) GetPendingCount() int
> 获取待编排的成员数量
+
***
+
+
#### func (*Editor) RemoveAreaItem(area *Area[ID, AreaInfo], item Item[ID])
> 从编排区域中移除一个成员到待编排队列中,如果该成员不存在于编排区域中,则不进行任何操作
+
***
+
+
#### func (*Editor) AddAreaItem(area *Area[ID, AreaInfo], item Item[ID])
> 将一个成员添加到编排区域中,如果该成员已经存在于编排区域中,则不进行任何操作
+
***
+
+
#### func (*Editor) GetAreas() []*Area[ID, AreaInfo]
> 获取所有的编排区域
+
***
+
+
#### func (*Editor) GetAreasWithScoreAsc(extra ...Item[ID]) []*Area[ID, AreaInfo]
> 获取所有的编排区域,并按照分数升序排序
+
***
+
+
#### func (*Editor) GetAreasWithScoreDesc(extra ...Item[ID]) []*Area[ID, AreaInfo]
> 获取所有的编排区域,并按照分数降序排序
+
***
+
+
#### func (*Editor) GetRetryCount() int
> 获取重试次数
+
***
+
+
#### func (*Editor) GetThresholdProgressRate() float64
> 获取重试次数阈值进度
+
***
+
+
#### func (*Editor) GetAllowAreas(item Item[ID]) []*Area[ID, AreaInfo]
> 获取允许的编排区域
+
***
+
+
#### func (*Editor) GetNoAllowAreas(item Item[ID]) []*Area[ID, AreaInfo]
> 获取不允许的编排区域
+
***
+
+
#### func (*Editor) GetBestAllowArea(item Item[ID]) *Area[ID, AreaInfo]
> 获取最佳的允许的编排区域,如果不存在,则返回 nil
+
***
+
+
#### func (*Editor) GetBestNoAllowArea(item Item[ID]) *Area[ID, AreaInfo]
> 获取最佳的不允许的编排区域,如果不存在,则返回 nil
+
***
+
+
#### func (*Editor) GetWorstAllowArea(item Item[ID]) *Area[ID, AreaInfo]
> 获取最差的允许的编排区域,如果不存在,则返回 nil
+
***
+
+
#### func (*Editor) GetWorstNoAllowArea(item Item[ID]) *Area[ID, AreaInfo]
> 获取最差的不允许的编排区域,如果不存在,则返回 nil
+
***
### Item `INTERFACE`
diff --git a/utils/buffer/README.md b/utils/buffer/README.md
index 1470178..81cd797 100644
--- a/utils/buffer/README.md
+++ b/utils/buffer/README.md
@@ -94,8 +94,11 @@ type Ring[T any] struct {
w int
}
```
+
+
#### func (*Ring) Read() ( T, error)
> 读取数据
+
查看 / 收起基准测试
@@ -120,14 +123,23 @@ func BenchmarkRing_Read(b *testing.B) {
***
+
+
#### func (*Ring) ReadAll() []T
> 读取所有数据
+
***
+
+
#### func (*Ring) Peek() (t T, err error)
> 查看数据
+
***
+
+
#### func (*Ring) Write(v T)
> 写入数据
+
查看 / 收起基准测试
@@ -149,17 +161,29 @@ func BenchmarkRing_Write(b *testing.B) {
***
+
+
#### func (*Ring) IsEmpty() bool
> 是否为空
+
***
+
+
#### func (*Ring) Cap() int
> 返回缓冲区容量
+
***
+
+
#### func (*Ring) Len() int
> 返回缓冲区长度
+
***
+
+
#### func (*Ring) Reset()
> 重置缓冲区
+
***
### RingUnbounded `STRUCT`
@@ -175,8 +199,11 @@ type RingUnbounded[T any] struct {
closedSignal chan struct{}
}
```
+
+
#### func (*RingUnbounded) Write(v T)
> 写入数据
+
查看 / 收起基准测试
@@ -198,8 +225,11 @@ func BenchmarkRingUnbounded_Write(b *testing.B) {
***
+
+
#### func (*RingUnbounded) Read() chan T
> 读取数据
+
查看 / 收起基准测试
@@ -224,11 +254,17 @@ func BenchmarkRingUnbounded_Read(b *testing.B) {
***
+
+
#### func (*RingUnbounded) Closed() bool
> 判断缓冲区是否已关闭
+
***
+
+
#### func (*RingUnbounded) Close() chan struct {}
> 关闭缓冲区,关闭后将不再接收新数据,但是已有数据仍然可以读取
+
查看 / 收起单元测试
@@ -268,15 +304,24 @@ type Unbounded[V any] struct {
backlog []V
}
```
+
+
#### func (*Unbounded) Put(t V)
> 将数据放入缓冲区
+
***
+
+
#### func (*Unbounded) Load()
> 将缓冲区中的数据发送到读取通道中,如果缓冲区中没有数据,则不会发送
> - 在每次 Get 后都应该执行该函数
+
***
+
+
#### func (*Unbounded) Get() chan V
> 获取读取通道
+
查看 / 收起单元测试
@@ -299,9 +344,15 @@ func TestUnbounded_Get(t *testing.T) {
***
+
+
#### func (*Unbounded) Close()
> 关闭
+
***
+
+
#### func (*Unbounded) IsClosed() bool
> 是否已关闭
+
***
diff --git a/utils/collection/README.md b/utils/collection/README.md
index 355a9b8..4c5f566 100644
--- a/utils/collection/README.md
+++ b/utils/collection/README.md
@@ -147,7 +147,7 @@ collection 定义了各种对于集合操作有用的各种函数
**示例代码:**
-slice 克隆后将会得到一个新的 slice result,而 result 和 slice 将不会有任何关联,但是如果 slice 中的元素是引用类型,那么 result 中的元素将会和 slice 中的元素指向同一个地址
+在该示例中,将 slice 克隆后将会得到一个新的 slice result,而 result 和 slice 将不会有任何关联,但是如果 slice 中的元素是引用类型,那么 result 中的元素将会和 slice 中的元素指向同一个地址
- 示例中的结果将会输出 [1 2 3]
@@ -202,7 +202,7 @@ func TestCloneSlice(t *testing.T) {
**示例代码:**
-map 克隆后将会得到一个新的 map result,而 result 和 map 将不会有任何关联,但是如果 map 中的元素是引用类型,那么 result 中的元素将会和 map 中的元素指向同一个地址
+在该示例中,将 map 克隆后将会得到一个新的 map result,而 result 和 map 将不会有任何关联,但是如果 map 中的元素是引用类型,那么 result 中的元素将会和 map 中的元素指向同一个地址
- 示例中的结果将会输出 3
@@ -257,7 +257,7 @@ func TestCloneMap(t *testing.T) {
**示例代码:**
-slice 克隆为 2 个新的 slice,将会得到一个新的 slice result,而 result 和 slice 将不会有任何关联,但是如果 slice 中的元素是引用类型,那么 result 中的元素将会和 slice 中的元素指向同一个地址
+通过将 slice 克隆为 2 个新的 slice,将会得到一个新的 slice result,而 result 和 slice 将不会有任何关联,但是如果 slice 中的元素是引用类型,那么 result 中的元素将会和 slice 中的元素指向同一个地址
- result 的结果为 [[1 2 3] [1 2 3]]
- 示例中的结果将会输出 2
@@ -319,7 +319,7 @@ func TestCloneSliceN(t *testing.T) {
**示例代码:**
-map 克隆为 2 个新的 map,将会得到一个新的 map result,而 result 和 map 将不会有任何关联,但是如果 map 中的元素是引用类型,那么 result 中的元素将会和 map 中的元素指向同一个地址
+通过将 map 克隆为 2 个新的 map,将会得到一个新的 map result,而 result 和 map 将不会有任何关联,但是如果 map 中的元素是引用类型,那么 result 中的元素将会和 map 中的元素指向同一个地址
- result 的结果为 [map[1:1 2:2 3:3] map[1:1 2:2 3:3]] `无序的 Key-Value 对`
- 示例中的结果将会输出 2
@@ -382,7 +382,7 @@ func TestCloneMapN(t *testing.T) {
**示例代码:**
-slice 克隆为 2 个新的 slice,将会得到一个新的 slice result,而 result 和 slice 将不会有任何关联,但是如果 slice 中的元素是引用类型,那么 result 中的元素将会和 slice 中的元素指向同一个地址
+通过将多个 slice 克隆为 2 个新的 slice,将会得到一个新的 slice result,而 result 和 slice 将不会有任何关联,但是如果 slice 中的元素是引用类型,那么 result 中的元素将会和 slice 中的元素指向同一个地址
- result 的结果为 [[1 2 3] [1 2 3]]
@@ -441,7 +441,7 @@ func TestCloneSlices(t *testing.T) {
**示例代码:**
-map 克隆为 2 个新的 map,将会得到一个新的 map result,而 result 和 map 将不会有任何关联,但是如果 map 中的元素是引用类型,那么 result 中的元素将会和 map 中的元素指向同一个地址
+通过将多个 map 克隆为 2 个新的 map,将会得到一个新的 map result,而 result 和 map 将不会有任何关联,但是如果 map 中的元素是引用类型,那么 result 中的元素将会和 map 中的元素指向同一个地址
- result 的结果为 [map[1:1 2:2 3:3] map[1:1 2:2 3:3]] `无序的 Key-Value 对`
diff --git a/utils/collection/listings/README.md b/utils/collection/listings/README.md
index 6d0a0dd..6ff9276 100644
--- a/utils/collection/listings/README.md
+++ b/utils/collection/listings/README.md
@@ -65,17 +65,29 @@ type Matrix[V any] struct {
data []V
}
```
+
+
#### func (*Matrix) Get(index ...int) *V
> 获取矩阵中给定索引的元素。
+
***
+
+
#### func (*Matrix) Set(index []int, value V)
> 设置矩阵中给定索引的元素。
+
***
+
+
#### func (*Matrix) Dimensions() []int
> 返回矩阵的维度大小。
+
***
+
+
#### func (*Matrix) Clear()
> 清空矩阵。
+
***
### PagedSlice `STRUCT`
@@ -88,23 +100,41 @@ type PagedSlice[T any] struct {
lenLast int
}
```
+
+
#### func (*PagedSlice) Add(value T)
> 添加一个元素到 PagedSlice 中。
+
***
+
+
#### func (*PagedSlice) Get(index int) *T
> 获取 PagedSlice 中给定索引的元素。
+
***
+
+
#### func (*PagedSlice) Set(index int, value T)
> 设置 PagedSlice 中给定索引的元素。
+
***
+
+
#### func (*PagedSlice) Len() int
> 返回 PagedSlice 中元素的数量。
+
***
+
+
#### func (*PagedSlice) Clear()
> 清空 PagedSlice。
+
***
+
+
#### func (*PagedSlice) Range(f func (index int, value T) bool)
> 迭代 PagedSlice 中的所有元素。
+
***
### PrioritySlice `STRUCT`
@@ -114,17 +144,29 @@ type PrioritySlice[V any] struct {
items []*priorityItem[V]
}
```
+
+
#### func (*PrioritySlice) Len() int
> 返回切片长度
+
***
+
+
#### func (*PrioritySlice) Cap() int
> 返回切片容量
+
***
+
+
#### func (*PrioritySlice) Clear()
> 清空切片
+
***
+
+
#### func (*PrioritySlice) Append(v V, p int)
> 添加元素
+
查看 / 收起单元测试
@@ -145,44 +187,83 @@ func TestPrioritySlice_Append(t *testing.T) {
***
+
+
#### func (*PrioritySlice) Appends(priority int, vs ...V)
> 添加元素
+
***
+
+
#### func (*PrioritySlice) Get(index int) ( V, int)
> 获取元素
+
***
+
+
#### func (*PrioritySlice) GetValue(index int) V
> 获取元素值
+
***
+
+
#### func (*PrioritySlice) GetPriority(index int) int
> 获取元素优先级
+
***
+
+
#### func (*PrioritySlice) Set(index int, value V, priority int)
> 设置元素
+
***
+
+
#### func (*PrioritySlice) SetValue(index int, value V)
> 设置元素值
+
***
+
+
#### func (*PrioritySlice) SetPriority(index int, priority int)
> 设置元素优先级
+
***
+
+
#### func (*PrioritySlice) Action(action func (items []*priorityItem[V]) []*priorityItem[V])
> 直接操作切片,如果返回值不为 nil,则替换切片
+
***
+
+
#### func (*PrioritySlice) Range(action func (index int, item *priorityItem[V]) bool)
> 遍历切片,如果返回值为 false,则停止遍历
+
***
+
+
#### func (*PrioritySlice) RangeValue(action func (index int, value V) bool)
> 遍历切片值,如果返回值为 false,则停止遍历
+
***
+
+
#### func (*PrioritySlice) RangePriority(action func (index int, priority int) bool)
> 遍历切片优先级,如果返回值为 false,则停止遍历
+
***
+
+
#### func (*PrioritySlice) Slice() []V
-> 返回切片
+> SyncSlice 返回切片
+
***
+
+
#### func (*PrioritySlice) String() string
> 返回切片字符串
+
***
### SyncSlice `STRUCT`
@@ -193,17 +274,38 @@ type SyncSlice[V any] struct {
data []V
}
```
+
+
#### func (*SyncSlice) Get(index int) V
+
***
+
+
#### func (*SyncSlice) GetWithRange(start int, end int) []V
+
***
+
+
#### func (*SyncSlice) Set(index int, value V)
+
***
+
+
#### func (*SyncSlice) Append(values ...V)
+
***
+
+
#### func (*SyncSlice) Release()
+
***
+
+
#### func (*SyncSlice) Clear()
+
***
+
+
#### func (*SyncSlice) GetData() []V
+
***
diff --git a/utils/collection/mappings/README.md b/utils/collection/mappings/README.md
index 4084040..17546e1 100644
--- a/utils/collection/mappings/README.md
+++ b/utils/collection/mappings/README.md
@@ -46,55 +46,109 @@ type SyncMap[K comparable, V any] struct {
atom bool
}
```
+
+
#### func (*SyncMap) Set(key K, value V)
> 设置一个值
+
***
+
+
#### func (*SyncMap) Get(key K) V
> 获取一个值
+
***
+
+
#### func (*SyncMap) Atom(handle func (m map[K]V))
> 原子操作
+
***
+
+
#### func (*SyncMap) Exist(key K) bool
> 判断是否存在
+
***
+
+
#### func (*SyncMap) GetExist(key K) ( V, bool)
> 获取一个值并判断是否存在
+
***
+
+
#### func (*SyncMap) Delete(key K)
> 删除一个值
+
***
+
+
#### func (*SyncMap) DeleteGet(key K) V
> 删除一个值并返回
+
***
+
+
#### func (*SyncMap) DeleteGetExist(key K) ( V, bool)
> 删除一个值并返回是否存在
+
***
+
+
#### func (*SyncMap) DeleteExist(key K) bool
> 删除一个值并返回是否存在
+
***
+
+
#### func (*SyncMap) Clear()
> 清空
+
***
+
+
#### func (*SyncMap) ClearHandle(handle func (key K, value V))
> 清空并处理
+
***
+
+
#### func (*SyncMap) Range(handle func (key K, value V) bool)
> 遍历所有值,如果 handle 返回 true 则停止遍历
+
***
+
+
#### func (*SyncMap) Keys() []K
> 获取所有的键
+
***
+
+
#### func (*SyncMap) Slice() []V
> 获取所有的值
+
***
+
+
#### func (*SyncMap) Map() map[K]V
> 转换为普通 map
+
***
+
+
#### func (*SyncMap) Size() int
> 获取数量
+
***
+
+
#### func (*SyncMap) MarshalJSON() ( []byte, error)
+
***
+
+
#### func (*SyncMap) UnmarshalJSON(bytes []byte) error
+
***
diff --git a/utils/combination/README.md b/utils/combination/README.md
index 089fb4d..ec27303 100644
--- a/utils/combination/README.md
+++ b/utils/combination/README.md
@@ -44,7 +44,7 @@ combination 包提供了一些实用的组合函数。
|[WithValidatorHandleContinuousNot](#WithValidatorHandleContinuousNot)|校验组合成员是否不连续
|[WithValidatorHandleGroupContinuous](#WithValidatorHandleGroupContinuous)|校验组合成员是否能够按类型分组并且连续
|[WithValidatorHandleGroupContinuousN](#WithValidatorHandleGroupContinuousN)|校验组合成员是否能够按分组为 n 组类型并且连续
-|[WithValidatorHandleNCarryM](#WithValidatorHandleNCarryM)| 校验组合成员是否匹配 N 携带相同的 M 的组合
+|[WithValidatorHandleNCarryM](#WithValidatorHandleNCarryM)|校验组合成员是否匹配 N 携带相同的 M 的组合
|[WithValidatorHandleNCarryIndependentM](#WithValidatorHandleNCarryIndependentM)|校验组合成员是否匹配 N 携带独立的 M 的组合
@@ -227,7 +227,7 @@ combination 包提供了一些实用的组合函数。
***
#### func WithValidatorHandleNCarryM\[T Item, E generic.Ordered\](n int, m int, getType func (item T) E) ValidatorOption[T]
-> 校验组合成员是否匹配 N 携带相同的 M 的组合
+> 校验组合成员是否匹配 N 携带相同的 M 的组合
> - n: 组合中元素的数量,表示需要匹配的组合数量,n 的类型需要全部相同
> - m: 组合中元素的数量,表示需要匹配的组合数量,m 的类型需要全部相同
> - getType: 用于获取组合中元素的类型,用于判断是否相同
@@ -251,23 +251,41 @@ type Combination[T Item] struct {
priority []string
}
```
+
+
#### func (*Combination) NewMatcher(name string, options ...MatcherOption[T]) *Combination[T]
> 添加一个新的匹配器
+
***
+
+
#### func (*Combination) AddMatcher(name string, matcher *Matcher[T]) *Combination[T]
> 添加一个匹配器
+
***
+
+
#### func (*Combination) RemoveMatcher(name string) *Combination[T]
> 移除一个匹配器
+
***
+
+
#### func (*Combination) Combinations(items []T) (result [][]T)
> 从一组数据中提取所有符合匹配器规则的组合
+
***
+
+
#### func (*Combination) CombinationsToName(items []T) (result map[string][][]T)
> 从一组数据中提取所有符合匹配器规则的组合,并返回匹配器名称
+
***
+
+
#### func (*Combination) Best(items []T) (name string, result []T)
> 从一组数据中提取符合匹配器规则的最佳组合
+
查看 / 收起单元测试
@@ -302,8 +320,11 @@ func TestCombination_Best(t *testing.T) {
***
+
+
#### func (*Combination) Worst(items []T) (name string, result []T)
> 从一组数据中提取符合匹配器规则的最差组合
+
***
### Option `STRUCT`
@@ -326,18 +347,30 @@ type Matcher[T Item] struct {
filter []func(items []T) [][]T
}
```
+
+
#### func (*Matcher) AddFilter(filter func (items []T) [][]T)
> 添加一个筛选器
> - 筛选器用于对组合进行筛选,返回一个二维数组,每个数组内的元素都是一个组合
+
***
+
+
#### func (*Matcher) Combinations(items []T) [][]T
> 从一组数据中提取所有符合筛选器规则的组合
+
***
+
+
#### func (*Matcher) Best(items []T) []T
> 从一组数据中提取符筛选器规则的最佳组合
+
***
+
+
#### func (*Matcher) Worst(items []T) []T
> 从一组数据中提取符筛选器规则的最差组合
+
***
### MatcherOption `STRUCT`
@@ -353,8 +386,11 @@ type Validator[T Item] struct {
vh []func(items []T) bool
}
```
+
+
#### func (*Validator) Validate(items []T) bool
> 校验组合是否符合要求
+
查看 / 收起单元测试
diff --git a/utils/deck/README.md b/utils/deck/README.md
index 4dd3712..b34c7f8 100644
--- a/utils/deck/README.md
+++ b/utils/deck/README.md
@@ -52,26 +52,47 @@ type Deck[I Item] struct {
sort []int64
}
```
+
+
#### func (*Deck) AddGroup(group *Group[I])
> 将一个组添加到甲板中
+
***
+
+
#### func (*Deck) RemoveGroup(guid int64)
> 移除甲板中的一个组
+
***
+
+
#### func (*Deck) GetCount() int
> 获取甲板中的组数量
+
***
+
+
#### func (*Deck) GetGroups() map[int64]*Group[I]
> 获取所有组
+
***
+
+
#### func (*Deck) GetGroupsSlice() []*Group[I]
> 获取所有组
+
***
+
+
#### func (*Deck) GetNext(guid int64) *Group[I]
> 获取特定组的下一个组
+
***
+
+
#### func (*Deck) GetPrev(guid int64) *Group[I]
> 获取特定组的上一个组
+
***
### Group `STRUCT`
@@ -83,50 +104,95 @@ type Group[I Item] struct {
items []I
}
```
+
+
#### func (*Group) GetGuid() int64
> 获取组的 guid
+
***
+
+
#### func (*Group) Fill()
> 将该组的数据填充为 WithGroupFillHandle 中设置的内容
+
***
+
+
#### func (*Group) Pop() (item I)
> 从顶部获取一个内容
+
***
+
+
#### func (*Group) PopN(n int) (items []I)
> 从顶部获取指定数量的内容
+
***
+
+
#### func (*Group) PressOut() (item I)
> 从底部压出一个内容
+
***
+
+
#### func (*Group) PressOutN(n int) (items []I)
> 从底部压出指定数量的内容
+
***
+
+
#### func (*Group) Push(item I)
> 向顶部压入一个内容
+
***
+
+
#### func (*Group) PushN(items []I)
> 向顶部压入指定数量的内容
+
***
+
+
#### func (*Group) Insert(item I)
> 向底部插入一个内容
+
***
+
+
#### func (*Group) InsertN(items []I)
> 向底部插入指定数量的内容
+
***
+
+
#### func (*Group) Pull(index int) (item I)
> 从特定位置拔出一个内容
+
***
+
+
#### func (*Group) Thrust(index int, item I)
> 向特定位置插入一个内容
+
***
+
+
#### func (*Group) IsFree() bool
> 检查组是否为空
+
***
+
+
#### func (*Group) GetCount() int
> 获取组中剩余的内容数量
+
***
+
+
#### func (*Group) GetItem(index int) I
> 获取组中的指定内容
+
***
### Item `INTERFACE`
diff --git a/utils/fsm/README.md b/utils/fsm/README.md
index ab18674..12625fb 100644
--- a/utils/fsm/README.md
+++ b/utils/fsm/README.md
@@ -85,32 +85,59 @@ type FSM[State comparable, Data any] struct {
exitAfterEventHandles map[State][]func(state *FSM[State, Data])
}
```
+
+
#### func (*FSM) Update()
> 触发当前状态
+
***
+
+
#### func (*FSM) Register(state State, options ...Option[State, Data])
> 注册状态
+
***
+
+
#### func (*FSM) Unregister(state State)
> 反注册状态
+
***
+
+
#### func (*FSM) HasState(state State) bool
> 检查状态机是否存在特定状态
+
***
+
+
#### func (*FSM) Change(state State)
> 改变状态机状态到新的状态
+
***
+
+
#### func (*FSM) Current() (state State)
> 获取当前状态
+
***
+
+
#### func (*FSM) GetData() Data
> 获取状态机数据
+
***
+
+
#### func (*FSM) IsZero() bool
> 检查状态机是否无状态
+
***
+
+
#### func (*FSM) PrevIsZero() bool
> 检查状态机上一个状态是否无状态
+
***
### Option `STRUCT`
diff --git a/utils/generator/astgo/README.md b/utils/generator/astgo/README.md
index 3d775cb..3433548 100644
--- a/utils/generator/astgo/README.md
+++ b/utils/generator/astgo/README.md
@@ -93,7 +93,10 @@ type File struct {
Comment *Comment
}
```
+
+
#### func (*File) Package() string
+
***
### Function `STRUCT`
@@ -114,7 +117,10 @@ type Function struct {
Test bool
}
```
+
+
#### func (*Function) Code() string
+
***
### Package `STRUCT`
@@ -128,19 +134,40 @@ type Package struct {
Functions map[string]*Function
}
```
+
+
#### func (*Package) StructFunc(name string) []*Function
+
***
+
+
#### func (*Package) PackageFunc() []*Function
+
***
+
+
#### func (*Package) Structs() []*Struct
+
***
+
+
#### func (*Package) FileComments() *Comment
+
***
+
+
#### func (*Package) GetUnitTest(f *Function) *Function
+
***
+
+
#### func (*Package) GetExampleTest(f *Function) *Function
+
***
+
+
#### func (*Package) GetBenchmarkTest(f *Function) *Function
+
***
### Struct `STRUCT`
diff --git a/utils/generator/genreadme/README.md b/utils/generator/genreadme/README.md
index 04c96d0..cbfe512 100644
--- a/utils/generator/genreadme/README.md
+++ b/utils/generator/genreadme/README.md
@@ -44,7 +44,10 @@ type Builder struct {
o string
}
```
+
+
#### func (*Builder) Generate() error
+
查看 / 收起单元测试
diff --git a/utils/geometry/README.md b/utils/geometry/README.md
index ad08194..1f5b0d0 100644
--- a/utils/geometry/README.md
+++ b/utils/geometry/README.md
@@ -878,23 +878,41 @@ type Circle[V generic.SignedNumber] struct {
Shape[V]
}
```
+
+
#### func (Circle) Radius() V
> 获取圆形半径
+
***
+
+
#### func (Circle) Centroid() Point[V]
> 获取圆形质心位置
+
***
+
+
#### func (Circle) Overlap(circle Circle[V]) bool
> 与另一个圆是否发生重叠
+
***
+
+
#### func (Circle) Area() V
> 获取圆形面积
+
***
+
+
#### func (Circle) Length() V
> 获取圆的周长
+
***
+
+
#### func (Circle) CentroidDistance(circle Circle[V]) V
> 计算与另一个圆的质心距离
+
***
### FloorPlan `STRUCT`
@@ -902,17 +920,29 @@ type Circle[V generic.SignedNumber] struct {
```go
type FloorPlan []string
```
+
+
#### func (FloorPlan) IsFree(point Point[int]) bool
> 检查位置是否为空格
+
***
+
+
#### func (FloorPlan) IsInBounds(point Point[int]) bool
> 检查位置是否在边界内
+
***
+
+
#### func (FloorPlan) Put(point Point[int], c rune)
> 设置平面图特定位置的字符
+
***
+
+
#### func (FloorPlan) String() string
> 获取平面图结果
+
***
### Direction `STRUCT`
@@ -926,17 +956,29 @@ type Direction uint8
```go
type LineSegment[V generic.SignedNumber] [2]Point[V]
```
+
+
#### func (LineSegment) GetPoints() [2]Point[V]
> 获取该线段的两个点
+
***
+
+
#### func (LineSegment) GetStart() Point[V]
> 获取该线段的开始位置
+
***
+
+
#### func (LineSegment) GetEnd() Point[V]
> 获取该线段的结束位置
+
***
+
+
#### func (LineSegment) GetLength() V
> 获取该线段的长度
+
***
### LineSegmentCap `STRUCT`
@@ -947,7 +989,10 @@ type LineSegmentCap[V generic.SignedNumber, Data any] struct {
Data Data
}
```
+
+
#### func (*LineSegmentCap) GetData() Data
+
***
### Point `STRUCT`
@@ -955,53 +1000,101 @@ type LineSegmentCap[V generic.SignedNumber, Data any] struct {
```go
type Point[V generic.SignedNumber] [2]V
```
+
+
#### func (Point) GetX() V
> 返回该点的 x 坐标
+
***
+
+
#### func (Point) GetY() V
> 返回该点的 y 坐标
+
***
+
+
#### func (Point) GetXY() (x V, y V)
> 返回该点的 x、y 坐标
+
***
+
+
#### func (Point) GetPos(width V) V
> 返回该点位于特定宽度的二维数组的顺序位置
+
***
+
+
#### func (Point) GetOffset(x V, y V) Point[V]
> 获取偏移后的新坐标
+
***
+
+
#### func (Point) Negative() bool
> 返回该点是否是一个负数坐标
+
***
+
+
#### func (Point) OutOf(minWidth V, minHeight V, maxWidth V, maxHeight V) bool
> 返回该点在特定宽高下是否越界f
+
***
+
+
#### func (Point) Equal(point Point[V]) bool
> 返回两个点是否相等
+
***
+
+
#### func (Point) Copy() Point[V]
> 复制一个点位置
+
***
+
+
#### func (Point) Add(point Point[V]) Point[V]
> 得到加上 point 后的点
+
***
+
+
#### func (Point) Sub(point Point[V]) Point[V]
> 得到减去 point 后的点
+
***
+
+
#### func (Point) Mul(point Point[V]) Point[V]
> 得到乘以 point 后的点
+
***
+
+
#### func (Point) Div(point Point[V]) Point[V]
> 得到除以 point 后的点
+
***
+
+
#### func (Point) Abs() Point[V]
> 返回位置的绝对值
+
***
+
+
#### func (Point) Max(point Point[V]) Point[V]
> 返回两个位置中每个维度的最大值组成的新的位置
+
***
+
+
#### func (Point) Min(point Point[V]) Point[V]
> 返回两个位置中每个维度的最小值组成的新的位置
+
***
### PointCap `STRUCT`
@@ -1012,8 +1105,11 @@ type PointCap[V generic.SignedNumber, D any] struct {
Data D
}
```
+
+
#### func (PointCap) GetData() D
> 获取数据
+
***
### Shape `STRUCT`
@@ -1021,8 +1117,11 @@ type PointCap[V generic.SignedNumber, D any] struct {
```go
type Shape[V generic.SignedNumber] []Point[V]
```
+
+
#### func (Shape) Points() []Point[V]
> 获取这个形状的所有点
+
**示例代码:**
```go
@@ -1059,8 +1158,11 @@ func TestShape_Points(t *testing.T) {
***
+
+
#### func (Shape) PointCount() int
> 获取这个形状的点数量
+
**示例代码:**
```go
@@ -1092,15 +1194,24 @@ func TestShape_PointCount(t *testing.T) {
***
+
+
#### func (Shape) Contains(point Point[V]) bool
> 返回该形状中是否包含点
+
***
+
+
#### func (Shape) ToCircle() Circle[V]
> 将形状转换为圆形进行处理
> - 当形状非圆形时将会产生意外情况
+
***
+
+
#### func (Shape) String() string
> 将该形状转换为可视化的字符串进行返回
+
**示例代码:**
```go
@@ -1133,6 +1244,8 @@ func TestShape_String(t *testing.T) {
***
+
+
#### func (Shape) ShapeSearch(options ...ShapeSearchOption) (result []Shape[V])
> 获取该形状中包含的所有图形组合及其位置
> - 需要注意的是,即便图形最终表示为相同的,但是只要位置组合顺序不同,那么也将被认定为一种图形组合
@@ -1140,6 +1253,7 @@ func TestShape_String(t *testing.T) {
> - 返回的坐标为原始形状的坐标
>
> 可通过可选项对搜索结果进行过滤
+
**示例代码:**
```go
@@ -1155,12 +1269,18 @@ func ExampleShape_ShapeSearch() {
```
***
+
+
#### func (Shape) Edges() (edges []LineSegment[V])
> 获取该形状每一条边
> - 该形状需要最少由3个点组成,否则将不会返回任意一边
+
***
+
+
#### func (Shape) IsPointOnEdge(point Point[V]) bool
> 检查点是否在该形状的一条边上
+
***
### ShapeSearchOption `STRUCT`
diff --git a/utils/geometry/astar/README.md b/utils/geometry/astar/README.md
index 63809a3..b5e8753 100644
--- a/utils/geometry/astar/README.md
+++ b/utils/geometry/astar/README.md
@@ -86,5 +86,8 @@ type Graph[Node comparable] interface {
Neighbours(node Node) []Node
}
```
+
+
#### func (Graph) Neighbours(point geometry.Point[int]) []geometry.Point[int]
+
***
diff --git a/utils/geometry/dp/README.md b/utils/geometry/dp/README.md
index 1eaf3ce..bbec081 100644
--- a/utils/geometry/dp/README.md
+++ b/utils/geometry/dp/README.md
@@ -81,29 +81,47 @@ type DistributionPattern[Item any] struct {
usePos bool
}
```
+
+
#### func (*DistributionPattern) GetLinks(pos int) (result []Link[Item])
> 获取关联的成员
> - 其中包含传入的 pos 成员
+
***
+
+
#### func (*DistributionPattern) HasLink(pos int) bool
> 检查一个位置是否包含除它本身外的其他关联成员
+
***
+
+
#### func (*DistributionPattern) LoadMatrix(matrix [][]Item)
> 通过二维矩阵加载分布图
> - 通过该函数加载的分布图使用的矩阵是复制后的矩阵,因此无法直接通过刷新(Refresh)来更新分布关系
> - 需要通过直接刷新的方式请使用 LoadMatrixWithPos
+
***
+
+
#### func (*DistributionPattern) LoadMatrixWithPos(width int, matrix []Item)
> 通过二维矩阵加载分布图
+
***
+
+
#### func (*DistributionPattern) Refresh(pos int)
> 刷新特定位置的分布关系
> - 由于 LoadMatrix 的矩阵是复制后的矩阵,所以任何外部的改动都不会影响到分布图的变化,在这种情况下,刷新将没有任何意义
> - 需要通过直接刷新的方式请使用 LoadMatrixWithPos 加载矩阵,或者通过 RefreshWithItem 函数进行刷新
+
***
+
+
#### func (*DistributionPattern) RefreshWithItem(pos int, item Item)
> 通过特定的成员刷新特定位置的分布关系
> - 如果矩阵通过 LoadMatrixWithPos 加载,将会重定向至 Refresh
+
***
### Link `STRUCT`
diff --git a/utils/geometry/matrix/README.md b/utils/geometry/matrix/README.md
index c8972d1..7ed208c 100644
--- a/utils/geometry/matrix/README.md
+++ b/utils/geometry/matrix/README.md
@@ -47,52 +47,100 @@ type Matrix[T any] struct {
m []T
}
```
+
+
#### func (*Matrix) GetWidth() int
> 获取二维矩阵宽度
+
***
+
+
#### func (*Matrix) GetHeight() int
> 获取二维矩阵高度
+
***
+
+
#### func (*Matrix) GetWidth2Height() (width int, height int)
> 获取二维矩阵的宽度和高度
+
***
+
+
#### func (*Matrix) GetMatrix() [][]T
> 获取二维矩阵
> - 通常建议使用 GetMatrixWithPos 进行处理这样将拥有更高的效率
+
***
+
+
#### func (*Matrix) GetMatrixWithPos() []T
> 获取顺序的矩阵
+
***
+
+
#### func (*Matrix) Get(x int, y int) (value T)
> 获取特定坐标的内容
+
***
+
+
#### func (*Matrix) GetExist(x int, y int) (value T, exist bool)
> 获取特定坐标的内容,如果不存在则返回 false
+
***
+
+
#### func (*Matrix) GetWithPos(pos int) (value T)
> 获取特定坐标的内容
+
***
+
+
#### func (*Matrix) Set(x int, y int, data T)
> 设置特定坐标的内容
+
***
+
+
#### func (*Matrix) SetWithPos(pos int, data T)
> 设置特定坐标的内容
+
***
+
+
#### func (*Matrix) Swap(x1 int, y1 int, x2 int, y2 int)
> 交换两个位置的内容
+
***
+
+
#### func (*Matrix) SwapWithPos(pos1 int, pos2 int)
> 交换两个位置的内容
+
***
+
+
#### func (*Matrix) TrySwap(x1 int, y1 int, x2 int, y2 int, expressionHandle func (matrix *Matrix[T]) bool)
> 尝试交换两个位置的内容,交换后不满足表达式时进行撤销
+
***
+
+
#### func (*Matrix) TrySwapWithPos(pos1 int, pos2 int, expressionHandle func (matrix *Matrix[T]) bool)
> 尝试交换两个位置的内容,交换后不满足表达式时进行撤销
+
***
+
+
#### func (*Matrix) FillFull(generateHandle func (x int) T)
> 根据提供的生成器填充整个矩阵
+
***
+
+
#### func (*Matrix) FillFullWithPos(generateHandle func (pos int) T)
> 根据提供的生成器填充整个矩阵
+
***
diff --git a/utils/geometry/navmesh/README.md b/utils/geometry/navmesh/README.md
index af138da..301e2ed 100644
--- a/utils/geometry/navmesh/README.md
+++ b/utils/geometry/navmesh/README.md
@@ -63,9 +63,14 @@ type NavMesh[V generic.SignedNumber] struct {
meshShrinkAmount V
}
```
+
+
#### func (*NavMesh) Neighbours(node *shape[V]) []*shape[V]
> 实现 astar.Graph 的接口,用于向 A* 算法提供相邻图形
+
***
+
+
#### func (*NavMesh) Find(point geometry.Point[V], maxDistance V) (distance V, findPoint geometry.Point[V], findShape geometry.Shape[V])
> 用于在 NavMesh 中查找离给定点最近的形状,并返回距离、找到的点和找到的形状。
>
@@ -83,7 +88,10 @@ type NavMesh[V generic.SignedNumber] struct {
> - 如果给定点不在任何形状内部或者形状的边上,将计算给定点到每个形状的距离,并找到最近的形状和对应的点。
> - 距离的计算采用几何学中的投影点到形状的距离。
> - 函数返回离给定点最近的形状的距离、找到的点和找到的形状。
+
***
+
+
#### func (*NavMesh) FindPath(start geometry.Point[V], end geometry.Point[V]) (result []geometry.Point[V])
> 函数用于在 NavMesh 中查找从起点到终点的路径,并返回路径上的点序列。
>
@@ -99,6 +107,7 @@ type NavMesh[V generic.SignedNumber] struct {
> - 如果起点或终点不在任何形状内部,且 NavMesh 的 meshShrinkAmount 大于0,则会考虑缩小的形状。
> - 使用 A* 算法在 NavMesh 上搜索从起点形状到终点形状的最短路径。
> - 使用漏斗算法对路径进行优化,以得到最终的路径点序列。
+
**示例代码:**
```go
diff --git a/utils/hub/README.md b/utils/hub/README.md
index e518202..a89558d 100644
--- a/utils/hub/README.md
+++ b/utils/hub/README.md
@@ -100,8 +100,11 @@ type ObjectPool[T any] struct {
releaser func(data T)
}
```
+
+
#### func (*ObjectPool) Get() T
> 获取一个对象
+
查看 / 收起单元测试
@@ -137,8 +140,11 @@ func TestObjectPool_Get(t *testing.T) {
***
+
+
#### func (*ObjectPool) Release(data T)
> 将使用完成的对象放回缓冲区
+
查看 / 收起单元测试
diff --git a/utils/huge/README.md b/utils/huge/README.md
index 1f8e8a6..c79ece4 100644
--- a/utils/huge/README.md
+++ b/utils/huge/README.md
@@ -62,61 +62,124 @@
```go
type Float big.Float
```
+
+
#### func (*Float) Copy() *Float
+
***
+
+
#### func (*Float) Set(i *Float) *Float
+
***
+
+
#### func (*Float) IsZero() bool
+
***
+
+
#### func (*Float) ToBigFloat() *big.Float
+
***
+
+
#### func (*Float) Cmp(i *Float) int
> 比较,当 slf > i 时返回 1,当 slf < i 时返回 -1,当 slf == i 时返回 0
+
***
+
+
#### func (*Float) GreaterThan(i *Float) bool
> 大于
+
***
+
+
#### func (*Float) GreaterThanOrEqualTo(i *Float) bool
> 大于或等于
+
***
+
+
#### func (*Float) LessThan(i *Float) bool
> 小于
+
***
+
+
#### func (*Float) LessThanOrEqualTo(i *Float) bool
> 小于或等于
+
***
+
+
#### func (*Float) EqualTo(i *Float) bool
> 等于
+
***
+
+
#### func (*Float) Float64() float64
+
***
+
+
#### func (*Float) String() string
+
***
+
+
#### func (*Float) Add(i *Float) *Float
+
***
+
+
#### func (*Float) Sub(i *Float) *Float
+
***
+
+
#### func (*Float) Mul(i *Float) *Float
+
***
+
+
#### func (*Float) Div(i *Float) *Float
+
***
+
+
#### func (*Float) Sqrt() *Float
> 平方根
+
***
+
+
#### func (*Float) Abs() *Float
> 返回数字的绝对值
+
***
+
+
#### func (*Float) Sign() int
> 返回数字的符号
> - 1:正数
> - 0:零
> - -1:负数
+
***
+
+
#### func (*Float) IsPositive() bool
> 是否为正数
+
***
+
+
#### func (*Float) IsNegative() bool
> 是否为负数
+
***
### Int `STRUCT`
@@ -124,258 +187,591 @@ type Float big.Float
```go
type Int big.Int
```
+
+
#### func (*Int) Copy() *Int
+
***
+
+
#### func (*Int) Set(i *Int) *Int
+
***
+
+
#### func (*Int) SetInt(i int) *Int
+
***
+
+
#### func (*Int) SetInt8(i int8) *Int
+
***
+
+
#### func (*Int) SetInt16(i int16) *Int
+
***
+
+
#### func (*Int) SetInt32(i int32) *Int
+
***
+
+
#### func (*Int) SetInt64(i int64) *Int
+
***
+
+
#### func (*Int) SetUint(i uint) *Int
+
***
+
+
#### func (*Int) SetUint8(i uint8) *Int
+
***
+
+
#### func (*Int) SetUint16(i uint16) *Int
+
***
+
+
#### func (*Int) SetUint32(i uint32) *Int
+
***
+
+
#### func (*Int) SetUint64(i uint64) *Int
+
***
+
+
#### func (*Int) IsZero() bool
+
***
+
+
#### func (*Int) ToBigint() *big.Int
+
***
+
+
#### func (*Int) Cmp(i *Int) int
> 比较,当 slf > i 时返回 1,当 slf < i 时返回 -1,当 slf == i 时返回 0
+
***
+
+
#### func (*Int) GreaterThan(i *Int) bool
> 大于
+
***
+
+
#### func (*Int) GreaterThanOrEqualTo(i *Int) bool
> 大于或等于
+
***
+
+
#### func (*Int) LessThan(i *Int) bool
> 小于
+
***
+
+
#### func (*Int) LessThanOrEqualTo(i *Int) bool
> 小于或等于
+
***
+
+
#### func (*Int) EqualTo(i *Int) bool
> 等于
+
***
+
+
#### func (*Int) Int64() int64
+
***
+
+
#### func (*Int) String() string
+
***
+
+
#### func (*Int) Add(i *Int) *Int
+
***
+
+
#### func (*Int) AddInt(i int) *Int
+
***
+
+
#### func (*Int) AddInt8(i int8) *Int
+
***
+
+
#### func (*Int) AddInt16(i int16) *Int
+
***
+
+
#### func (*Int) AddInt32(i int32) *Int
+
***
+
+
#### func (*Int) AddInt64(i int64) *Int
+
***
+
+
#### func (*Int) AddUint(i uint) *Int
+
***
+
+
#### func (*Int) AddUint8(i uint8) *Int
+
***
+
+
#### func (*Int) AddUint16(i uint16) *Int
+
***
+
+
#### func (*Int) AddUint32(i uint32) *Int
+
***
+
+
#### func (*Int) AddUint64(i uint64) *Int
+
***
+
+
#### func (*Int) Mul(i *Int) *Int
+
***
+
+
#### func (*Int) MulInt(i int) *Int
+
***
+
+
#### func (*Int) MulInt8(i int8) *Int
+
***
+
+
#### func (*Int) MulInt16(i int16) *Int
+
***
+
+
#### func (*Int) MulInt32(i int32) *Int
+
***
+
+
#### func (*Int) MulInt64(i int64) *Int
+
***
+
+
#### func (*Int) MulUint(i uint) *Int
+
***
+
+
#### func (*Int) MulUint8(i uint8) *Int
+
***
+
+
#### func (*Int) MulUint16(i uint16) *Int
+
***
+
+
#### func (*Int) MulUint32(i uint32) *Int
+
***
+
+
#### func (*Int) MulUint64(i uint64) *Int
+
***
+
+
#### func (*Int) Sub(i *Int) *Int
+
***
+
+
#### func (*Int) SubInt(i int) *Int
+
***
+
+
#### func (*Int) SubInt8(i int8) *Int
+
***
+
+
#### func (*Int) SubInt16(i int16) *Int
+
***
+
+
#### func (*Int) SubInt32(i int32) *Int
+
***
+
+
#### func (*Int) SubInt64(i int64) *Int
+
***
+
+
#### func (*Int) SubUint(i uint) *Int
+
***
+
+
#### func (*Int) SubUint8(i uint8) *Int
+
***
+
+
#### func (*Int) SubUint16(i uint16) *Int
+
***
+
+
#### func (*Int) SubUint32(i uint32) *Int
+
***
+
+
#### func (*Int) SubUint64(i uint64) *Int
+
***
+
+
#### func (*Int) Div(i *Int) *Int
+
***
+
+
#### func (*Int) DivInt(i int) *Int
+
***
+
+
#### func (*Int) DivInt8(i int8) *Int
+
***
+
+
#### func (*Int) DivInt16(i int16) *Int
+
***
+
+
#### func (*Int) DivInt32(i int32) *Int
+
***
+
+
#### func (*Int) DivInt64(i int64) *Int
+
***
+
+
#### func (*Int) DivUint(i uint) *Int
+
***
+
+
#### func (*Int) DivUint8(i uint8) *Int
+
***
+
+
#### func (*Int) DivUint16(i uint16) *Int
+
***
+
+
#### func (*Int) DivUint32(i uint32) *Int
+
***
+
+
#### func (*Int) DivUint64(i uint64) *Int
+
***
+
+
#### func (*Int) Mod(i *Int) *Int
+
***
+
+
#### func (*Int) ModInt(i int) *Int
+
***
+
+
#### func (*Int) ModInt8(i int8) *Int
+
***
+
+
#### func (*Int) ModInt16(i int16) *Int
+
***
+
+
#### func (*Int) ModInt32(i int32) *Int
+
***
+
+
#### func (*Int) ModInt64(i int64) *Int
+
***
+
+
#### func (*Int) ModUint(i uint) *Int
+
***
+
+
#### func (*Int) ModUint8(i uint8) *Int
+
***
+
+
#### func (*Int) ModUint16(i uint16) *Int
+
***
+
+
#### func (*Int) ModUint32(i uint32) *Int
+
***
+
+
#### func (*Int) ModUint64(i uint64) *Int
+
***
+
+
#### func (*Int) Pow(i *Int) *Int
+
***
+
+
#### func (*Int) PowInt(i int) *Int
+
***
+
+
#### func (*Int) PowInt8(i int8) *Int
+
***
+
+
#### func (*Int) PowInt16(i int16) *Int
+
***
+
+
#### func (*Int) PowInt32(i int32) *Int
+
***
+
+
#### func (*Int) PowInt64(i int64) *Int
+
***
+
+
#### func (*Int) PowUint(i uint) *Int
+
***
+
+
#### func (*Int) PowUint8(i uint8) *Int
+
***
+
+
#### func (*Int) PowUint16(i uint16) *Int
+
***
+
+
#### func (*Int) PowUint32(i uint32) *Int
+
***
+
+
#### func (*Int) PowUint64(i uint64) *Int
+
***
+
+
#### func (*Int) Lsh(i int) *Int
> 左移
+
***
+
+
#### func (*Int) Rsh(i int) *Int
> 右移
+
***
+
+
#### func (*Int) And(i *Int) *Int
> 与
+
***
+
+
#### func (*Int) AndNot(i *Int) *Int
> 与非
+
***
+
+
#### func (*Int) Or(i *Int) *Int
> 或
+
***
+
+
#### func (*Int) Xor(i *Int) *Int
> 异或
+
***
+
+
#### func (*Int) Not() *Int
> 非
+
***
+
+
#### func (*Int) Sqrt() *Int
> 平方根
+
***
+
+
#### func (*Int) GCD(i *Int) *Int
> 最大公约数
+
***
+
+
#### func (*Int) LCM(i *Int) *Int
> 最小公倍数
+
***
+
+
#### func (*Int) ModInverse(i *Int) *Int
> 模反元素
+
***
+
+
#### func (*Int) ModSqrt(i *Int) *Int
> 模平方根
+
***
+
+
#### func (*Int) BitLen() int
> 二进制长度
+
***
+
+
#### func (*Int) Bit(i int) uint
> 二进制位
+
***
+
+
#### func (*Int) SetBit(i int, v uint) *Int
> 设置二进制位
+
***
+
+
#### func (*Int) Neg() *Int
> 返回数字的相反数
+
***
+
+
#### func (*Int) Abs() *Int
> 返回数字的绝对值
+
***
+
+
#### func (*Int) Sign() int
> 返回数字的符号
> - 1:正数
> - 0:零
> - -1:负数
+
***
+
+
#### func (*Int) IsPositive() bool
> 是否为正数
+
***
+
+
#### func (*Int) IsNegative() bool
> 是否为负数
+
***
+
+
#### func (*Int) IsEven() bool
> 是否为偶数
+
***
+
+
#### func (*Int) IsOdd() bool
> 是否为奇数
+
***
+
+
#### func (*Int) ProportionalCalc(proportional *Int, formula func (v *Int) *Int) *Int
> 比例计算,该函数会再 formula 返回值的基础上除以 proportional
> - formula 为计算公式,该公式的参数为调用该函数的 Int 的拷贝
+
***
diff --git a/utils/leaderboard/README.md b/utils/leaderboard/README.md
index 2d8b992..1576b6c 100644
--- a/utils/leaderboard/README.md
+++ b/utils/leaderboard/README.md
@@ -76,9 +76,12 @@ type BinarySearch[CompetitorID comparable, Score generic.Ordered] struct {
rankClearBeforeEventHandles []BinarySearchRankClearBeforeEventHandle[CompetitorID, Score]
}
```
+
+
#### func (*BinarySearch) Competitor(competitorId CompetitorID, score Score)
> 声明排行榜竞争者
> - 如果竞争者存在的情况下,会更新已有成绩,否则新增竞争者
+
**示例代码:**
```go
@@ -97,8 +100,11 @@ func ExampleBinarySearch_Competitor() {
```
***
+
+
#### func (*BinarySearch) RemoveCompetitor(competitorId CompetitorID)
> 删除特定竞争者
+
**示例代码:**
```go
@@ -118,16 +124,25 @@ func ExampleBinarySearch_RemoveCompetitor() {
```
***
+
+
#### func (*BinarySearch) Size() int
> 获取竞争者数量
+
***
+
+
#### func (*BinarySearch) GetRankDefault(competitorId CompetitorID, defaultValue int) int
> 获取竞争者排名,如果竞争者不存在则返回默认值
> - 排名从 0 开始
+
***
+
+
#### func (*BinarySearch) GetRank(competitorId CompetitorID) ( int, error)
> 获取竞争者排名
> - 排名从 0 开始
+
**示例代码:**
```go
@@ -144,38 +159,77 @@ func ExampleBinarySearch_GetRank() {
```
***
+
+
#### func (*BinarySearch) GetCompetitor(rank int) (competitorId CompetitorID, err error)
> 获取特定排名的竞争者
+
***
+
+
#### func (*BinarySearch) GetCompetitorWithRange(start int, end int) ( []CompetitorID, error)
> 获取第start名到第end名竞争者
+
***
+
+
#### func (*BinarySearch) GetScore(competitorId CompetitorID) (score Score, err error)
> 获取竞争者成绩
+
***
+
+
#### func (*BinarySearch) GetScoreDefault(competitorId CompetitorID, defaultValue Score) Score
> 获取竞争者成绩,不存在时返回默认值
+
***
+
+
#### func (*BinarySearch) GetAllCompetitor() []CompetitorID
> 获取所有竞争者ID
> - 结果为名次有序的
+
***
+
+
#### func (*BinarySearch) Clear()
> 清空排行榜
+
***
+
+
#### func (*BinarySearch) Cmp(s1 Score, s2 Score) int
+
***
+
+
#### func (*BinarySearch) UnmarshalJSON(bytes []byte) error
+
***
+
+
#### func (*BinarySearch) MarshalJSON() ( []byte, error)
+
***
+
+
#### func (*BinarySearch) RegRankChangeEvent(handle BinarySearchRankChangeEventHandle[CompetitorID, Score])
+
***
+
+
#### func (*BinarySearch) OnRankChangeEvent(competitorId CompetitorID, oldRank int, newRank int, oldScore Score, newScore Score)
+
***
+
+
#### func (*BinarySearch) RegRankClearBeforeEvent(handle BinarySearchRankClearBeforeEventHandle[CompetitorID, Score])
+
***
+
+
#### func (*BinarySearch) OnRankClearBeforeEvent()
+
***
### BinarySearchRankChangeEventHandle `STRUCT`
diff --git a/utils/log/README.md b/utils/log/README.md
index 16682a5..a743124 100644
--- a/utils/log/README.md
+++ b/utils/log/README.md
@@ -415,13 +415,25 @@ type MultiHandler struct {
handlers []slog.Handler
}
```
+
+
#### func (MultiHandler) Enabled(ctx context.Context, level slog.Level) bool
+
***
+
+
#### func (MultiHandler) Handle(ctx context.Context, record slog.Record) (err error)
+
***
+
+
#### func (MultiHandler) WithAttrs(attrs []slog.Attr) slog.Handler
+
***
+
+
#### func (MultiHandler) WithGroup(name string) slog.Handler
+
***
### Option `STRUCT`
diff --git a/utils/log/survey/README.md b/utils/log/survey/README.md
index f852995..18084d7 100644
--- a/utils/log/survey/README.md
+++ b/utils/log/survey/README.md
@@ -166,32 +166,58 @@ type Analyzer struct {
m sync.Mutex
}
```
+
+
#### func (*Analyzer) Sub(key string) *Analyzer
> 获取子分析器
+
***
+
+
#### func (*Analyzer) SetFormat(key string, format func (v any) any)
> 设置格式化函数
+
***
+
+
#### func (*Analyzer) SetValueIfGreaterThan(key string, value float64)
> 设置指定 key 的值,当新值大于旧值时
> - 当已有值不为 float64 时,将会被忽略
+
***
+
+
#### func (*Analyzer) SetValueIfLessThan(key string, value float64)
> 设置指定 key 的值,当新值小于旧值时
> - 当已有值不为 float64 时,将会被忽略
+
***
+
+
#### func (*Analyzer) SetValueIf(key string, expression bool, value float64)
> 当表达式满足的时候将设置指定 key 的值为 value
+
***
+
+
#### func (*Analyzer) SetValueStringIf(key string, expression bool, value string)
> 当表达式满足的时候将设置指定 key 的值为 value
+
***
+
+
#### func (*Analyzer) SetValue(key string, value float64)
> 设置指定 key 的值
+
***
+
+
#### func (*Analyzer) SetValueString(key string, value string)
> 设置指定 key 的值
+
***
+
+
#### func (*Analyzer) Increase(key string, record R, recordKey string)
> 在指定 key 现有值的基础上增加 recordKey 的值
> - 当分析器已经记录过相同 key 的值时,会根据已有的值类型进行不同处理
@@ -199,21 +225,37 @@ type Analyzer struct {
> 处理方式:
> - 当已有值类型为 string 时,将会使用新的值的 string 类型进行覆盖
> - 当已有值类型为 float64 时,当新的值类型不为 float64 时,将会被忽略
+
***
+
+
#### func (*Analyzer) IncreaseValue(key string, value float64)
> 在指定 key 现有值的基础上增加 value
+
***
+
+
#### func (*Analyzer) IncreaseNonRepeat(key string, record R, recordKey string, dimension ...string)
> 在指定 key 现有值的基础上增加 recordKey 的值,但是当去重维度 dimension 相同时,不会增加
+
***
+
+
#### func (*Analyzer) IncreaseValueNonRepeat(key string, record R, value float64, dimension ...string)
> 在指定 key 现有值的基础上增加 value,但是当去重维度 dimension 相同时,不会增加
+
***
+
+
#### func (*Analyzer) GetValue(key string) float64
> 获取当前记录的值
+
***
+
+
#### func (*Analyzer) GetValueString(key string) string
> 获取当前记录的值
+
***
### Flusher `INTERFACE`
@@ -236,9 +278,15 @@ type FileFlusher struct {
layoutLen int
}
```
+
+
#### func (*FileFlusher) Flush(records []string)
+
***
+
+
#### func (*FileFlusher) Info() string
+
***
### Option `STRUCT`
@@ -258,33 +306,60 @@ type Result gjson.Result
```go
type R string
```
+
+
#### func (R) GetTime(layout string) time.Time
> 获取该记录的时间
+
***
+
+
#### func (R) Get(key string) Result
> 获取指定 key 的值
> - 当 key 为嵌套 key 时,使用 . 进行分割,例如:a.b.c
> - 更多用法参考:https://github.com/tidwall/gjson
+
***
+
+
#### func (R) Exist(key string) bool
> 判断指定 key 是否存在
+
***
+
+
#### func (R) GetString(key string) string
> 该函数为 Get(key).String() 的简写
+
***
+
+
#### func (R) GetInt64(key string) int64
> 该函数为 Get(key).Int() 的简写
+
***
+
+
#### func (R) GetInt(key string) int
> 该函数为 Get(key).Int() 的简写,但是返回值为 int 类型
+
***
+
+
#### func (R) GetFloat64(key string) float64
> 该函数为 Get(key).Float() 的简写
+
***
+
+
#### func (R) GetBool(key string) bool
> 该函数为 Get(key).Bool() 的简写
+
***
+
+
#### func (R) String() string
+
***
### Report `STRUCT`
@@ -298,26 +373,50 @@ type Report struct {
Subs []*Report
}
```
+
+
#### func (*Report) Avg(key string) float64
> 计算平均值
+
***
+
+
#### func (*Report) Count(key string) int64
> 获取特定 key 的计数次数
+
***
+
+
#### func (*Report) Sum(keys ...string) float64
> 获取特定 key 的总和
+
***
+
+
#### func (*Report) Sub(name string) *Report
> 获取特定名称的子报告
+
***
+
+
#### func (*Report) ReserveSubByPrefix(prefix string) *Report
> 仅保留特定前缀的子报告
+
***
+
+
#### func (*Report) ReserveSub(names ...string) *Report
> 仅保留特定名称子报告
+
***
+
+
#### func (*Report) FilterSub(names ...string) *Report
> 将特定名称的子报告过滤掉
+
***
+
+
#### func (*Report) String() string
+
***
diff --git a/utils/memory/README.md b/utils/memory/README.md
index 81e1057..4410a5e 100644
--- a/utils/memory/README.md
+++ b/utils/memory/README.md
@@ -107,10 +107,13 @@ type Option struct {
delay time.Duration
}
```
+
+
#### func (*Option) WithPeriodicity(ticker *timer.Ticker, firstDelay time.Duration, interval time.Duration, delay time.Duration) *Option
> 设置持久化周期
> - ticker 定时器,通常建议使用服务器的定时器,这样可以降低多线程的程序复杂性
> - firstDelay 首次持久化延迟,当首次持久化为 0 时,将会在下一个持久化周期开始时持久化
> - interval 持久化间隔
> - delay 每条数据持久化间隔,适当的设置该值可以使持久化期间尽量降低对用户体验的影响,如果为0,将会一次性持久化所有数据
+
***
diff --git a/utils/moving/README.md b/utils/moving/README.md
index 6606faf..48538d6 100644
--- a/utils/moving/README.md
+++ b/utils/moving/README.md
@@ -115,8 +115,11 @@ type TwoDimensional[EID generic.Basic, PosType generic.SignedNumber] struct {
position2DStopMoveEventHandles []Position2DStopMoveEventHandle[EID, PosType]
}
```
+
+
#### func (*TwoDimensional) MoveTo(entity TwoDimensionalEntity[EID, PosType], x PosType, y PosType)
> 设置对象移动到特定位置
+
**示例代码:**
```go
@@ -140,8 +143,11 @@ func ExampleTwoDimensional_MoveTo() {
```
***
+
+
#### func (*TwoDimensional) StopMove(id EID)
> 停止特定对象的移动
+
**示例代码:**
```go
@@ -215,23 +221,44 @@ func TestTwoDimensional_StopMove(t *testing.T) {
***
+
+
#### func (*TwoDimensional) RegPosition2DChangeEvent(handle Position2DChangeEventHandle[EID, PosType])
> 在对象位置改变时将执行注册的事件处理函数
+
***
+
+
#### func (*TwoDimensional) OnPosition2DChangeEvent(entity TwoDimensionalEntity[EID, PosType], oldX PosType, oldY PosType)
+
***
+
+
#### func (*TwoDimensional) RegPosition2DDestinationEvent(handle Position2DDestinationEventHandle[EID, PosType])
> 在对象到达终点时将执行被注册的事件处理函数
+
***
+
+
#### func (*TwoDimensional) OnPosition2DDestinationEvent(entity TwoDimensionalEntity[EID, PosType])
+
***
+
+
#### func (*TwoDimensional) RegPosition2DStopMoveEvent(handle Position2DStopMoveEventHandle[EID, PosType])
> 在对象停止移动时将执行被注册的事件处理函数
+
***
+
+
#### func (*TwoDimensional) OnPosition2DStopMoveEvent(entity TwoDimensionalEntity[EID, PosType])
+
***
+
+
#### func (*TwoDimensional) Release()
> 释放对象移动对象所占用的资源
+
***
### TwoDimensionalEntity `INTERFACE`
diff --git a/utils/offset/README.md b/utils/offset/README.md
index 4c11c00..a25117d 100644
--- a/utils/offset/README.md
+++ b/utils/offset/README.md
@@ -67,12 +67,21 @@ type Time struct {
offset time.Duration
}
```
+
+
#### func (*Time) SetOffset(offset time.Duration)
> 设置时间偏移
+
***
+
+
#### func (*Time) Now() time.Time
> 获取当前时间偏移后的时间
+
***
+
+
#### func (*Time) Since(t time.Time) time.Duration
> 获取当前时间偏移后的时间自从 t 以来经过的时间
+
***
diff --git a/utils/random/README.md b/utils/random/README.md
index ee9e3a9..d4e92fc 100644
--- a/utils/random/README.md
+++ b/utils/random/README.md
@@ -20,6 +20,7 @@
|[DiceN](#DiceN)|掷骰子
|[NetIP](#NetIP)|返回一个随机的IP地址
|[Port](#Port)|返回一个随机的端口号
+|[UsablePort](#UsablePort)|随机返回一个可用的端口号,如果没有可用端口号则返回 -1
|[IPv4](#IPv4)|返回一个随机产生的IPv4地址。
|[IPv4Port](#IPv4Port)|返回一个随机产生的IPv4地址和端口。
|[Int64](#Int64)|返回一个介于min和max之间的int64类型的随机数。
@@ -73,6 +74,11 @@
> 返回一个随机的端口号
+***
+#### func UsablePort() int
+
+> 随机返回一个可用的端口号,如果没有可用端口号则返回 -1
+
***
#### func IPv4() string
diff --git a/utils/sole/README.md b/utils/sole/README.md
index 040be62..0bfd023 100644
--- a/utils/sole/README.md
+++ b/utils/sole/README.md
@@ -133,9 +133,15 @@ type Once[V any] struct {
r map[any]struct{}
}
```
+
+
#### func (*Once) Get(key any, value V, defaultValue V) V
> 获取一个值,当该值已经被获取过的时候,返回 defaultValue,否则返回 value
+
***
+
+
#### func (*Once) Reset(key ...any)
> 当 key 数量大于 0 时,将会重置对应 key 的记录,否则重置所有记录
+
***
diff --git a/utils/super/README.md b/utils/super/README.md
index 90754cc..b0f1093 100644
--- a/utils/super/README.md
+++ b/utils/super/README.md
@@ -752,8 +752,11 @@ type BitSet[Bit generic.Integer] struct {
set []uint64
}
```
+
+
#### func (*BitSet) Set(bit Bit) *BitSet[Bit]
> 将指定的位 bit 设置为 1
+
查看 / 收起单元测试
@@ -775,8 +778,11 @@ func TestBitSet_Set(t *testing.T) {
***
+
+
#### func (*BitSet) Del(bit Bit) *BitSet[Bit]
> 将指定的位 bit 设置为 0
+
查看 / 收起单元测试
@@ -799,9 +805,12 @@ func TestBitSet_Del(t *testing.T) {
***
+
+
#### func (*BitSet) Shrink() *BitSet[Bit]
> 将 BitSet 中的比特位集合缩小到最小
> - 正常情况下当 BitSet 中的比特位超出 64 位时,将自动增长,当 BitSet 中的比特位数量减少时,可以使用该方法将 BitSet 中的比特位集合缩小到最小
+
查看 / 收起单元测试
@@ -825,92 +834,179 @@ func TestBitSet_Shrink(t *testing.T) {
***
+
+
#### func (*BitSet) Cap() int
> 返回当前 BitSet 中可以表示的最大比特位数量
+
***
+
+
#### func (*BitSet) Has(bit Bit) bool
> 检查指定的位 bit 是否被设置为 1
+
***
+
+
#### func (*BitSet) Clear() *BitSet[Bit]
> 清空所有的比特位
+
***
+
+
#### func (*BitSet) Len() int
> 返回当前 BitSet 中被设置的比特位数量
+
***
+
+
#### func (*BitSet) Bits() []Bit
> 返回当前 BitSet 中被设置的比特位
+
***
+
+
#### func (*BitSet) Reverse() *BitSet[Bit]
> 反转当前 BitSet 中的所有比特位
+
***
+
+
#### func (*BitSet) Not() *BitSet[Bit]
> 返回当前 BitSet 中所有比特位的反转
+
***
+
+
#### func (*BitSet) And(other *BitSet[Bit]) *BitSet[Bit]
> 将当前 BitSet 与另一个 BitSet 进行按位与运算
+
***
+
+
#### func (*BitSet) Or(other *BitSet[Bit]) *BitSet[Bit]
> 将当前 BitSet 与另一个 BitSet 进行按位或运算
+
***
+
+
#### func (*BitSet) Xor(other *BitSet[Bit]) *BitSet[Bit]
> 将当前 BitSet 与另一个 BitSet 进行按位异或运算
+
***
+
+
#### func (*BitSet) Sub(other *BitSet[Bit]) *BitSet[Bit]
> 将当前 BitSet 与另一个 BitSet 进行按位减运算
+
***
+
+
#### func (*BitSet) IsZero() bool
> 检查当前 BitSet 是否为空
+
***
+
+
#### func (*BitSet) Clone() *BitSet[Bit]
> 返回当前 BitSet 的副本
+
***
+
+
#### func (*BitSet) Equal(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否与另一个 BitSet 相等
+
***
+
+
#### func (*BitSet) Contains(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否包含另一个 BitSet
+
***
+
+
#### func (*BitSet) ContainsAny(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否包含另一个 BitSet 中的任意比特位
+
***
+
+
#### func (*BitSet) ContainsAll(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否包含另一个 BitSet 中的所有比特位
+
***
+
+
#### func (*BitSet) Intersect(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否与另一个 BitSet 有交集
+
***
+
+
#### func (*BitSet) Union(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否与另一个 BitSet 有并集
+
***
+
+
#### func (*BitSet) Difference(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否与另一个 BitSet 有差集
+
***
+
+
#### func (*BitSet) SymmetricDifference(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否与另一个 BitSet 有对称差集
+
***
+
+
#### func (*BitSet) Subset(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否为另一个 BitSet 的子集
+
***
+
+
#### func (*BitSet) Superset(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否为另一个 BitSet 的超集
+
***
+
+
#### func (*BitSet) Complement(other *BitSet[Bit]) bool
> 检查当前 BitSet 是否为另一个 BitSet 的补集
+
***
+
+
#### func (*BitSet) Max() Bit
> 返回当前 BitSet 中最大的比特位
+
***
+
+
#### func (*BitSet) Min() Bit
> 返回当前 BitSet 中最小的比特位
+
***
+
+
#### func (*BitSet) String() string
> 返回当前 BitSet 的字符串表示
+
***
+
+
#### func (*BitSet) MarshalJSON() ( []byte, error)
> 实现 json.Marshaler 接口
+
***
+
+
#### func (*BitSet) UnmarshalJSON(data []byte) error
> 实现 json.Unmarshaler 接口
+
***
### LossCounter `STRUCT`
@@ -922,13 +1018,22 @@ type LossCounter struct {
lossKey []string
}
```
+
+
#### func (*LossCounter) Record(name string)
> 记录一次损耗
+
***
+
+
#### func (*LossCounter) GetLoss(handler func (step int, name string, loss time.Duration))
> 获取损耗
+
***
+
+
#### func (*LossCounter) String() string
+
***
### Matcher `STRUCT`
@@ -940,11 +1045,17 @@ type Matcher[Value any, Result any] struct {
d bool
}
```
+
+
#### func (*Matcher) Case(value Value, result Result) *Matcher[Value, Result]
> 匹配
+
***
+
+
#### func (*Matcher) Default(value Result) Result
> 默认
+
***
### Permission `STRUCT`
@@ -955,17 +1066,29 @@ type Permission[Code generic.Integer, EntityID comparable] struct {
l sync.RWMutex
}
```
+
+
#### func (*Permission) HasPermission(entityId EntityID, permission Code) bool
> 是否有权限
+
***
+
+
#### func (*Permission) AddPermission(entityId EntityID, permission ...Code)
> 添加权限
+
***
+
+
#### func (*Permission) RemovePermission(entityId EntityID, permission ...Code)
> 移除权限
+
***
+
+
#### func (*Permission) SetPermission(entityId EntityID, permission ...Code)
> 设置权限
+
***
### StackGo `STRUCT`
@@ -978,19 +1101,28 @@ type StackGo struct {
collect chan []byte
}
```
+
+
#### func (*StackGo) Wait()
> 等待收集消息堆栈
> - 在调用 Wait 函数后,当前协程将会被挂起,直到调用 Stack 或 GiveUp 函数
+
***
+
+
#### func (*StackGo) Stack() []byte
> 获取消息堆栈
> - 在调用 Wait 函数后调用该函数,将会返回上一个协程的堆栈信息
> - 在调用 GiveUp 函数后调用该函数,将会 panic
+
***
+
+
#### func (*StackGo) GiveUp()
> 放弃收集消息堆栈
> - 在调用 Wait 函数后调用该函数,将会放弃收集消息堆栈并且释放资源
> - 在调用 GiveUp 函数后调用 Stack 函数,将会 panic
+
***
### VerifyHandle `STRUCT`
@@ -1002,13 +1134,22 @@ type VerifyHandle[V any] struct {
hit bool
}
```
+
+
#### func (*VerifyHandle) PreCase(expression func () bool, value V, caseHandle func (verify *VerifyHandle[V]) bool) bool
> 先决校验用例,当 expression 成立时,将跳过 caseHandle 的执行,直接执行 handle 并返回 false
> - 常用于对前置参数的空指针校验,例如当 a 为 nil 时,不执行 a.B(),而是直接返回 false
+
***
+
+
#### func (*VerifyHandle) Case(expression bool, value V) *VerifyHandle[V]
> 校验用例,当 expression 成立时,将忽略后续 Case,并将在 Do 时执行 handle,返回 false
+
***
+
+
#### func (*VerifyHandle) Do() bool
> 执行校验,当校验失败时,将执行 handle,并返回 false
+
***
diff --git a/utils/timer/README.md b/utils/timer/README.md
index ab9b2f2..38d3129 100644
--- a/utils/timer/README.md
+++ b/utils/timer/README.md
@@ -115,16 +115,25 @@ type Pool struct {
closed bool
}
```
+
+
#### func (*Pool) ChangePoolSize(size int) error
> 改变定时器池大小
> - 当传入的大小小于或等于 0 时,将会返回错误,并且不会发生任何改变
+
***
+
+
#### func (*Pool) GetTicker(size int, options ...Option) *Ticker
> 获取一个新的定时器
+
***
+
+
#### func (*Pool) Release()
> 释放定时器池的资源,释放后由其产生的 Ticker 在 Ticker.Release 后将不再回到池中,而是直接释放
> - 虽然定时器池已被释放,但是依旧可以产出 Ticker
+
***
### Scheduler `STRUCT`
@@ -145,14 +154,23 @@ type Scheduler struct {
expr *cronexpr.Expression
}
```
+
+
#### func (*Scheduler) Name() string
> 获取调度器名称
+
***
+
+
#### func (*Scheduler) Next(prev time.Time) time.Time
> 获取下一次执行的时间
+
***
+
+
#### func (*Scheduler) Caller()
> 可由外部发起调用的执行函数
+
***
### Ticker `STRUCT`
@@ -167,24 +185,42 @@ type Ticker struct {
mark string
}
```
+
+
#### func (*Ticker) Mark() string
> 获取定时器的标记
> - 通常用于鉴别定时器来源
+
***
+
+
#### func (*Ticker) Release()
> 释放定时器,并将定时器重新放回 Pool 池中
+
***
+
+
#### func (*Ticker) StopTimer(name string)
> 停止特定名称的调度器
+
***
+
+
#### func (*Ticker) IsStopped(name string) bool
> 特定名称的调度器是否已停止
+
***
+
+
#### func (*Ticker) GetSchedulers() []string
> 获取所有调度器名称
+
***
+
+
#### func (*Ticker) Cron(name string, expression string, handleFunc interface {}, args ...interface {})
> 通过 cron 表达式设置一个调度器,当 cron 表达式错误时,将会引发 panic
+
查看 / 收起单元测试
@@ -212,12 +248,21 @@ func TestTicker_Cron(t *testing.T) {
***
+
+
#### func (*Ticker) CronByInstantly(name string, expression string, handleFunc interface {}, args ...interface {})
> 与 Cron 相同,但是会立即执行一次
+
***
+
+
#### func (*Ticker) After(name string, after time.Duration, handleFunc interface {}, args ...interface {})
> 设置一个在特定时间后运行一次的调度器
+
***
+
+
#### func (*Ticker) Loop(name string, after time.Duration, interval time.Duration, times int, handleFunc interface {}, args ...interface {})
> 设置一个在特定时间后反复运行的调度器
+
***
diff --git a/utils/times/README.md b/utils/times/README.md
index 091682e..90dc59c 100644
--- a/utils/times/README.md
+++ b/utils/times/README.md
@@ -410,6 +410,8 @@ type StateLine[State generic.Basic] struct {
trigger [][]func()
}
```
+
+
#### func (*StateLine) Check(missingAllowed bool, states ...State) bool
> 根据状态顺序检查时间线是否合法
> - missingAllowed: 是否允许状态缺失,如果为 true,则状态可以不连续,如果为 false,则状态必须连续
@@ -417,76 +419,146 @@ type StateLine[State generic.Basic] struct {
> 状态不连续表示时间线中存在状态缺失,例如:
> - 状态为 [1, 2, 3, 4, 5] 的时间线,如果 missingAllowed 为 true,则状态为 [1, 3, 5] 也是合法的
> - 状态为 [1, 2, 3, 4, 5] 的时间线,如果 missingAllowed 为 false,则状态为 [1, 3, 5] 是不合法的
+
***
+
+
#### func (*StateLine) GetMissingStates(states ...State) []State
> 获取缺失的状态
+
***
+
+
#### func (*StateLine) HasState(state State) bool
> 检查时间线中是否包含指定状态
+
***
+
+
#### func (*StateLine) String() string
> 获取时间线的字符串表示
+
***
+
+
#### func (*StateLine) AddState(state State, t time.Time, onTrigger ...func ()) *StateLine[State]
> 添加一个状态到时间线中,状态不能与任一时间点重合,否则将被忽略
> - onTrigger: 该状态绑定的触发器,该触发器不会被主动执行,需要主动获取触发器执行
+
***
+
+
#### func (*StateLine) GetTimeByState(state State) time.Time
> 获取指定状态的时间点
+
***
+
+
#### func (*StateLine) GetNextTimeByState(state State) time.Time
> 获取指定状态的下一个时间点
+
***
+
+
#### func (*StateLine) GetLastState() State
> 获取最后一个状态
+
***
+
+
#### func (*StateLine) GetPrevTimeByState(state State) time.Time
> 获取指定状态的上一个时间点
+
***
+
+
#### func (*StateLine) GetIndexByState(state State) int
> 获取指定状态的索引
+
***
+
+
#### func (*StateLine) GetStateByTime(t time.Time) State
> 获取指定时间点的状态
+
***
+
+
#### func (*StateLine) GetTimeByIndex(index int) time.Time
> 获取指定索引的时间点
+
***
+
+
#### func (*StateLine) Move(d time.Duration) *StateLine[State]
> 时间线整体移动
+
***
+
+
#### func (*StateLine) GetNextStateTimeByIndex(index int) time.Time
> 获取指定索引的下一个时间点
+
***
+
+
#### func (*StateLine) GetPrevStateTimeByIndex(index int) time.Time
> 获取指定索引的上一个时间点
+
***
+
+
#### func (*StateLine) GetStateIndexByTime(t time.Time) int
> 获取指定时间点的索引
+
***
+
+
#### func (*StateLine) GetStateCount() int
> 获取状态数量
+
***
+
+
#### func (*StateLine) GetStateByIndex(index int) State
> 获取指定索引的状态
+
***
+
+
#### func (*StateLine) GetTriggerByTime(t time.Time) []func ()
> 获取指定时间点的触发器
+
***
+
+
#### func (*StateLine) GetTriggerByIndex(index int) []func ()
> 获取指定索引的触发器
+
***
+
+
#### func (*StateLine) GetTriggerByState(state State) []func ()
> 获取指定状态的触发器
+
***
+
+
#### func (*StateLine) AddTriggerToState(state State, onTrigger ...func ()) *StateLine[State]
> 给指定状态添加触发器
+
***
+
+
#### func (*StateLine) Range(handler func (index int, state State, t time.Time) bool)
> 按照时间顺序遍历时间线
+
***
+
+
#### func (*StateLine) RangeReverse(handler func (index int, state State, t time.Time) bool)
> 按照时间逆序遍历时间线
+
***
### Period `STRUCT`
@@ -494,61 +566,118 @@ type StateLine[State generic.Basic] struct {
```go
type Period [2]time.Time
```
+
+
#### func (Period) Start() time.Time
> 返回时间段的开始时间
+
***
+
+
#### func (Period) End() time.Time
> 返回时间段的结束时间
+
***
+
+
#### func (Period) Duration() time.Duration
> 返回时间段的持续时间
+
***
+
+
#### func (Period) Day() int
> 返回时间段的持续天数
+
***
+
+
#### func (Period) Hour() int
> 返回时间段的持续小时数
+
***
+
+
#### func (Period) Minute() int
> 返回时间段的持续分钟数
+
***
+
+
#### func (Period) Seconds() int
> 返回时间段的持续秒数
+
***
+
+
#### func (Period) Milliseconds() int
> 返回时间段的持续毫秒数
+
***
+
+
#### func (Period) Microseconds() int
> 返回时间段的持续微秒数
+
***
+
+
#### func (Period) Nanoseconds() int
> 返回时间段的持续纳秒数
+
***
+
+
#### func (Period) IsZero() bool
> 判断时间段是否为零值
+
***
+
+
#### func (Period) IsInvalid() bool
> 判断时间段是否无效
+
***
+
+
#### func (Period) IsBefore(t time.Time) bool
> 判断时间段是否在指定时间之前
+
***
+
+
#### func (Period) IsAfter(t time.Time) bool
> 判断时间段是否在指定时间之后
+
***
+
+
#### func (Period) IsBetween(t time.Time) bool
> 判断指定时间是否在时间段之间
+
***
+
+
#### func (Period) IsOngoing(t time.Time) bool
> 判断指定时间是否正在进行时
> - 如果时间段的开始时间在指定时间之前或者等于指定时间,且时间段的结束时间在指定时间之后,则返回 true
+
***
+
+
#### func (Period) IsBetweenOrEqual(t time.Time) bool
> 判断指定时间是否在时间段之间或者等于时间段的开始或结束时间
+
***
+
+
#### func (Period) IsBetweenOrEqualPeriod(t Period) bool
> 判断指定时间是否在时间段之间或者等于时间段的开始或结束时间
+
***
+
+
#### func (Period) IsOverlap(t Period) bool
> 判断时间段是否与指定时间段重叠
+
***