mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-04 08:10:55 +00:00
105 lines
2.0 KiB
Go
105 lines
2.0 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"sync"
|
|
|
|
"github.com/GopeedLab/gopeed/pkg/download"
|
|
)
|
|
|
|
type TaskEventMask uint64
|
|
|
|
const (
|
|
// Keep these first two unchanged because Flutter already uses
|
|
// bit 0 for done and bit 1 for error.
|
|
TaskEventDone TaskEventMask = 1 << iota
|
|
TaskEventError
|
|
|
|
TaskEventStart
|
|
TaskEventProgress
|
|
TaskEventPause
|
|
TaskEventDelete
|
|
)
|
|
|
|
type TaskEvent struct {
|
|
Type string `json:"type"`
|
|
TaskID string `json:"taskId"`
|
|
Name string `json:"name,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
type TaskEventListener func(payload string)
|
|
|
|
type taskEventSubscription struct {
|
|
mu sync.RWMutex
|
|
mask TaskEventMask
|
|
listener TaskEventListener
|
|
}
|
|
|
|
func (s *Service) SubscribeTaskEvents(mask TaskEventMask, listener TaskEventListener) {
|
|
s.taskEvents.mu.Lock()
|
|
defer s.taskEvents.mu.Unlock()
|
|
s.taskEvents.mask = mask
|
|
s.taskEvents.listener = listener
|
|
}
|
|
|
|
func (s *Service) emitTaskEvent(event *download.Event) {
|
|
if event == nil || event.Task == nil {
|
|
return
|
|
}
|
|
|
|
var mask TaskEventMask
|
|
|
|
switch event.Key {
|
|
case download.EventKeyDone:
|
|
mask = TaskEventDone
|
|
|
|
case download.EventKeyError:
|
|
mask = TaskEventError
|
|
|
|
case download.EventKeyStart:
|
|
mask = TaskEventStart
|
|
|
|
case download.EventKeyProgress:
|
|
mask = TaskEventProgress
|
|
|
|
case download.EventKeyPause:
|
|
mask = TaskEventPause
|
|
|
|
case download.EventKeyDelete:
|
|
mask = TaskEventDelete
|
|
|
|
default:
|
|
return
|
|
}
|
|
|
|
s.taskEvents.mu.RLock()
|
|
if s.taskEvents.mask&mask == 0 || s.taskEvents.listener == nil {
|
|
s.taskEvents.mu.RUnlock()
|
|
return
|
|
}
|
|
listener := s.taskEvents.listener
|
|
s.taskEvents.mu.RUnlock()
|
|
|
|
payload := TaskEvent{
|
|
Type: "task." + string(event.Key),
|
|
TaskID: event.Task.ID,
|
|
}
|
|
if event.Task.Meta != nil {
|
|
payload.Name = event.Task.Name()
|
|
}
|
|
if event.Err != nil {
|
|
payload.Error = event.Err.Error()
|
|
}
|
|
data, err := json.Marshal(payload)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// A platform callback must never be able to crash a download worker.
|
|
func() {
|
|
defer func() { _ = recover() }()
|
|
listener(string(data))
|
|
}()
|
|
}
|