diff --git a/src/core.go b/src/core.go index 4cdf79a..7abee80 100644 --- a/src/core.go +++ b/src/core.go @@ -77,6 +77,7 @@ func Run(options *Options) { pattern := patternBuilder([]rune(patternString)) looping := true + eventBox.Unwatch(EVT_READ_NEW) for looping { eventBox.Wait(func(events *Events) { for evt, _ := range *events { @@ -87,7 +88,6 @@ func Run(options *Options) { } } }) - time.Sleep(COORDINATOR_DELAY) } matches, cancelled := matcher.scan(MatchRequest{ @@ -116,6 +116,7 @@ func Run(options *Options) { // Event coordination reading := true ticks := 0 + eventBox.Watch(EVT_READ_NEW) for { delay := true ticks += 1 diff --git a/src/eventbox.go b/src/eventbox.go index 6685e7c..95126cc 100644 --- a/src/eventbox.go +++ b/src/eventbox.go @@ -9,10 +9,14 @@ type Events map[EventType]interface{} type EventBox struct { events Events cond *sync.Cond + ignore map[EventType]bool } func NewEventBox() *EventBox { - return &EventBox{make(Events), sync.NewCond(&sync.Mutex{})} + return &EventBox{ + events: make(Events), + cond: sync.NewCond(&sync.Mutex{}), + ignore: make(map[EventType]bool)} } func (b *EventBox) Wait(callback func(*Events)) { @@ -30,7 +34,9 @@ func (b *EventBox) Set(event EventType, value interface{}) { b.cond.L.Lock() defer b.cond.L.Unlock() b.events[event] = value - b.cond.Broadcast() + if _, found := b.ignore[event]; !found { + b.cond.Broadcast() + } } // Unsynchronized; should be called within Wait routine @@ -46,3 +52,19 @@ func (b *EventBox) Peak(event EventType) bool { _, ok := b.events[event] return ok } + +func (b *EventBox) Watch(events ...EventType) { + b.cond.L.Lock() + defer b.cond.L.Unlock() + for _, event := range events { + delete(b.ignore, event) + } +} + +func (b *EventBox) Unwatch(events ...EventType) { + b.cond.L.Lock() + defer b.cond.L.Unlock() + for _, event := range events { + b.ignore[event] = true + } +} diff --git a/src/eventbox_test.go b/src/eventbox_test.go new file mode 100644 index 0000000..fb0ceed --- /dev/null +++ b/src/eventbox_test.go @@ -0,0 +1,51 @@ +package fzf + +import "testing" + +func TestEventBox(t *testing.T) { + eb := NewEventBox() + + // Wait should return immediately + ch := make(chan bool) + + go func() { + eb.Set(EVT_READ_NEW, 10) + ch <- true + <-ch + eb.Set(EVT_SEARCH_NEW, 10) + eb.Set(EVT_SEARCH_NEW, 15) + eb.Set(EVT_SEARCH_NEW, 20) + eb.Set(EVT_SEARCH_PROGRESS, 30) + ch <- true + <-ch + eb.Set(EVT_SEARCH_FIN, 40) + ch <- true + <-ch + }() + + count := 0 + sum := 0 + looping := true + for looping { + <-ch + eb.Wait(func(events *Events) { + for _, value := range *events { + switch val := value.(type) { + case int: + sum += val + looping = sum < 100 + } + } + events.Clear() + }) + ch <- true + count += 1 + } + + if count != 3 { + t.Error("Invalid number of events", count) + } + if sum != 100 { + t.Error("Invalid sum", sum) + } +}