package commandctrl import ( "context" tea "github.com/charmbracelet/bubbletea" "github.com/go-co-op/gocron/v2" "github.com/pkg/errors" "ucl.lmika.dev/ucl" ) type commandCtlKeyType struct{} var commandCtlKey = commandCtlKeyType{} type execContext struct { ctrl *CommandController requestRefresh bool } func PostMsg(ctx context.Context, msg tea.Msg) { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if ok { cmdCtl.ctrl.postMessage(msg) } } func SelectedItemIndex(ctx context.Context) (int, bool) { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return 0, false } return cmdCtl.ctrl.uiStateProvider.SelectedItemIndex(), true } func SetSelectedItemIndex(ctx context.Context, newIdx int) tea.Msg { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return nil } return cmdCtl.ctrl.uiStateProvider.SetSelectedItemIndex(newIdx) } func GetInvoker(ctx context.Context) Invoker { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return nil } return cmdCtl.ctrl } func QueueRefresh(ctx context.Context) { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return } cmdCtl.requestRefresh = true } func CronScheduler(ctx context.Context) gocron.Scheduler { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return nil } return cmdCtl.ctrl.cronScheduler } func ScheduleTask(ctx context.Context, task func(ctx context.Context) error) error { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return errors.New("no command controller") } select { case cmdCtl.ctrl.pendingTaskChan <- pendingTask{task: task}: return nil default: return errors.New("task queue is full") } } func ScheduleAuxTask(ctx context.Context, descr string, task func(ctx context.Context) error) error { cmdCtl, ok := ctx.Value(commandCtlKey).(*execContext) if !ok { return errors.New("no command controller") } select { case cmdCtl.ctrl.pendingAuxTaskChan <- pendingTask{descr: descr, task: task}: return nil default: return errors.New("aux task queue is full") } } type Invoker interface { Invoke(invokable ucl.Invokable, args []any) tea.Msg Inst() *ucl.Inst }