Commit 3e5adb86 authored by liming6's avatar liming6
Browse files

feature 添加进程选择功能

parent c915d1bd
......@@ -8,6 +8,7 @@ import (
"get-container/utils"
"math"
"os"
"sort"
"strconv"
"strings"
"sync"
......@@ -364,7 +365,8 @@ func (m *DCUInfoMap) GetDCUProcessInfo2() map[int][]DCUProcessInfo {
pids = append(pids, int32(v.Pid))
}
pinfo := getProcessInfo(pids)
for _, v := range info {
for _, v := range info { // 按照进程遍历
// 获取进程使用的所有dcu的索引
index := make([]int, 0)
for _, i := range v.HCUIndex {
ii, err := strconv.Atoi(i)
......@@ -384,9 +386,17 @@ func (m *DCUInfoMap) GetDCUProcessInfo2() map[int][]DCUProcessInfo {
item.DCUMem = v.VRamUsed.HumanReadStr(1)
item.SDMA = v.SDMAUsed
l = append(l, item)
result[i] = l
}
}
// 每个切片对pid排序
for k, v := range result {
sort.SliceStable(v, func(i, j int) bool {
return v[i].Info.Pid < v[j].Info.Pid
})
result[k] = v
}
return result
}
......
......@@ -21,7 +21,7 @@ func main() {
log.Fatalf("error init data backend: %v", err)
}
model := tui.NewModelMain(w, h)
if _, err := tea.NewProgram(&model).Run(); err != nil {
if _, err := tea.NewProgram(&model, tea.WithAltScreen()).Run(); err != nil {
log.Fatalf("error create program; %v", err)
}
backend.Shutdown()
......
......@@ -10,14 +10,18 @@ import (
"github.com/charmbracelet/bubbles/progress"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/lucasb-eyer/go-colorful"
"github.com/muesli/gamut"
"github.com/muesli/termenv"
)
type ModelDCUInfo struct {
pro progress.Model // 进度条
proLowLeight progress.Model // 低亮度进度条
proWidth int // 进度条宽度
modMsg *ModelMsg
width, height int
actionMsg *ActionMsg
}
const (
......@@ -46,7 +50,10 @@ func (m *ModelDCUInfo) Init() tea.Cmd {
if m.width > StaticWidth+ProgressMinWidth+OtherWidth {
m.proWidth = m.width - OtherWidth - StaticWidth
}
m.pro = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient("#0000ffff", "#ff0000ff"), progress.WithWidth(m.proWidth))
m.pro = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient("#0000ffff", "#ff0000ff"), progress.WithWidth(m.proWidth-5), progress.WithoutPercentage())
c1, _ := colorful.MakeColor(gamut.Darker(lipgloss.Color("#0000ffff"), 0.8))
c2, _ := colorful.MakeColor(gamut.Darker(lipgloss.Color("#ff0000ff"), 0.8))
m.proLowLeight = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient(c1.Hex(), c2.Hex()), progress.WithWidth(m.proWidth-5), progress.WithoutPercentage())
return nil
}
......@@ -59,6 +66,9 @@ func (m *ModelDCUInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
m.height = msg.Height
m.width = msg.Width
return m, nil
case *ActionMsg:
m.actionMsg = msg
return m, nil
}
return m, nil
}
......@@ -72,77 +82,146 @@ func (m *ModelDCUInfo) View() string {
smap, slock := m.modMsg.DCUInfo.GetSlowInfo()
defer slock.Unlock()
defer qlock.Unlock()
conTime := 0
strBuilder := strings.Builder{}
strCache := strings.Builder{}
var targetDCU int = -1
if m.actionMsg != nil && m.actionMsg.TargetDCUIndex != nil {
targetDCU = *m.actionMsg.TargetDCUIndex
}
infos := make([]string, 0)
for i := range 128 {
for i := range 64 {
qinfo, haveq := qmap[i]
sinfo, haves := smap[i]
if !(haveq || haves) {
conTime++
if conTime > 8 {
break
}
continue
}
isLowStyle := (targetDCU != qinfo.Id && targetDCU != -1)
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(strconv.Itoa(qinfo.Id), 4, lipgloss.Left))
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(ReDCUName.FindString(qinfo.Name), 8, lipgloss.Left))
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(qinfo.PerformanceLevel, 15, lipgloss.Right))
strBuilder.WriteByte(' ')
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(qinfo.BusId, 13, lipgloss.Left))
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr("Off", 6, lipgloss.Right))
strBuilder.WriteByte(' ')
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(strconv.Itoa(qinfo.Id), 4, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(ReDCUName.FindString(qinfo.Name), 8, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(qinfo.PerformanceLevel, 15, lipgloss.Right))
strCache.WriteByte(' ')
if isLowStyle {
str := strCache.String()
strBuilder.WriteString(LowLeightStyle.Render(str))
} else {
strBuilder.WriteString(strCache.String())
}
strCache.Reset()
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte(' ')
if sinfo.Mig.Load() {
strBuilder.WriteString(FormatStr("On", 16, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(qinfo.BusId, 13, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr("Off", 6, lipgloss.Right))
strCache.WriteByte(' ')
if isLowStyle {
str := strCache.String()
strBuilder.WriteString(LowLeightStyle.Render(str))
} else {
strBuilder.WriteString(FormatStr("Off", 16, lipgloss.Left))
strBuilder.WriteString(strCache.String())
}
strBuilder.WriteByte(' ')
strCache.Reset()
strCache.WriteByte(' ')
strCache.WriteString(FormatStr("Off", 16, lipgloss.Left))
strBuilder.WriteString(myBorder.Left)
strCache.WriteByte(' ')
if sinfo.Ecc.Load() {
strBuilder.WriteString(FormatStr("On", 3, lipgloss.Right))
strCache.WriteString(FormatStr("On", 3, lipgloss.Right))
} else {
strCache.WriteString(FormatStr("Off", 3, lipgloss.Right))
}
strCache.WriteByte(' ')
if isLowStyle {
str := strCache.String()
strBuilder.WriteString(LowLeightStyle.Render(str))
} else {
strBuilder.WriteString(FormatStr("Off", 3, lipgloss.Right))
strBuilder.WriteString(strCache.String())
}
strBuilder.WriteByte(' ')
strCache.Reset()
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteString(" DCU: ")
strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.DCUUTil / 100)))
strBuilder.WriteByte(' ')
if isLowStyle {
strBuilder.WriteString(LowLeightStyle.Render(" DCU: "))
strBuilder.WriteString(m.proLowLeight.ViewAs(float64(qinfo.DCUUTil / 100)))
strBuilder.WriteString(LowLeightStyle.Render(fmt.Sprintf(" %3d%% ", int(qinfo.DCUUTil))))
} else {
strBuilder.WriteString(" DCU: ")
strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.DCUUTil / 100)))
strBuilder.WriteString(fmt.Sprintf(" %3d%% ", int(qinfo.DCUUTil)))
}
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte('\n')
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(qinfo.Fan, 4, lipgloss.Left))
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(fmt.Sprintf("%.1fC", qinfo.Temp), 6, lipgloss.Left))
strBuilder.WriteByte(' ')
// 18
strBuilder.WriteString(FormatStr(fmt.Sprintf("%.1fW / %.1fW", qinfo.PwrAvg, qinfo.PwrCap), 17, lipgloss.Right))
strBuilder.WriteByte(' ')
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(qinfo.Fan, 4, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(fmt.Sprintf("%.1fC", qinfo.Temp), 6, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(fmt.Sprintf("%.1fW / %.1fW", qinfo.PwrAvg, qinfo.PwrCap), 17, lipgloss.Right))
strCache.WriteByte(' ')
if isLowStyle {
str := strCache.String()
strBuilder.WriteString(LowLeightStyle.Render(str))
} else {
strBuilder.WriteString(strCache.String())
}
strCache.Reset()
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte(' ')
// 20
strBuilder.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
strBuilder.WriteByte(' ')
if isLowStyle {
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
strCache.WriteByte(' ')
strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
strCache.Reset()
} else {
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
strBuilder.WriteByte(' ')
}
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
strBuilder.WriteByte(' ')
if isLowStyle {
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
strCache.WriteByte(' ')
strCache.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
strCache.WriteByte(' ')
strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
strCache.Reset()
} else {
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
strBuilder.WriteByte(' ')
strBuilder.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
strBuilder.WriteByte(' ')
}
strBuilder.WriteString(myBorder.Left)
strBuilder.WriteString(" Mem: ")
strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
strBuilder.WriteByte(' ')
if isLowStyle {
strCache.WriteString(" Mem: ")
strCache.WriteString(m.proLowLeight.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
strCache.WriteString(LowLeightStyle.Render(fmt.Sprintf(" %3d%% ", int(100*float64(qinfo.MemUsed)/float64(qinfo.MemTotal)))))
strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
strCache.Reset()
} else {
strBuilder.WriteString(" Mem: ")
strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
strBuilder.WriteByte(' ')
strBuilder.WriteString(fmt.Sprintf("%3d%%", int(100*float64(qinfo.MemUsed)/float64(qinfo.MemTotal))))
strBuilder.WriteByte(' ')
}
strBuilder.WriteString(myBorder.Left)
infos = append(infos, strBuilder.String())
strBuilder.Reset()
......
......@@ -4,6 +4,7 @@ import (
"get-container/cmd/hytop/backend"
"get-container/gpu"
"get-container/utils"
"syscall"
"time"
tea "github.com/charmbracelet/bubbletea"
......@@ -14,6 +15,15 @@ const (
DCUTopVersion = "1.0.0"
)
var (
HeightLightStyle = lipgloss.NewStyle().Background(lipgloss.Color("#00fffb7a")) // 高亮风格
SelectedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#ffb81fe3")) // 被选中的风格
HeightSelectedStyle = lipgloss.NewStyle().Background(lipgloss.Color("#ffb81fe3")) // 既被选中,又高亮的风格
LowLeightStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#442d2d"))
NormalStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#e6e6e6eb"))
)
// ModelMsg 模型信息,在父组件和各个子组件间共享信息
type ModelMsg struct {
t time.Time // 当前时间
......@@ -26,6 +36,17 @@ type ModelMsg struct {
type TickMsg time.Time
// ActionMsg 动作消息
type ActionMsg struct {
SelectPids map[int32]bool // 选择的pid进程
Action *syscall.Signal // 对选择的pid的动作
PidView *int32 // 进程视图指标的pid号,为null表示没有进入进程指标视图
PointPid *int32 // 指针指向的pid,为null表示没有选择进程
PidEnvView *int32 // 进程环境变量视图的pid号,为null表示不进入进程环境变量视图
PidTreeView *int32 // 进入pstree视图的pid号,为null表示不进入pstree视图
TargetDCUIndex *int // PointPid使用的dcu index
}
// ModelMain tui主模型类
type ModelMain struct {
width, height int // 终端尺寸
......@@ -34,6 +55,7 @@ type ModelMain struct {
SysLoad *ModelSysLoad
ProcessInfo *ModelProcessInfo
modelMsg *ModelMsg
actionMsg *ActionMsg
}
func NewModelMain(width, height int) ModelMain {
......@@ -44,6 +66,7 @@ func NewModelMain(width, height int) ModelMain {
result.DCUInfo = NewModelDCUInfo(width, height)
result.SysLoad = NewModelSysLoad(width)
result.ProcessInfo = NewModelProcessInfo(width)
result.actionMsg = &ActionMsg{}
return result
}
......@@ -90,6 +113,24 @@ func (m *ModelMain) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case "up":
cmd := m.handleKeyUp()
return m, cmd
case "down":
cmd := m.handleKeyDown()
return m, cmd
case "enter":
return m, tea.Quit
case "h":
return m, tea.Quit
case "k":
return m, tea.Quit
case "esc":
cmd := m.handleKeyEsc()
return m, cmd
case " ":
cmd := m.handleKeySpace()
return m, cmd
}
case TickMsg: // 定时事件
updateModelInfo(m.modelMsg, time.Time(msg))
......@@ -127,6 +168,28 @@ func (m *ModelMain) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
func (m *ModelMain) handleKeyEsc() tea.Cmd {
return nil
}
func (m *ModelMain) handleKeySpace() tea.Cmd {
if m.actionMsg == nil || m.actionMsg.PointPid == nil {
return nil
}
if m.actionMsg.SelectPids == nil {
m.actionMsg.SelectPids = make(map[int32]bool)
}
_, have := m.actionMsg.SelectPids[*m.actionMsg.PointPid]
if have {
delete(m.actionMsg.SelectPids, *m.actionMsg.PointPid)
} else {
m.actionMsg.SelectPids[*m.actionMsg.PointPid] = true
}
m1, cmd1 := m.ProcessInfo.Update(m.actionMsg)
m.ProcessInfo = m1.(*ModelProcessInfo)
return cmd1
}
func (m *ModelMain) View() string {
return m.Header.View() + m.DCUInfo.View() + m.SysLoad.View() + m.ProcessInfo.View() + "\n"
}
......@@ -185,3 +248,100 @@ func updateModelInfo(modelMsg *ModelMsg, t time.Time) error {
}
return nil
}
func (m *ModelMain) handleKeyUp() tea.Cmd {
if m.actionMsg == nil {
m.actionMsg = &ActionMsg{}
}
if m.modelMsg.DCUPidInfo == nil {
return nil
}
processes := make([]backend.DCUProcessInfo, 0)
for index := range 64 {
p, have := m.modelMsg.DCUPidInfo[index]
if have && len(p) > 0 {
processes = append(processes, p...)
}
}
processNum := len(processes)
if processNum == 0 {
return nil
}
index := 0
if m.actionMsg.PointPid == nil {
// 获取列表中的最后一个进程的pid
index = processNum - 1
} else {
var targetIndex = -1
for l := processNum - 1; l >= 0; l-- {
if processes[l].Info.Pid == *m.actionMsg.PointPid {
targetIndex = l - 1
break
}
}
if targetIndex == -1 {
index = processNum - 1
} else {
index = targetIndex
}
}
pid := processes[index].Info.Pid
m.actionMsg.PointPid = &pid
idx := processes[index].DCU
m.actionMsg.TargetDCUIndex = &idx
m1, cmd1 := m.ProcessInfo.Update(m.actionMsg)
m2, cmd2 := m.DCUInfo.Update(m.actionMsg)
m.ProcessInfo = m1.(*ModelProcessInfo)
m.DCUInfo = m2.(*ModelDCUInfo)
return tea.Batch(cmd1, cmd2)
}
func (m *ModelMain) handleKeyDown() tea.Cmd {
if m.actionMsg == nil {
m.actionMsg = &ActionMsg{}
}
if m.modelMsg.DCUPidInfo == nil {
return nil
}
processes := make([]backend.DCUProcessInfo, 0)
for index := range 64 {
p, have := m.modelMsg.DCUPidInfo[index]
if have && len(p) > 0 {
processes = append(processes, p...)
}
}
processNum := len(processes)
if processNum == 0 {
return nil
}
index := 0
if m.actionMsg.PointPid == nil {
index = 0
} else {
var targetIndex = -1
for l := 0; l < processNum-1; l++ {
if processes[l].Info.Pid == *m.actionMsg.PointPid {
targetIndex = l + 1
if targetIndex >= processNum {
targetIndex = 0
}
break
}
}
if targetIndex == -1 {
index = 0
} else {
index = targetIndex
}
}
pid := processes[index].Info.Pid
m.actionMsg.PointPid = &pid
idx := processes[index].DCU
m.actionMsg.TargetDCUIndex = &idx
m1, cmd1 := m.ProcessInfo.Update(m.actionMsg)
m2, cmd2 := m.DCUInfo.Update(m.actionMsg)
m.ProcessInfo = m1.(*ModelProcessInfo)
m.DCUInfo = m2.(*ModelDCUInfo)
return tea.Batch(cmd1, cmd2)
}
......@@ -20,6 +20,7 @@ type ModelProcessInfo struct {
width int
style lipgloss.Style
modMsg *ModelMsg
actionMsg *ActionMsg
}
const (
......@@ -61,8 +62,13 @@ func (m *ModelProcessInfo) Init() tea.Cmd {
func (m *ModelProcessInfo) View() string {
haveProcess := false
var heightLightPid int32 = 0
if m.actionMsg != nil && m.actionMsg.PointPid != nil {
heightLightPid = *m.actionMsg.PointPid
}
lines := make([]string, 0)
sb := strings.Builder{}
sbInner := strings.Builder{}
for index := range 64 {
processes, have := m.Cache[index]
if !have {
......@@ -71,38 +77,61 @@ func (m *ModelProcessInfo) View() string {
for _, process := range processes {
haveProcess = true
sb.WriteString(myBorder.Left)
sb.WriteString(FormatStr(fmt.Sprintf("%d", process.DCU), 4, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(fmt.Sprintf("%d", process.Info.Pid), 7, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(process.Info.User, 8, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(process.DCUMem, 8, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(fmt.Sprintf("%d", process.SDMA), 4, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(fmt.Sprintf("%.1f", process.Info.CPU), 5, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(fmt.Sprintf("%.1f", process.Info.Mem), 5, lipgloss.Right))
sb.WriteByte(' ')
sb.WriteString(FormatStr(process.Info.Time, 9, lipgloss.Right))
sb.WriteByte(' ')
sbInner.WriteString(FormatStr(fmt.Sprintf("%d", process.DCU), 4, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(fmt.Sprintf("%d", process.Info.Pid), 7, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(process.Info.User, 8, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(process.DCUMem, 8, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(fmt.Sprintf("%d", process.SDMA), 4, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(fmt.Sprintf("%.1f", process.Info.CPU), 5, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(fmt.Sprintf("%.1f", process.Info.Mem), 5, lipgloss.Right))
sbInner.WriteByte(' ')
sbInner.WriteString(FormatStr(process.Info.Time, 9, lipgloss.Right))
sbInner.WriteByte(' ')
if process.Info.ContInfo != nil {
sb.WriteString(FormatStr(process.Info.ContInfo.Name, 20, lipgloss.Left))
sbInner.WriteString(FormatStr(process.Info.ContInfo.Name, 20, lipgloss.Left))
} else {
sb.WriteString(FormatStr(" - ", 20, lipgloss.Right))
sbInner.WriteString(FormatStr(" - ", 20, lipgloss.Right))
}
sb.WriteByte(' ')
w := m.width - lipgloss.Width(sb.String()) - 2
sbInner.WriteByte(' ')
w := m.width - lipgloss.Width(sbInner.String()) - 3
tw := lipgloss.Width(process.Info.Cmd)
if w >= tw {
sb.WriteString(process.Info.Cmd)
sb.WriteString(strings.Repeat(" ", w-tw))
sbInner.WriteString(process.Info.Cmd)
sbInner.WriteString(strings.Repeat(" ", w-tw))
} else {
sb.WriteString(FormatStr(process.Info.Cmd, w-2, lipgloss.Left))
sb.WriteString("..")
sbInner.WriteString(FormatStr(process.Info.Cmd, w-1, lipgloss.Left))
sbInner.WriteString("..")
}
sb.WriteByte(' ')
sbInner.WriteByte(' ')
selected := false
if m.actionMsg != nil && m.actionMsg.SelectPids != nil {
b, have := m.actionMsg.SelectPids[process.Info.Pid]
if have && b {
selected = true
}
}
if heightLightPid == process.Info.Pid {
if selected {
sb.WriteString(HeightSelectedStyle.Render(sbInner.String()))
} else {
sb.WriteString(HeightLightStyle.Render(sbInner.String()))
}
} else {
if selected {
sb.WriteString(SelectedStyle.Render(sbInner.String()))
} else {
sb.WriteString(sbInner.String())
}
}
sbInner.Reset()
sb.WriteString(myBorder.Right)
sb.WriteByte('\n')
lines = append(lines, sb.String())
......@@ -131,6 +160,9 @@ func (m *ModelProcessInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
maps.Copy(m.Cache, msg.DCUPidInfo)
m.modMsg = msg
return m, nil
case *ActionMsg:
m.actionMsg = msg
return m, nil
}
return m, nil
}
......@@ -35,8 +35,10 @@ type ModelSysLoad struct {
topLine string
bottomLine string
style lipgloss.Style
width int // 组件总宽度
colors []color.Color
width int // 组件总宽度
colors []color.Color // 时序图的颜色表
actionMsg *ActionMsg // 动作消息
modelMsg *ModelMsg // 模型周期性消息
}
type SysLoadInfo struct {
......@@ -145,7 +147,12 @@ func (m *ModelSysLoad) init() [6]time.Time {
func (m *ModelSysLoad) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := inputMsg.(type) {
case *ModelMsg:
m.modelMsg = msg
m.updateInfo(msg)
return m, nil
case *ActionMsg:
m.actionMsg = msg
return m, nil
}
return m, nil
......@@ -196,8 +203,6 @@ func (m *ModelSysLoad) updateInfo(t *ModelMsg) {
s.DCUMemUsageAvg, s.DCUUsageAvg = 0, 0
qinfo, lock := t.DCUInfo.GetQuitInfo()
defer lock.Unlock()
for k, v := range qinfo {
s.DCUMemUsageAvg += v.MemUsedPerent
s.DCUMemUsage[k] = v.MemUsedPerent
......@@ -205,6 +210,7 @@ func (m *ModelSysLoad) updateInfo(t *ModelMsg) {
s.DCUUsage[k] = v.DCUUTil
}
l := len(qinfo)
lock.Unlock()
s.DCUMemUsageAvg /= float32(l)
s.DCUUsageAvg /= float32(l)
m.current = &s
......
......@@ -192,6 +192,9 @@ func (m *MyTimeChart) View() string {
case utils.CharFull:
runes[line][col] = utils.FullMW
}
if t, have := utils.MM[runes[line][col]]; have {
runes[line][col] = t
}
case utils.CharLeft:
switch utils.CharTypeOr(charStat, utils.CharLeft) {
case utils.CharLeft:
......@@ -202,6 +205,9 @@ func (m *MyTimeChart) View() string {
runes[line][col] = utils.FullMW
}
charStat = utils.CharTypeOr(charStat, utils.CharLeft)
if t, have := utils.MM[runes[line][col]]; have {
runes[line][col] = t
}
case utils.CharRight:
switch utils.CharTypeOr(charStat, utils.CharRight) {
case utils.CharLeft:
......@@ -212,8 +218,14 @@ func (m *MyTimeChart) View() string {
runes[line][col] = utils.FullMW
}
charStat = utils.CharTypeOr(charStat, utils.CharRight)
if t, have := utils.MM[runes[line][col]]; have {
runes[line][col] = t
}
case utils.CharFull:
charStat = utils.CharFull
if t, have := utils.MM[runes[line][col]]; have {
runes[line][col] = t
}
}
}
......
......@@ -462,7 +462,6 @@ type DCUPidInfo struct {
}
// GetDCUPidInfo 获取Pid相关信息
// 需要剔除PCIBus为空的项
func GetDCUPidInfo() ([]DCUPidInfo, error) {
output, err := exec.Command(DCUBinaryFile, "--showpids").Output()
if err != nil {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment