diff options
Diffstat (limited to 'internal/display/cpu.go')
| -rw-r--r-- | internal/display/cpu.go | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/internal/display/cpu.go b/internal/display/cpu.go new file mode 100644 index 0000000..1b9edaf --- /dev/null +++ b/internal/display/cpu.go @@ -0,0 +1,151 @@ +package display + +import ( + "sort" + + "codeberg.org/snonux/loadbars/internal/constants" + "codeberg.org/snonux/loadbars/internal/stats" + "github.com/veandco/go-sdl2/sdl" +) + +func peakPctForBar(state *runState, key string, cpuAvg int, s *[10]float64) float64 { + if !state.extended || s == nil { + return 0 + } + userSys := (*s)[0] + (*s)[1] + hist := state.peakHistory[key] + hist = append(hist, userSys) + n := cpuAvg + if n < 1 { + n = 1 + } + for len(hist) > n { + hist = hist[1:] + } + state.peakHistory[key] = hist + var max float64 + for _, v := range hist { + if v > max { + max = v + } + } + return max +} + +func sortedCPUNames(cpu map[string]stats.CPULine, cpuMode int) []string { + if cpuMode == constants.CPUModeOff { + return nil + } + var names []string + for name := range cpu { + if name == "cpu" { + names = append(names, "cpu") + continue + } + if cpuMode == constants.CPUModeCores { + names = append(names, name) + } + } + sort.Slice(names, func(i, j int) bool { + if names[i] == "cpu" { + return true + } + if names[j] == "cpu" { + return false + } + return names[i] < names[j] + }) + return names +} + +// cpuBarTargetPcts returns the 9 segment percentages (system, user, nice, idle, iowait, irq, softirq, guest, steal) from cur/prev delta. +func cpuBarTargetPcts(cur, prev stats.CPULine) (out [10]float64, ok bool) { + totalCur := cur.Total() + totalPrev := prev.Total() + if totalPrev == 0 || totalCur <= totalPrev { + return out, false + } + scale := float64(totalCur-totalPrev) / 100.0 + if scale <= 0 { + return out, false + } + out[0] = float64(cur.System-prev.System) / scale + out[1] = float64(cur.User-prev.User) / scale + out[2] = float64(cur.Nice-prev.Nice) / scale + out[3] = float64(cur.Idle-prev.Idle) / scale + out[4] = float64(cur.Iowait-prev.Iowait) / scale + out[5] = float64(cur.IRQ-prev.IRQ) / scale + out[6] = float64(cur.SoftIRQ-prev.SoftIRQ) / scale + out[7] = float64(cur.Guest-prev.Guest) / scale + out[8] = float64(cur.Steal-prev.Steal) / scale + out[9] = float64(cur.GuestNice-prev.GuestNice) / scale + for i := range out { + if out[i] < 0 { + out[i] = 0 + } + if out[i] > 100 { + out[i] = 100 + } + } + return out, true +} + +func normalizePcts(s *[10]float64) { + var sum float64 + for i := 0; i < 10; i++ { + sum += (*s)[i] + } + if sum <= 0 { + return + } + for i := 0; i < 10; i++ { + (*s)[i] = (*s)[i] * 100 / sum + } +} + +func drawCPUBarFromPcts(renderer *sdl.Renderer, s *[10]float64, barW int32, x, y, barH int32, extended bool, peakPct float64) { + renderer.SetDrawColor(constants.Black.R, constants.Black.G, constants.Black.B, 255) + renderer.FillRect(&sdl.Rect{X: x, Y: y, W: barW, H: barH}) + if s == nil { + return + } + pxPerPct := float64(barH) / 100.0 + curY := float64(y + barH) + fill := func(r, g, b uint8, pct float64) { + hh := int32(pct * pxPerPct) + if hh < 1 && pct > 0 { + hh = 1 + } + curY -= float64(hh) + renderer.SetDrawColor(r, g, b, 255) + renderer.FillRect(&sdl.Rect{X: x, Y: int32(curY), W: barW, H: hh}) + } + fill(constants.Blue.R, constants.Blue.G, constants.Blue.B, (*s)[0]) + fill(constants.Yellow.R, constants.Yellow.G, constants.Yellow.B, (*s)[1]) + fill(constants.Green.R, constants.Green.G, constants.Green.B, (*s)[2]) + fill(constants.LimeGreen.R, constants.LimeGreen.G, constants.LimeGreen.B, (*s)[9]) + fill(constants.Black.R, constants.Black.G, constants.Black.B, (*s)[3]) + fill(constants.Purple.R, constants.Purple.G, constants.Purple.B, (*s)[4]) + fill(constants.White.R, constants.White.G, constants.White.B, (*s)[5]) + fill(constants.White.R, constants.White.G, constants.White.B, (*s)[6]) + fill(constants.Red.R, constants.Red.G, constants.Red.B, (*s)[7]) + fill(constants.Red.R, constants.Red.G, constants.Red.B, (*s)[8]) + if !extended || peakPct <= 0 { + return + } + peakY := y + barH - int32(peakPct*pxPerPct) + if peakY < y { + peakY = y + } + if peakY >= y+barH { + peakY = y + barH - 1 + } + if peakPct > float64(constants.UserOrangeThreshold) { + renderer.SetDrawColor(constants.Orange.R, constants.Orange.G, constants.Orange.B, 255) + } else if peakPct > float64(constants.UserYellowThreshold) { + renderer.SetDrawColor(constants.Yellow0.R, constants.Yellow0.G, constants.Yellow0.B, 255) + } else { + renderer.SetDrawColor(constants.Yellow.R, constants.Yellow.G, constants.Yellow.B, 255) + } + renderer.FillRect(&sdl.Rect{X: x, Y: peakY, W: barW, H: 1}) +} |
