Merge and OnComplete
Vladimir Bauer
6 years ago
| 20 | 20 | var pdecorators mpb.BarOption |
| 21 | 21 | if i == 0 { |
| 22 | 22 | pdecorators = mpb.PrependDecorators( |
| 23 | // Merge to sync width with decorators on lines 37 and 38 | |
| 24 | 23 | decor.Merge( |
| 25 | newVariadicSpinner(decor.WCSyncSpace), | |
| 24 | decor.OnComplete( | |
| 25 | newVariadicSpinner(decor.WCSyncSpace), | |
| 26 | "done", | |
| 27 | ), | |
| 26 | 28 | decor.WCSyncSpace, // Placeholder |
| 27 | 29 | ), |
| 28 | 30 | ) |
| 57 | 59 | |
| 58 | 60 | func newVariadicSpinner(wc decor.WC) decor.Decorator { |
| 59 | 61 | d := &variadicSpinner{ |
| 60 | WC: wc.Init(), | |
| 61 | d: decor.Spinner(nil), | |
| 62 | WC: wc.Init(), | |
| 63 | base: decor.Spinner(nil), | |
| 62 | 64 | } |
| 63 | 65 | return d |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | 68 | type variadicSpinner struct { |
| 67 | 69 | decor.WC |
| 68 | d decor.Decorator | |
| 69 | complete *string | |
| 70 | base decor.Decorator | |
| 70 | 71 | } |
| 71 | 72 | |
| 72 | 73 | func (d *variadicSpinner) Decor(st *decor.Statistics) string { |
| 73 | if st.Completed && d.complete != nil { | |
| 74 | return d.FormatMsg(*d.complete) | |
| 75 | } | |
| 76 | msg := d.d.Decor(st) | |
| 74 | msg := d.base.Decor(st) | |
| 77 | 75 | msg = strings.Repeat(msg, int(st.Current/3)) |
| 78 | 76 | return d.FormatMsg(msg) |
| 79 | 77 | } |
| 80 | ||
| 81 | func (d *variadicSpinner) OnCompleteMessage(msg string) { | |
| 82 | d.complete = &msg | |
| 83 | } | |
| 16 | 16 | func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) { |
| 17 | 17 | for _, decorator := range decorators { |
| 18 | 18 | if mw, ok := decorator.(mergeWrapper); ok { |
| 19 | dd := mw.MergeUnwrap() | |
| 20 | s.mDecorators = append(s.mDecorators, dd[0]) | |
| 21 | *dest = append(*dest, dd[1:]...) | |
| 19 | *dest = append(*dest, mw.MergeUnwrap()...) | |
| 22 | 20 | } |
| 23 | 21 | *dest = append(*dest, decorator) |
| 24 | 22 | } |
| 24 | 24 | } |
| 25 | 25 | decorator.SetConf(&WC{}) |
| 26 | 26 | for i, wc := range placeholders { |
| 27 | if (wc.C & DSyncWidth) == 0 { | |
| 28 | return decorator | |
| 29 | } | |
| 27 | 30 | md.placeHolders[i] = &placeHolderDecorator{ |
| 28 | WC: wc.Init(), | |
| 29 | wsync: make(chan int), | |
| 31 | WC: wc.Init(), | |
| 32 | wch: make(chan int), | |
| 30 | 33 | } |
| 31 | 34 | } |
| 32 | 35 | return md |
| 39 | 42 | } |
| 40 | 43 | |
| 41 | 44 | func (d *mergeDecorator) MergeUnwrap() []Decorator { |
| 42 | decorators := make([]Decorator, len(d.placeHolders)+1) | |
| 43 | decorators[0] = d.Decorator | |
| 45 | decorators := make([]Decorator, len(d.placeHolders)) | |
| 44 | 46 | for i, ph := range d.placeHolders { |
| 45 | decorators[i+1] = ph | |
| 47 | decorators[i] = ph | |
| 46 | 48 | } |
| 47 | 49 | return decorators |
| 48 | 50 | } |
| 51 | 53 | return d.wc.Sync() |
| 52 | 54 | } |
| 53 | 55 | |
| 56 | func (d *mergeDecorator) Base() Decorator { | |
| 57 | return d.Decorator | |
| 58 | } | |
| 59 | ||
| 54 | 60 | func (d *mergeDecorator) Decor(st *Statistics) string { |
| 55 | 61 | msg := d.Decorator.Decor(st) |
| 56 | 62 | msgLen := utf8.RuneCountInString(msg) |
| 57 | 63 | |
| 58 | var pWidth int | |
| 64 | var space int | |
| 59 | 65 | for _, ph := range d.placeHolders { |
| 60 | pWidth += <-ph.wsync | |
| 66 | space += <-ph.wch | |
| 61 | 67 | } |
| 62 | 68 | |
| 63 | d.wc.wsync <- msgLen - pWidth | |
| 69 | d.wc.wsync <- msgLen - space | |
| 64 | 70 | |
| 65 | 71 | max := <-d.wc.wsync |
| 66 | 72 | if (d.wc.C & DextraSpace) != 0 { |
| 67 | 73 | max++ |
| 68 | 74 | } |
| 69 | return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+pWidth), msg) | |
| 75 | return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+space), msg) | |
| 70 | 76 | } |
| 71 | 77 | |
| 72 | 78 | type placeHolderDecorator struct { |
| 73 | 79 | WC |
| 74 | wsync chan int | |
| 80 | wch chan int | |
| 75 | 81 | } |
| 76 | 82 | |
| 77 | 83 | func (d *placeHolderDecorator) Decor(st *Statistics) string { |
| 78 | 84 | go func() { |
| 79 | d.wsync <- utf8.RuneCountInString(d.FormatMsg("")) | |
| 85 | d.wch <- utf8.RuneCountInString(d.FormatMsg("")) | |
| 80 | 86 | }() |
| 81 | 87 | return "" |
| 82 | 88 | } |
| 8 | 8 | func OnComplete(decorator Decorator, message string) Decorator { |
| 9 | 9 | d := &onCompleteWrapper{ |
| 10 | 10 | Decorator: decorator, |
| 11 | wc: decorator.GetConf(), | |
| 12 | 11 | msg: message, |
| 13 | 12 | } |
| 14 | 13 | return d |
| 16 | 15 | |
| 17 | 16 | type onCompleteWrapper struct { |
| 18 | 17 | Decorator |
| 19 | wc WC | |
| 20 | 18 | msg string |
| 21 | 19 | } |
| 22 | 20 | |
| 23 | 21 | func (d *onCompleteWrapper) Decor(st *Statistics) string { |
| 24 | 22 | if st.Completed { |
| 25 | return d.wc.FormatMsg(d.msg) | |
| 23 | wc := d.GetConf() | |
| 24 | return wc.FormatMsg(d.msg) | |
| 26 | 25 | } |
| 27 | 26 | return d.Decorator.Decor(st) |
| 28 | 27 | } |
| 28 | ||
| 29 | func (d *onCompleteWrapper) Base() Decorator { | |
| 30 | return d.Decorator | |
| 31 | } | |