Skip to content

Commit

Permalink
no mutex, only channel
Browse files Browse the repository at this point in the history
  • Loading branch information
tsukinoko-kun committed Jan 28, 2024
1 parent 1bfe49d commit 144a1b0
Showing 1 changed file with 11 additions and 46 deletions.
57 changes: 11 additions & 46 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package fyneflow

import (
"errors"
"sync"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/data/binding"
Expand All @@ -16,13 +15,10 @@ type FlowItem struct {

type Flow struct {
window fyne.Window
flowMut sync.Mutex
current string
next string
signal chan struct{}
next chan string
items map[string]*FlowItem

stateMut sync.Mutex
strState map[string]binding.String
intState map[string]binding.Int
close bool
Expand All @@ -36,19 +32,16 @@ type Flow struct {
func NewFlow(w fyne.Window) *Flow {
f := new(Flow)
f.window = w
f.flowMut = sync.Mutex{}
f.items = make(map[string]*FlowItem)
f.signal = make(chan struct{}, 1)
f.next = make(chan string, 1)
go f.loop()
return f
}

// Close closes the Flow.
// This will not close the associated fyne.Window!
func (f *Flow) Close() {
f.signal <- struct{}{}
f.flowMut.Lock()
defer f.flowMut.Unlock()
f.next <- ""

f.close = true
for k := range f.items {
Expand All @@ -58,88 +51,63 @@ func (f *Flow) Close() {

func (f *Flow) loop() {
for !f.close {
<-f.signal
if f.next != f.current {
f.apply()
next := <-f.next
if next != f.current {
f.apply(next)
}
}
}

// Set adds a FlowItem to the Flow.
// If the key already exists, the FlowItem will be overwritten.
func (f *Flow) Set(key string, generator FlowItemGenerator) *FlowItem {
f.flowMut.Lock()
defer f.flowMut.Unlock()

fi := new(FlowItem)
fi.generator = generator
apply := len(f.items) == 0
f.items[key] = fi
if apply {
f.next = key
f.next <- key
}
f.signal <- struct{}{}
return fi
}

// GoTo sets the content of the window to the content of the FlowItem associated with the given key.
// If the key is not found, an error is returned.
func (f *Flow) GoTo(key string) error {
f.flowMut.Lock()
defer f.flowMut.Unlock()

if f.current == key {
return nil
}

if _, ok := f.items[key]; ok {
f.next = key
f.signal <- struct{}{}
f.next <- key
return nil
} else {
return errors.New("flow: key not found")
}
}

func (f *Flow) apply() {
f.flowMut.Lock()
defer f.flowMut.Unlock()

fi, ok := f.items[f.next]
func (f *Flow) apply(next string) {
fi, ok := f.items[next]
if !ok || fi == nil {
return
}

obj := fi.generator()

f.window.SetContent(obj)
f.current = f.next
f.current = next
}

// Current returns the key of the FlowItem that is currently displayed.
func (f *Flow) Current() string {
f.flowMut.Lock()
defer f.flowMut.Unlock()

return f.current
}

// Next returns the key of the FlowItem that will be displayed next.
func (f *Flow) Next() string {
f.flowMut.Lock()
defer f.flowMut.Unlock()

return f.next
}

// UseStateStr returns a binding.String that is associated with the given key.
// If the key does not exist, a new binding.String is created with the given default value.
// If the key does exist, the default value is ignored.
// The returned binding.String is shared between all FlowItems of the Flow.
func (f *Flow) UseStateStr(key string, def string) binding.String {
f.stateMut.Lock()
defer f.stateMut.Unlock()

if f.strState == nil {
f.strState = make(map[string]binding.String)
}
Expand All @@ -157,9 +125,6 @@ func (f *Flow) UseStateStr(key string, def string) binding.String {
// If the key does exist, the default value is ignored.
// The returned binding.Int is shared between all FlowItems of the Flow.
func (f *Flow) UseStateInt(key string, def int) binding.Int {
f.stateMut.Lock()
defer f.stateMut.Unlock()

if f.intState == nil {
f.intState = make(map[string]binding.Int)
}
Expand Down

0 comments on commit 144a1b0

Please sign in to comment.