refactor: 任务 task 包重构
This commit is contained in:
parent
8368fe0770
commit
a23e48b087
|
@ -0,0 +1,14 @@
|
||||||
|
package task
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrTaskNotFinish 任务未完成
|
||||||
|
ErrTaskNotFinish = errors.New("task not finish")
|
||||||
|
// ErrTaskRewardReceived 任务奖励已领取
|
||||||
|
ErrTaskRewardReceived = errors.New("task reward received")
|
||||||
|
// ErrTaskNotStart 任务未开始
|
||||||
|
ErrTaskNotStart = errors.New("task not start")
|
||||||
|
// ErrTaskFail 任务失败
|
||||||
|
ErrTaskFail = errors.New("task fail")
|
||||||
|
)
|
|
@ -1,32 +1,35 @@
|
||||||
package task
|
package task
|
||||||
|
|
||||||
type (
|
type (
|
||||||
TaskDoneEventHandle func(eventId int64, task *Task)
|
RefreshTaskCountEvent func(taskType int, increase int64)
|
||||||
|
RefreshTaskChildCountEvent func(taskType int, key any, increase int64)
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskDoneEventHandles = make(map[int64]map[int64]TaskDoneEventHandle)
|
var (
|
||||||
|
refreshTaskCountEventHandles = make(map[int]RefreshTaskCountEvent)
|
||||||
|
refreshTaskChildCountEventHandles = make(map[int]RefreshTaskChildCountEvent)
|
||||||
|
)
|
||||||
|
|
||||||
// RegTaskDoneEvent 注册任务完成事件
|
// RegRefreshTaskCount 注册任务计数刷新事件
|
||||||
func RegTaskDoneEvent(id int64, eventId int64, handle TaskDoneEventHandle) {
|
func RegRefreshTaskCount(taskType int, handler RefreshTaskCountEvent) {
|
||||||
events, exist := taskDoneEventHandles[id]
|
refreshTaskCountEventHandles[taskType] = handler
|
||||||
if !exist {
|
|
||||||
events = map[int64]TaskDoneEventHandle{}
|
|
||||||
taskDoneEventHandles[id] = events
|
|
||||||
}
|
|
||||||
events[eventId] = handle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnRegTaskDoneEvent 取消注册任务完成事件
|
// OnRefreshTaskCount 触发任务计数刷新事件
|
||||||
func UnRegTaskDoneEvent(id int64, eventId int64) {
|
func OnRefreshTaskCount(taskType int, increase int64) {
|
||||||
events, exist := taskDoneEventHandles[id]
|
if handler, ok := refreshTaskCountEventHandles[taskType]; ok {
|
||||||
if exist {
|
handler(taskType, increase)
|
||||||
delete(events, eventId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnTaskDoneEvent 任务完成事件
|
// RegRefreshTaskChildCount 注册任务子计数刷新事件
|
||||||
func OnTaskDoneEvent(task *Task) {
|
func RegRefreshTaskChildCount(taskType int, handler RefreshTaskChildCountEvent) {
|
||||||
for eventId, handle := range taskDoneEventHandles[task.id] {
|
refreshTaskChildCountEventHandles[taskType] = handler
|
||||||
handle(eventId, task)
|
}
|
||||||
|
|
||||||
|
// OnRefreshTaskChildCount 触发任务子计数刷新事件
|
||||||
|
func OnRefreshTaskChildCount(taskType int, key any, increase int64) {
|
||||||
|
if handler, ok := refreshTaskChildCountEventHandles[taskType]; ok {
|
||||||
|
handler(taskType, key, increase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,85 @@
|
||||||
package task
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/offset"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type Option func(task *Task)
|
type Option func(task *Task)
|
||||||
|
|
||||||
// WithInitCount 通过初始化计数的方式创建任务
|
// WithChildCount 通过初始化子计数的方式创建任务
|
||||||
func WithInitCount(count int) Option {
|
func WithChildCount(key any, childCount int64) Option {
|
||||||
return func(task *Task) {
|
return func(task *Task) {
|
||||||
task.count = count
|
if task.childCount == nil {
|
||||||
|
task.childCount = make(map[any]int64)
|
||||||
|
}
|
||||||
|
if task.childCondition == nil {
|
||||||
|
task.childCondition = make(map[any]int64)
|
||||||
|
}
|
||||||
|
task.childCount[key] = childCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithDone 通过指定任务完成计数的方式创建任务
|
// WithChild 通过指定子计数的方式创建任务
|
||||||
func WithDone(done int) Option {
|
// - 只有当子计数与主计数均达到条件时,任务才会完成
|
||||||
|
// - 通常用于多条件的任务
|
||||||
|
func WithChild(key any, childCondition int64) Option {
|
||||||
return func(task *Task) {
|
return func(task *Task) {
|
||||||
task.done = done
|
if task.childCount == nil {
|
||||||
|
task.childCount = make(map[any]int64)
|
||||||
|
}
|
||||||
|
if task.childCondition == nil {
|
||||||
|
task.childCondition = make(map[any]int64)
|
||||||
|
}
|
||||||
|
task.childCondition[key] = childCondition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDisableNotStartGetReward 禁止未开始的任务领取奖励
|
||||||
|
func WithDisableNotStartGetReward() Option {
|
||||||
|
return func(task *Task) {
|
||||||
|
task.disableNotStartGetReward = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCount 通过初始化计数的方式创建任务
|
||||||
|
func WithCount(count int64) Option {
|
||||||
|
return func(task *Task) {
|
||||||
|
task.SetCount(count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStartTime 通过指定开始时间的方式创建任务
|
||||||
|
// - 只有当时间在开始时间之后,任务才会开始计数
|
||||||
|
func WithStartTime(startTime time.Time) Option {
|
||||||
|
return func(task *Task) {
|
||||||
|
task.start = startTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithOffsetTime 通过指定偏移时间的方式创建任务
|
||||||
|
func WithOffsetTime(offset *offset.Time) Option {
|
||||||
|
return func(task *Task) {
|
||||||
|
task.offset = offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLimitedTime 通过限时的方式创建任务
|
||||||
|
func WithLimitedTime(limitTime time.Duration) Option {
|
||||||
|
return func(task *Task) {
|
||||||
|
task.limitTime = limitTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithFront 通过指定任务前置任务的方式创建任务
|
||||||
|
// - 当前置任务未完成时,当前任务不会开始计数
|
||||||
|
func WithFront(fronts ...*Task) Option {
|
||||||
|
return func(task *Task) {
|
||||||
|
if task.fronts == nil {
|
||||||
|
task.fronts = make(map[int64]*Task)
|
||||||
|
}
|
||||||
|
for _, front := range fronts {
|
||||||
|
task.fronts[front.GetID()] = front
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package task
|
package task
|
||||||
|
|
||||||
const (
|
const (
|
||||||
StateDoing State = iota // 进行中
|
StateAccept State = iota // 已接受
|
||||||
StateDone // 已完成
|
StateFinish // 已完成
|
||||||
StateReward // 已领取
|
StateReward // 已领取
|
||||||
|
StateFail // 已失败
|
||||||
)
|
)
|
||||||
|
|
||||||
// State 任务状态
|
type State uint16
|
||||||
type State byte
|
|
||||||
|
|
|
@ -1,67 +1,204 @@
|
||||||
package task
|
package task
|
||||||
|
|
||||||
// NewTask 新建任务
|
import (
|
||||||
func NewTask(id int64, options ...Option) *Task {
|
"github.com/kercylan98/minotaur/utils/hash"
|
||||||
|
"github.com/kercylan98/minotaur/utils/offset"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewTask 创建任务
|
||||||
|
func NewTask(id int64, taskType int, condition int64, options ...Option) *Task {
|
||||||
task := &Task{
|
task := &Task{
|
||||||
id: id,
|
id: id,
|
||||||
|
condition: condition,
|
||||||
|
state: StateAccept,
|
||||||
}
|
}
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(task)
|
option(task)
|
||||||
}
|
}
|
||||||
if task.count > task.done {
|
if task.start.IsZero() {
|
||||||
task.count = task.done
|
if task.offset != nil {
|
||||||
|
task.start = task.offset.Now()
|
||||||
|
} else {
|
||||||
|
task.start = time.Now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for key := range task.childCount {
|
||||||
|
if !hash.Exist(task.childCondition, key) {
|
||||||
|
delete(task.childCount, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if task.count == task.condition {
|
||||||
|
task.state = StateFinish
|
||||||
}
|
}
|
||||||
task.Add(0)
|
|
||||||
return task
|
return task
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Task 通用任务数据结构
|
||||||
type Task struct {
|
type Task struct {
|
||||||
id int64 // 任务ID
|
id int64 // 任务ID
|
||||||
count int // 任务计数
|
taskType int // 任务类型
|
||||||
done int // 任务完成计数
|
count int64 // 任务主计数
|
||||||
reward bool // 是否已领取奖励
|
condition int64 // 任务完成需要的计数条件
|
||||||
|
childCount map[any]int64 // 任务子计数
|
||||||
|
childCondition map[any]int64 // 任务子计数条件
|
||||||
|
state State // 任务状态
|
||||||
|
start time.Time // 任务开始时间
|
||||||
|
limitTime time.Duration // 任务限时
|
||||||
|
fronts map[int64]*Task // 任务前置任务
|
||||||
|
disableNotStartGetReward bool // 禁止未开始的任务领取奖励
|
||||||
|
|
||||||
|
offset *offset.Time // 任务偏移时间
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID 获取任务ID
|
||||||
|
func (slf *Task) GetID() int64 {
|
||||||
|
return slf.id
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetType 获取任务类型
|
||||||
|
func (slf *Task) GetType() int {
|
||||||
|
return slf.taskType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset 重置任务
|
// Reset 重置任务
|
||||||
func (slf *Task) Reset() {
|
func (slf *Task) Reset() {
|
||||||
slf.count = 0
|
slf.count = 0
|
||||||
slf.reward = false
|
slf.state = StateAccept
|
||||||
switch slf.GetState() {
|
for key := range slf.childCount {
|
||||||
case StateDone:
|
delete(slf.childCount, key)
|
||||||
OnTaskDoneEvent(slf)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add 增加任务计数
|
// GetFronts 获取前置任务
|
||||||
func (slf *Task) Add(count int) {
|
func (slf *Task) GetFronts() map[int64]*Task {
|
||||||
if count != 0 {
|
return slf.fronts
|
||||||
slf.count += count
|
}
|
||||||
if slf.count < 0 {
|
|
||||||
slf.count = 0
|
// GetFrontsWithState 获取特定状态的前置任务
|
||||||
} else if slf.count > slf.done {
|
func (slf *Task) GetFrontsWithState(state State) map[int64]*Task {
|
||||||
slf.count = slf.done
|
fronts := make(map[int64]*Task)
|
||||||
|
for id, front := range slf.fronts {
|
||||||
|
if front.GetState() == state {
|
||||||
|
fronts[id] = front
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch slf.GetState() {
|
return fronts
|
||||||
case StateDone:
|
}
|
||||||
OnTaskDoneEvent(slf)
|
|
||||||
|
// FrontsIsFinish 判断前置任务是否完成
|
||||||
|
func (slf *Task) FrontsIsFinish() bool {
|
||||||
|
for _, front := range slf.fronts {
|
||||||
|
state := front.GetState()
|
||||||
|
if state == StateAccept || state == StateFail {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReward 获取任务奖励
|
||||||
|
// - 当任务状态为 StateFinish 时,调用 rewardHandle 函数
|
||||||
|
// - 当任务状态不为 StateFinish 或奖励函数发生错误时,返回错误
|
||||||
|
func (slf *Task) GetReward(rewardHandle func() error) error {
|
||||||
|
if !slf.IsStart() {
|
||||||
|
return ErrTaskNotStart
|
||||||
|
}
|
||||||
|
switch slf.GetState() {
|
||||||
|
case StateAccept:
|
||||||
|
return ErrTaskNotFinish
|
||||||
|
case StateReward:
|
||||||
|
return ErrTaskRewardReceived
|
||||||
|
case StateFail:
|
||||||
|
return ErrTaskFail
|
||||||
|
}
|
||||||
|
if err := rewardHandle(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
slf.state = StateReward
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetState 获取任务状态
|
// GetState 获取任务状态
|
||||||
func (slf *Task) GetState() State {
|
func (slf *Task) GetState() State {
|
||||||
if slf.count >= slf.done {
|
return slf.state
|
||||||
if slf.reward {
|
|
||||||
return StateReward
|
|
||||||
}
|
|
||||||
return StateDone
|
|
||||||
}
|
|
||||||
return StateDoing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reward 返回是否领取过奖励,并且设置任务为领取过奖励的状态
|
// IsStart 判断任务是否开始
|
||||||
func (slf *Task) Reward() bool {
|
func (slf *Task) IsStart() bool {
|
||||||
reward := slf.reward
|
var current time.Time
|
||||||
slf.reward = true
|
if slf.offset != nil {
|
||||||
return reward
|
current = slf.offset.Now()
|
||||||
|
} else {
|
||||||
|
current = time.Now()
|
||||||
|
}
|
||||||
|
if current.Before(slf.start) {
|
||||||
|
return false
|
||||||
|
} else if slf.limitTime > 0 && current.Sub(slf.start) >= slf.limitTime {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCount 设置计数
|
||||||
|
func (slf *Task) SetCount(count int64) {
|
||||||
|
if !slf.IsStart() || !slf.FrontsIsFinish() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
slf.count = count
|
||||||
|
if slf.count >= slf.condition {
|
||||||
|
slf.count = slf.condition
|
||||||
|
} else if slf.count < 0 {
|
||||||
|
slf.count = 0
|
||||||
|
}
|
||||||
|
slf.refreshState()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCount 增加计数
|
||||||
|
func (slf *Task) AddCount(count int64) {
|
||||||
|
slf.SetCount(slf.count + count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCount 获取计数
|
||||||
|
func (slf *Task) GetCount() int64 {
|
||||||
|
return slf.count
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCondition 获取计数条件
|
||||||
|
func (slf *Task) GetCondition() int64 {
|
||||||
|
return slf.condition
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChildCount 设置子计数
|
||||||
|
func (slf *Task) SetChildCount(key any, count int64) {
|
||||||
|
if !slf.IsStart() || !slf.FrontsIsFinish() || !hash.Exist(slf.childCondition, key) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if condition := slf.childCondition[key]; count > condition {
|
||||||
|
count = condition
|
||||||
|
} else if count < 0 {
|
||||||
|
count = 0
|
||||||
|
}
|
||||||
|
slf.childCount[key] = count
|
||||||
|
slf.refreshState()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddChildCount 增加子计数
|
||||||
|
func (slf *Task) AddChildCount(key any, count int64) {
|
||||||
|
slf.SetChildCount(key, slf.childCount[key]+count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// refreshState 刷新任务状态
|
||||||
|
func (slf *Task) refreshState() {
|
||||||
|
slf.state = StateFinish
|
||||||
|
if slf.count != slf.condition {
|
||||||
|
slf.state = StateAccept
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for key, condition := range slf.childCondition {
|
||||||
|
if slf.childCount[key] != condition {
|
||||||
|
slf.state = StateAccept
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultTolerance = 0.0001 // 默认误差范围
|
DefaultTolerance = 0.0001 // 默认误差范围
|
||||||
|
Zero = 0 // 零
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetDefaultTolerance 获取默认误差范围
|
// GetDefaultTolerance 获取默认误差范围
|
||||||
|
|
Loading…
Reference in New Issue