From e2b87a41f878d37d5e9063204ccd27fcabc5abc4 Mon Sep 17 00:00:00 2001 From: David Florness Date: Tue, 19 Jan 2021 21:07:59 -0500 Subject: [PATCH] Properly sort elections by room in TUI --- election/map.go | 34 ++++++++++++++++++---------------- ui/tui.go | 19 ++++++++++++++----- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/election/map.go b/election/map.go index ac4be84..8999934 100644 --- a/election/map.go +++ b/election/map.go @@ -7,6 +7,7 @@ import ( "os" "sort" "sync" + "time" log "github.com/sirupsen/logrus" @@ -16,8 +17,12 @@ import ( type ElectionsMap struct { sync.RWMutex - M map[id.EventID]*Election - L []*Election // sorted list of elections by CreationTimestamp (newest to oldest) + M map[id.EventID]*Election + + // by room, sorted list of elections by CreationTimestamp (newest to oldest) + L map[id.RoomID][]*Election + Ltime time.Time // last time list was update + Joins map[id.EventID]*Voter Save func() } @@ -43,7 +48,8 @@ func GetElections() (elections *ElectionsMap, err error) { func NewElectionsMap() *ElectionsMap { em := &ElectionsMap{ M: make(map[id.EventID]*Election), - L: make([]*Election, 0), + L: make(map[id.RoomID][]*Election, 0), + Ltime: time.Now(), Joins: make(map[id.EventID]*Voter), } em.Save = func() { @@ -73,7 +79,7 @@ func (em *ElectionsMap) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &em.M); err != nil { return err } - em.L = make([]*Election, 0) + em.L = make(map[id.RoomID][]*Election, 0) for createEventId, el := range em.M { em.insort(createEventId, el) } @@ -100,12 +106,6 @@ func (em *ElectionsMap) GetOk(createEventID id.EventID) (*Election, bool) { return el, ok } -func (em *ElectionsMap) GetI(i int) *Election { - em.RLock() - defer em.RUnlock() - return em.L[i] -} - func (em *ElectionsMap) SetIfNotExists(createEventID id.EventID, el *Election) { em.Lock() defer em.Save() @@ -126,12 +126,14 @@ func (em *ElectionsMap) set(createEventID id.EventID, el *Election) { } func (em *ElectionsMap) insort(createEventID id.EventID, el *Election) { - i := sort.Search(len(em.L), func(i int) bool { - return em.L[i].CreationTimestamp < el.CreationTimestamp + list := em.L[el.RoomID] + i := sort.Search(len(list), func(i int) bool { + return list[i].CreationTimestamp < el.CreationTimestamp }) - newList := make([]*Election, len(em.L)+1) - copy(newList[:i], em.L[:i]) + newList := make([]*Election, len(list)+1) + copy(newList[:i], list[:i]) newList[i] = el - copy(newList[i+1:], em.L[i:]) - em.L = newList + copy(newList[i+1:], list[i:]) + em.L[el.RoomID] = newList + em.Ltime = time.Now() } diff --git a/ui/tui.go b/ui/tui.go index e3e8027..b69bf10 100644 --- a/ui/tui.go +++ b/ui/tui.go @@ -70,15 +70,17 @@ func RoomTUI(client *mautrix.Client, roomID id.RoomID, elections *election.Elect app := tview.NewApplication() list := tview.NewList(). AddItem("Create Election", "start a new election in this room", '+', nil) - n := 0 + var L []*election.Election + var Ltime time.Time = elections.Ltime.Add(-1 * time.Millisecond) update := func() { elections.RLock() defer elections.RUnlock() - if n == len(elections.L) { + if !Ltime.Before(elections.Ltime) { return } - n = len(elections.L) - for i, el := range elections.L { + L = elections.L[roomID] + Ltime = elections.Ltime + for i, el := range L { title := el.Title if title == "" { title = "" @@ -104,11 +106,18 @@ func RoomTUI(client *mautrix.Client, roomID id.RoomID, elections *election.Elect list.SetSelectedFunc(func(i int, _ string, _ string, _ rune) { alive = false app.Stop() + elections.RLock() + // don't do anything if the election under the cursor has + // changed + if Ltime.Before(elections.Ltime) && L[i] != elections.L[roomID][i] { + return + } + elections.RUnlock() if i > 0 { // user wants to join election - el = elections.GetI(i - 1) + el = L[i - 1] // don't need to lock because this goroutine controls LocalVoter if el.LocalVoter != nil { if el.LocalVoter.Ballot == nil { -- 2.38.4