From 0e4b8f668b75280ec4ec7a36928d6344f4b91577 Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Tue, 13 Oct 2020 08:57:46 +0200 Subject: [PATCH] refactor: populate segments in parallel --- engine.go | 29 +++++++++++++++++++++-------- segment.go | 13 +++++++++---- segment_test.go | 8 ++++---- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/engine.go b/engine.go index 4d578b91..2badf4b2 100644 --- a/engine.go +++ b/engine.go @@ -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 diff --git a/segment.go b/segment.go index 1ea916fe..fe0e1740 100644 --- a/segment.go +++ b/segment.go @@ -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") } diff --git a/segment_test.go b/segment_test.go index c6a6812e..d805dabd 100755 --- a/segment_test.go +++ b/segment_test.go @@ -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) }