diff --git a/.golangci-soft.yml b/.golangci-soft.yml new file mode 100644 index 0000000..d325d4f --- /dev/null +++ b/.golangci-soft.yml @@ -0,0 +1,40 @@ +run: + tests: false + issues-exit-code: 0 + +issues: + include: + - EXC0001 + - EXC0005 + - EXC0011 + - EXC0012 + - EXC0013 + + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + - exhaustive + - goconst + - godot + - godox + - mnd + - gomoddirectives + - goprintffuncname + - misspell + - nakedret + - nestif + - noctx + - nolintlint + - prealloc + - wrapcheck + + # disable default linters, they are already enabled in .golangci.yml + disable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - unused diff --git a/stopwatch/stopwatch.go b/stopwatch/stopwatch.go index 8f719a4..c6b91a3 100644 --- a/stopwatch/stopwatch.go +++ b/stopwatch/stopwatch.go @@ -36,7 +36,8 @@ type TickMsg struct { // Note, however, that a stopwatch will reject ticks from other // stopwatches, so it's safe to flow all TickMsgs through all stopwatches // and have them still behave appropriately. - ID int + ID int + tag int } // StartStopMsg is sent when the stopwatch should start or stop. @@ -54,6 +55,7 @@ type ResetMsg struct { type Model struct { d time.Duration id int + tag int running bool // How long to wait before every tick. Defaults to 1 second. @@ -86,7 +88,7 @@ func (m Model) Init() (Model, tea.Cmd) { func (m Model) Start() tea.Cmd { return tea.Batch(func() tea.Msg { return StartStopMsg{ID: m.id, running: true} - }, tick(m.id, m.Interval)) + }, tick(m.id, m.tag, m.Interval)) } // Stop stops the stopwatch. @@ -133,8 +135,17 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { if !m.running || msg.ID != m.id { break } + + // If a tag is set, and it's not the one we expect, reject the message. + // This prevents the stopwatch from receiving too many messages and + // thus ticking too fast. + if msg.tag > 0 && msg.tag != m.tag { + return m, nil + } + m.d += m.Interval - return m, tick(m.id, m.Interval) + m.tag++ + return m, tick(m.id, m.tag, m.Interval) } return m, nil @@ -150,8 +161,8 @@ func (m Model) View() string { return m.d.String() } -func tick(id int, d time.Duration) tea.Cmd { +func tick(id int, tag int, d time.Duration) tea.Cmd { return tea.Tick(d, func(_ time.Time) tea.Msg { - return TickMsg{ID: id} + return TickMsg{ID: id, tag: tag} }) } diff --git a/timer/timer.go b/timer/timer.go index 378da64..22c13ae 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -74,6 +74,8 @@ type TickMsg struct { // Timeout returns whether or not this tick is a timeout tick. You can // alternatively listen for TimeoutMsg. Timeout bool + + tag int } // TimeoutMsg is a message that is sent once when the timer times out. @@ -93,6 +95,7 @@ type Model struct { Interval time.Duration id int + tag int running bool } @@ -149,6 +152,13 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { break } + // If a tag is set, and it's not the one we expect, reject the message. + // This prevents the ticker from receiving too many messages and + // thus ticking too fast. + if msg.tag > 0 && msg.tag != m.tag { + return m, nil + } + m.Timeout -= m.Interval return m, tea.Batch(m.tick(), m.timedout()) } @@ -178,7 +188,7 @@ func (m *Model) Toggle() tea.Cmd { func (m Model) tick() tea.Cmd { return tea.Tick(m.Interval, func(_ time.Time) tea.Msg { - return TickMsg{ID: m.id, Timeout: m.Timedout()} + return TickMsg{ID: m.id, tag: m.tag, Timeout: m.Timedout()} }) }