commit 0064d3f30cb971cde1ec8214224497a158bc2649
parent 50e8e54ec6f7342fdf0a90c8e3cd652e4a1ac8b9
Author: hhvn <dev@hhvn.uk>
Date: Sat, 27 Jan 2024 15:17:35 +0000
Each bar has drawing goroutine. Mutexes eliminated.
Diffstat:
M | bar/bar.go | | | 54 | +++++++++++++++++++++++++++++++++++------------------- |
M | status/00-status.go | | | 49 | ++++++++++++++++++++++++------------------------- |
2 files changed, 59 insertions(+), 44 deletions(-)
diff --git a/bar/bar.go b/bar/bar.go
@@ -2,7 +2,6 @@ package bar // import "hhvn.uk/hbspbar/bar"
import (
"fmt"
- "sync"
"image"
"errors"
"image/color"
@@ -17,11 +16,16 @@ import (
var bars map[int]*bar
+type drawinfo struct {
+ State *bspc.State
+ Blocks *status.Blocks
+}
+
type bar struct {
id int
w *drw.Window
i *image.RGBA
- drawing sync.Mutex
+ redraw chan drawinfo
}
func (b *bar) init(state *bspc.State) error {
@@ -38,10 +42,26 @@ func (b *bar) init(state *bspc.State) error {
rect := image.Rect(0, 0, int(mon.Rectangle.Width), int(config.H))
b.i = image.NewRGBA(rect)
+ b.redraw = make(chan drawinfo, 20)
+
+ go func(){
+ for d := range b.redraw {
+ // Gobble up excess redraws
+ gobble: for {
+ select {
+ case d = <- b.redraw:
+ default: break gobble
+ }
+ }
+
+ b.draw(d)
+ }
+ }()
+
return nil
}
-func (b *bar) getmon(state *bspc.State) (*bspc.Monitor, error) {
+func (b bar) getmon(state *bspc.State) (*bspc.Monitor, error) {
return state.GetMon(b.id)
}
@@ -53,12 +73,12 @@ func (b *bar) drawRect(x, y, w, h int, c color.Color, fill bool) {
drw.DrawRect(b.i, x, y, w, h, c, fill)
}
-func (b *bar) draw(state *bspc.State) {
+func (b bar) draw(d drawinfo) {
var bg color.Color
var filled bool
- b.drawing.Lock()
- defer b.drawing.Unlock()
+ state := d.State
+ blocks := d.Blocks
mon, err := b.getmon(state)
if err != nil {
@@ -117,10 +137,9 @@ func (b *bar) draw(state *bspc.State) {
cx += ax + 2
}
- status.Mutex.Lock()
cx = int(mon.Rectangle.Width) - 6
- for i := len(status.Status) - 1; i >= 0; i -= 1 {
- s, ok := status.Status[i]
+ for i := blocks.Len() - 1; i >= 0; i -= 1 {
+ s, ok := blocks.Get(i)
if ok {
cx -= s.W
cx -= config.StatusPad
@@ -133,8 +152,8 @@ func (b *bar) draw(state *bspc.State) {
config.Status, true)
cx = int(mon.Rectangle.Width) - 6
- for i := len(status.Status) - 1; i >= 0; i -= 1 {
- s, ok := status.Status[i]
+ for i := blocks.Len() - 1; i >= 0; i -= 1 {
+ s, ok := blocks.Get(i)
if ok {
cx -= s.W
@@ -143,7 +162,6 @@ func (b *bar) draw(state *bspc.State) {
cx -= config.StatusPad
}
}
- status.Mutex.Unlock()
b.w.Paint(b.i)
}
@@ -170,8 +188,8 @@ var Handle handle
var finalstate *bspc.State = nil
func init() {
- var state *bspc.State
- state = nil
+ var state *bspc.State = nil
+ var blocks *status.Blocks = nil
Handle.Create = make(chan int)
Handle.Destroy = make(chan int)
@@ -218,14 +236,14 @@ func init() {
Handle.Err <- fmt.Errorf("Couldn't create window: %s\n", err)
return
}
- case <- status.Updated:
+ case blocks = <- status.NewBlocks:
for _, b := range bars {
- go b.draw(state)
+ b.redraw <- drawinfo{state, blocks}
}
case state = <- Handle.NewState:
finalstate = state
for _, b := range bars {
- go b.draw(state)
+ b.redraw <- drawinfo{state, blocks}
}
}
}
@@ -242,8 +260,6 @@ func create(state *bspc.State, id int) (error) {
return err
}
- go b.draw(state)
-
if bars == nil {
bars = make(map[int]*bar)
}
diff --git a/status/00-status.go b/status/00-status.go
@@ -3,7 +3,6 @@ package status // import "hhvn.uk/hbspbar/status"
import (
"fmt"
"time"
- "sync"
"image"
"image/color"
@@ -12,32 +11,38 @@ import (
"hhvn.uk/hbspbar/common"
)
-var Status map[int]*status
-var Mutex sync.Mutex
-var statusid map[string]int
-var Updated chan bool
-var updates chan *status
+var NewBlocks = make(chan *Blocks)
+var updates = make(chan *status)
+var statusid = make(map[string]int)
-const (
-)
+type Blocks map[int]*status
+
+func (b *Blocks) Len() int {
+ return len(map[int]*status(*b))
+}
+
+func (b *Blocks) Get(i int) (s *status, ok bool) {
+ s, ok = (map[int]*status(*b))[i]
+ return
+}
+
+type status struct {
+ Name string
+ I *image.RGBA
+ W int
+}
func init() {
- Status = make(map[int]*status)
- statusid = make(map[string]int)
- Updated = make(chan bool)
- updates = make(chan *status)
+ status := make(map[int]*status)
go func() {
- for {
- s := <- updates
-
+ for s := range updates {
id := statusid[s.Name]
- Mutex.Lock()
- Status[id] = s
- Mutex.Unlock()
+ status[id] = s
- Updated <- true
+ b := Blocks(status)
+ NewBlocks <- &b
}
}()
}
@@ -52,12 +57,6 @@ func register(name string) {
statusid[name] = nid
}
-type status struct {
- Name string
- I *image.RGBA
- W int
-}
-
func newUpdate(name string) (*status) {
var s status