process.go 4.03 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package tui

import (
	"fmt"
	"get-container/cmd/dcutop/backend"
	"maps"
	"strings"

	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
)

type ModelProcessInfo struct {
	Header           string
	Title            string
	DoubleMiddleLine string
	MiddleLine       string
	BottomLine       string
	NoProceseLine    string // 没有进程时显示的行
	Cache            map[int][]backend.DCUProcessInfo
	width            int
	style            lipgloss.Style
}

const (
	Processes             = " Processes:"
	ModelProcessInfoTitle = " DCU    PID      USER  DCU-MEM SDMA  %CPU  %MEM      TIME  Command"
	ModelProcessInfoNoPro = "  No running processes found"
)

func NewModelProcessInfo(width int) *ModelProcessInfo {
	result := ModelProcessInfo{width: width, Cache: make(map[int][]backend.DCUProcessInfo), style: lipgloss.NewStyle()}
	return &result
}

func (m *ModelProcessInfo) Init() tea.Cmd {
	sb := strings.Builder{}
	sb.WriteString(myBorder.Left)
	sb.WriteString(Processes)

	uah := fmt.Sprintf("%s@%s ", m.style.Foreground(lipgloss.Color("#edff2cff")).SetString(backend.User).String(),
		m.style.Foreground(lipgloss.Color("#a3ff2bff")).SetString(backend.HostName).String())
	space := strings.Repeat(" ", m.width-lipgloss.Width(Processes)-lipgloss.Width(uah)-2)

	sb.WriteString(space)
	sb.WriteString(uah)
	sb.WriteString(myBorder.Right)
	sb.WriteByte('\n')
	m.Header = sb.String()
	sb.Reset()

	sb.WriteString(myBorder.Left)
	sb.WriteString(ModelProcessInfoTitle)
	sb.WriteString(strings.Repeat(" ", m.width-2-lipgloss.Width(ModelProcessInfoTitle)))
	sb.WriteString(myBorder.Right)
	sb.WriteByte('\n')
	m.Title = sb.String()
	m.DoubleMiddleLine = "╞" + strings.Repeat("═", m.width-2) + "╡\n"
	m.MiddleLine = myBorder.MiddleLeft + strings.Repeat("─", m.width-2) + myBorder.MiddleRight + "\n"
	m.BottomLine = myBorder.BottomLeft + strings.Repeat("═", m.width-2) + myBorder.BottomRight
	m.NoProceseLine = myBorder.Left + ModelProcessInfoNoPro + strings.Repeat(" ", m.width-2-lipgloss.Width(ModelProcessInfoNoPro)) + myBorder.Right + "\n"
	return nil
}

func (m *ModelProcessInfo) View() string {
	haveProcess := false
	lines := make([]string, 0)
	sb := strings.Builder{}
	for index := range 64 {
		processes, have := m.Cache[index]
		if !have {
			continue
		}
		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), 6, lipgloss.Right))
			sb.WriteByte(' ')
			sb.WriteString(FormatStr(process.Info.User, 9, 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.WriteString("  ")
			w := m.width - lipgloss.Width(sb.String()) - 2
			tw := lipgloss.Width(process.Info.Cmd)
			if w >= tw {
				sb.WriteString(process.Info.Cmd)
				sb.WriteString(strings.Repeat(" ", w-tw))
			} else {
				sb.WriteString(FormatStr(process.Info.Cmd, w-2, lipgloss.Left))
				sb.WriteString("..")
			}
			sb.WriteByte(' ')
			sb.WriteString(myBorder.Right)
			sb.WriteByte('\n')
			lines = append(lines, sb.String())
			sb.Reset()
		}
		lines = append(lines, m.MiddleLine)
	}
	if !haveProcess {
		return m.Title + m.DoubleMiddleLine + m.NoProceseLine + m.BottomLine
	}
	sb.WriteString(m.Title)
	sb.WriteString(m.DoubleMiddleLine)
	for _, v := range lines[:len(lines)-1] {
		sb.WriteString(v)
	}
	sb.WriteString(m.BottomLine)
	return sb.String()
}

func (m *ModelProcessInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := inputMsg.(type) {
	case *ModelMsg:
		clear(m.Cache)
		maps.Copy(m.Cache, msg.DCUPidInfo)
	}
	return m, nil
}