From 5d00de091ce0b7c6448327a88fc7c040025edb7d Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 3 Jun 2019 12:15:25 +0200 Subject: ui: cache last observed state Sometimes State() is out of sync with the notifications when a service removal is pending. This unifies that, and also removes IPC from the main thread. Signed-off-by: Jason A. Donenfeld --- ui/listview.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'ui/listview.go') diff --git a/ui/listview.go b/ui/listview.go index ebdf3260..71e5df48 100644 --- a/ui/listview.go +++ b/ui/listview.go @@ -20,7 +20,8 @@ type ListModel struct { walk.TableModelBase walk.SorterBase - tunnels []manager.Tunnel + tunnels []manager.Tunnel + lastObservedState map[manager.Tunnel]manager.TunnelState } func (t *ListModel) RowCount() int { @@ -62,6 +63,7 @@ func NewListView(parent walk.Container) (*ListView, error) { tv.SetDoubleBuffering(true) model := new(ListModel) + model.lastObservedState = make(map[manager.Tunnel]manager.TunnelState) tv.SetModel(model) tv.SetLastColumnStretched(true) tv.SetHeaderHidden(true) @@ -113,10 +115,16 @@ func (tv *ListView) StyleCell(style *walk.CellStyle) { b.Width -= b.Height canvas.DrawText(tunnel.Name, tv.Font(), style.TextColor, b, walk.TextVCenter|walk.TextSingleLine) - //TODO: don't make an IPC call from the drawing thread like this! - state, err := tunnel.State() - if err != nil { - return + var state manager.TunnelState + var ok bool + state, ok = tv.model.lastObservedState[tv.model.tunnels[row]] + if !ok { + var err error + state, err = tunnel.State() + if err != nil { + return + } + tv.model.lastObservedState[tv.model.tunnels[row]] = state } const margin = 2 b.X = margin @@ -150,6 +158,7 @@ func (tv *ListView) onTunnelChange(tunnel *manager.Tunnel, state manager.TunnelS } if idx != -1 { + tv.model.lastObservedState[tv.model.tunnels[idx]] = state tv.model.PublishRowChanged(idx) return } @@ -193,6 +202,7 @@ func (tv *ListView) Load(asyncUI bool) { if t.Name == tunnel.Name { tv.model.tunnels = append(tv.model.tunnels[:i], tv.model.tunnels[i+1:]...) tv.model.PublishRowsRemoved(i, i) //TODO: Do we have to call that everytime or can we pass a range? + delete(tv.model.lastObservedState, t) break } } -- cgit v1.2.3-59-g8ed1b