refactor: populate segments in parallel

This commit is contained in:
Jan De Dobbeleer 2020-10-13 08:57:46 +02:00 committed by Jan De Dobbeleer
parent e5213551bd
commit 0e4b8f668b
3 changed files with 34 additions and 16 deletions

View file

@ -2,6 +2,7 @@ package main
import (
"fmt"
"sync"
)
type engine struct {
@ -83,20 +84,16 @@ func (e *engine) renderSegmentText(text string) {
func (e *engine) renderBlockSegments(block *Block) string {
defer e.reset()
e.activeBlock = block
cwd := e.env.getcwd()
e.setStringValues(block.Segments)
for _, segment := range block.Segments {
if segment.hasValue(IgnoreFolders, cwd) {
continue
}
props, err := segment.mapSegmentWithWriter(e.env)
if err != nil || !segment.enabled() {
if !segment.active {
continue
}
e.activeSegment = segment
e.endPowerline()
text := segment.string()
e.activeSegment.Background = props.background
e.activeSegment.Foreground = props.foreground
e.activeSegment.Background = segment.props.background
e.activeSegment.Foreground = segment.props.foreground
e.renderSegmentText(text)
}
if e.previousActiveSegment != nil && e.previousActiveSegment.Style == Powerline {
@ -105,6 +102,22 @@ func (e *engine) renderBlockSegments(block *Block) string {
return e.renderer.string()
}
func (e *engine) setStringValues(segments []*Segment) {
wg := sync.WaitGroup{}
wg.Add(len(segments))
defer wg.Wait()
cwd := e.env.getcwd()
for _, segment := range segments {
go func(s *Segment) {
defer wg.Done()
err := s.mapSegmentWithWriter(e.env)
if err == nil && !s.hasValue(IgnoreFolders, cwd) && s.enabled() {
s.stringValue = s.string()
}
}(segment)
}
}
func (e *engine) render() {
for _, block := range e.settings.Blocks {
// if line break, append a line break

View file

@ -13,7 +13,10 @@ type Segment struct {
LeadingDiamond string `json:"leading_diamond"`
TrailingDiamond string `json:"trailing_diamond"`
Properties map[Property]interface{} `json:"properties"`
props *properties
writer SegmentWriter
stringValue string
active bool
}
//SegmentWriter is the interface used to define what and if to write to the prompt
@ -73,7 +76,8 @@ func (segment *Segment) string() string {
}
func (segment *Segment) enabled() bool {
return segment.writer.enabled()
segment.active = segment.writer.enabled()
return segment.active
}
func (segment *Segment) getValue(property Property, defaultValue string) string {
@ -96,7 +100,7 @@ func (segment *Segment) hasValue(property Property, match string) bool {
return false
}
func (segment *Segment) mapSegmentWithWriter(env environmentInfo) (*properties, error) {
func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {
functions := map[SegmentType]SegmentWriter{
Session: &session{},
Path: &path{},
@ -122,7 +126,8 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) (*properties,
}
writer.init(props, env)
segment.writer = writer
return props, nil
segment.props = props
return nil
}
return nil, errors.New("Unable to map writer")
return errors.New("Unable to map writer")
}

View file

@ -12,8 +12,8 @@ func TestMapSegmentWriterCanMap(t *testing.T) {
Type: Session,
}
env := new(MockedEnvironment)
props, err := sc.mapSegmentWithWriter(env)
assert.NotNil(t, props)
err := sc.mapSegmentWithWriter(env)
assert.NotNil(t, sc.props)
assert.NoError(t, err)
assert.NotNil(t, sc.writer)
}
@ -23,8 +23,8 @@ func TestMapSegmentWriterCannotMap(t *testing.T) {
Type: "nilwriter",
}
env := new(MockedEnvironment)
props, err := sc.mapSegmentWithWriter(env)
assert.Nil(t, props)
err := sc.mapSegmentWithWriter(env)
assert.Nil(t, sc.props)
assert.Error(t, err)
}