Snapshot mutable tree display state
This commit is contained in:
committed by
Brandon McGinty
parent
461f172035
commit
b407a20132
@@ -16,6 +16,10 @@ import (
|
|||||||
type TreeItem struct {
|
type TreeItem struct {
|
||||||
User *gumble.User
|
User *gumble.User
|
||||||
Channel *gumble.Channel
|
Channel *gumble.Channel
|
||||||
|
display string
|
||||||
|
userSession uint32
|
||||||
|
channelID uint32
|
||||||
|
snapshot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Barnard struct {
|
type Barnard struct {
|
||||||
|
|||||||
+44
-18
@@ -8,6 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ti TreeItem) String() string {
|
func (ti TreeItem) String() string {
|
||||||
|
if ti.display != "" {
|
||||||
|
return ti.display
|
||||||
|
}
|
||||||
if ti.User != nil {
|
if ti.User != nil {
|
||||||
if ti.User.LocallyMuted() {
|
if ti.User.LocallyMuted() {
|
||||||
return "[MUTED] " + esc(ti.User.Name)
|
return "[MUTED] " + esc(ti.User.Name)
|
||||||
@@ -94,7 +97,13 @@ func (b *Barnard) TreeItemBuild(item uiterm.TreeItem) []uiterm.TreeItem {
|
|||||||
if root == nil {
|
if root == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return []uiterm.TreeItem{TreeItem{Channel: root}}
|
var display string
|
||||||
|
var channelID uint32
|
||||||
|
b.Client.Do(func() {
|
||||||
|
display = "#" + esc(root.Name)
|
||||||
|
channelID = root.ID
|
||||||
|
})
|
||||||
|
return []uiterm.TreeItem{TreeItem{Channel: root, display: display, channelID: channelID, snapshot: true}}
|
||||||
} else {
|
} else {
|
||||||
treeItem = ti
|
treeItem = ti
|
||||||
}
|
}
|
||||||
@@ -104,41 +113,52 @@ func (b *Barnard) TreeItemBuild(item uiterm.TreeItem) []uiterm.TreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
users := []uiterm.TreeItem{}
|
users := []uiterm.TreeItem{}
|
||||||
ul := []*gumble.User{}
|
type userDisplay struct {
|
||||||
cl := []*gumble.Channel{}
|
user *gumble.User
|
||||||
|
display string
|
||||||
|
name string
|
||||||
|
session uint32
|
||||||
|
}
|
||||||
|
type channelDisplay struct {
|
||||||
|
channel *gumble.Channel
|
||||||
|
name string
|
||||||
|
id uint32
|
||||||
|
}
|
||||||
|
ul := []userDisplay{}
|
||||||
|
cl := []channelDisplay{}
|
||||||
// TCP handlers mutate both maps; snapshot them while Client.Do holds its
|
// TCP handlers mutate both maps; snapshot them while Client.Do holds its
|
||||||
// read lock, then sort/render outside the protocol critical section.
|
// read lock, then sort/render outside the protocol critical section.
|
||||||
b.Client.Do(func() {
|
b.Client.Do(func() {
|
||||||
for _, user := range treeItem.Channel.Users {
|
for _, user := range treeItem.Channel.Users {
|
||||||
ul = append(ul, user)
|
boostPercent := float32(user.Boost()-1) * 10
|
||||||
|
totalVolume := user.Volume()*100 + boostPercent
|
||||||
|
display := fmt.Sprintf("%s [%.0f%%]", esc(user.Name), totalVolume)
|
||||||
|
if user.LocallyMuted() {
|
||||||
|
display = "[MUTED] " + display
|
||||||
|
}
|
||||||
|
ul = append(ul, userDisplay{user: user, name: user.Name, session: user.Session, display: display})
|
||||||
}
|
}
|
||||||
for _, subchannel := range treeItem.Channel.Children {
|
for _, subchannel := range treeItem.Channel.Children {
|
||||||
cl = append(cl, subchannel)
|
cl = append(cl, channelDisplay{channel: subchannel, name: subchannel.Name, id: subchannel.ID})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
sort.Slice(ul, func(i, j int) bool {
|
sort.Slice(ul, func(i, j int) bool {
|
||||||
return ul[i].Name < ul[j].Name
|
return ul[i].name < ul[j].name
|
||||||
})
|
})
|
||||||
for _, user := range ul {
|
for _, user := range ul {
|
||||||
users = append(users, TreeItem{
|
users = append(users, TreeItem{User: user.user, display: user.display, userSession: user.session, snapshot: true})
|
||||||
User: user,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channels := []uiterm.TreeItem{}
|
channels := []uiterm.TreeItem{}
|
||||||
sort.Slice(cl, func(i, j int) bool {
|
sort.Slice(cl, func(i, j int) bool {
|
||||||
return cl[i].Name < cl[j].Name
|
return cl[i].name < cl[j].name
|
||||||
})
|
})
|
||||||
for _, subchannel := range cl {
|
for _, subchannel := range cl {
|
||||||
displayName := subchannel.Name
|
displayName := "#" + esc(subchannel.name)
|
||||||
if b.isChannelMuted(subchannel.ID) {
|
if b.isChannelMuted(subchannel.id) {
|
||||||
displayName = "[MUTED] #" + displayName
|
displayName = "[MUTED] " + displayName
|
||||||
} else {
|
|
||||||
displayName = "#" + displayName
|
|
||||||
}
|
}
|
||||||
channels = append(channels, TreeItem{
|
channels = append(channels, TreeItem{Channel: subchannel.channel, display: displayName, channelID: subchannel.id, snapshot: true})
|
||||||
Channel: subchannel,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(users, channels...)
|
return append(users, channels...)
|
||||||
@@ -158,9 +178,15 @@ func sameUserChannelTreeItem(previous, current uiterm.TreeItem) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if prev.User != nil && cur.User != nil {
|
if prev.User != nil && cur.User != nil {
|
||||||
|
if prev.snapshot && cur.snapshot {
|
||||||
|
return prev.userSession == cur.userSession
|
||||||
|
}
|
||||||
return prev.User.Session == cur.User.Session
|
return prev.User.Session == cur.User.Session
|
||||||
}
|
}
|
||||||
if prev.Channel != nil && cur.Channel != nil {
|
if prev.Channel != nil && cur.Channel != nil {
|
||||||
|
if prev.snapshot && cur.snapshot {
|
||||||
|
return prev.channelID == cur.channelID
|
||||||
|
}
|
||||||
return prev.Channel.ID == cur.Channel.ID
|
return prev.Channel.ID == cur.Channel.ID
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.stormux.org/storm/barnard/gumble/gumble"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTreeItemUsesCapturedDisplaySnapshot(t *testing.T) {
|
||||||
|
user := &gumble.User{Name: "before"}
|
||||||
|
item := TreeItem{User: user, display: "before [100%]"}
|
||||||
|
user.Name = "after"
|
||||||
|
if got := item.String(); got != "before [100%]" {
|
||||||
|
t.Fatalf("tree display read mutable user state: %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user