package task import ( "reflect" "samba/pkg/service" ) type Manager struct { svr service.IService tasks map[string]*Task enable bool } type optional interface{ Apply(*Task) } func NewManager(svr service.IService) *Manager { return &Manager{ svr: svr, tasks: make(map[string]*Task), } } func (m *Manager) AddTask(ts ...Tasker) { for _, t := range ts { tk := m.NewTask(t.Name(), t.Do) callApply(t, tk, 1) t.Init(tk) } } func (m *Manager) NewTask(name string, do task) *Task { t := &Task{ name: name, do: do, svr: m.svr, } m.tasks[name] = t return t } func (m *Manager) Submit() { if m.enable { return } for _, t := range m.tasks { t.submit() } m.enable = true } func callApply(v any, t *Task, step int) { val := reflect.ValueOf(v) if val.Kind() == reflect.Ptr { val = val.Elem() } if step > 1 { if opt, ok := v.(optional); ok { opt.Apply(t) return } } if val.Kind() != reflect.Struct { return } for i := 0; i < val.NumField(); i++ { field := val.Field(i) if field.Kind() == reflect.Ptr && field.IsNil() { newField := reflect.New(field.Type().Elem()) field.Set(newField) } if field.IsValid() && field.CanInterface() { callApply(field.Interface(), t, step+1) } } }