main.go 4.83 KB
Newer Older
liming6's avatar
liming6 committed
1
2
3
package tui

import (
4
	"get-container/cmd/hytop/backend"
liming6's avatar
liming6 committed
5
	"get-container/gpu"
liming6's avatar
liming6 committed
6
	"get-container/utils"
liming6's avatar
liming6 committed
7
8
	"time"

liming6's avatar
liming6 committed
9
10
	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
liming6's avatar
liming6 committed
11
12
13
14
)

const (
	DCUTopVersion = "1.0.0"
liming6's avatar
liming6 committed
15
16
17
18
)

// ModelMsg 模型信息,在父组件和各个子组件间共享信息
type ModelMsg struct {
liming6's avatar
liming6 committed
19
20
	t          time.Time                        // 当前时间
	Version    *gpu.HYVersionInfo               // gpu版本相关信息
21
22
	DCUPidInfo map[int][]backend.DCUProcessInfo // 使用dcu的进程信息
	systemInfo *utils.SysInfo                   // 系统信息
liming6's avatar
liming6 committed
23
24
	MyVersion  string                           // 本软件的版本
	DCUInfo    *backend.DCUInfoMap              // dcu相关信息
liming6's avatar
liming6 committed
25
26
27
28
29
30
}

type TickMsg time.Time

// ModelMain tui主模型类
type ModelMain struct {
liming6's avatar
liming6 committed
31
32
33
	width, height int // 终端尺寸
	Header        *ModelHeader
	DCUInfo       *ModelDCUInfo
liming6's avatar
liming6 committed
34
	SysLoad       *ModelSysLoad
35
	ProcessInfo   *ModelProcessInfo
liming6's avatar
liming6 committed
36
	modelMsg      *ModelMsg
liming6's avatar
liming6 committed
37
38
}

liming6's avatar
liming6 committed
39
func NewModelMain(width, height int) ModelMain {
liming6's avatar
liming6 committed
40
	result := ModelMain{}
liming6's avatar
liming6 committed
41
42
	result.width = width
	result.height = height
43
44
	result.Header = NewModelHeader()
	result.DCUInfo = NewModelDCUInfo(width, height)
liming6's avatar
liming6 committed
45
	result.SysLoad = NewModelSysLoad(width)
46
	result.ProcessInfo = NewModelProcessInfo(width)
liming6's avatar
liming6 committed
47
	return result
liming6's avatar
liming6 committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
}

func tickCmd() tea.Cmd {
	return tea.Every(time.Second, func(t time.Time) tea.Msg {
		return TickMsg(t)
	})
}

func sendMsgCmd(modelMsg *ModelMsg) tea.Cmd {
	return func() tea.Msg {
		return *modelMsg
	}
}

// Init 初始化信息
func (m *ModelMain) Init() tea.Cmd {
liming6's avatar
liming6 committed
64
65
	modelMsg := ModelMsg{}
	if err := initModelInfo(&modelMsg); err != nil {
liming6's avatar
liming6 committed
66
67
		return tea.Quit
	}
liming6's avatar
liming6 committed
68
69
70
71
	cmds := make([]tea.Cmd, 0)
	if c := m.Header.Init(); c != nil {
		cmds = append(cmds, c)
	}
liming6's avatar
liming6 committed
72
73
74
	if c := m.DCUInfo.Init(); c != nil {
		cmds = append(cmds, c)
	}
liming6's avatar
liming6 committed
75
76
77
	if c := m.SysLoad.Init(); c != nil {
		cmds = append(cmds, c)
	}
78
79
80
	if c := m.ProcessInfo.Init(); c != nil {
		cmds = append(cmds, c)
	}
liming6's avatar
liming6 committed
81
	m.modelMsg = &modelMsg
liming6's avatar
liming6 committed
82
	// 将调用初始化方法
liming6's avatar
liming6 committed
83
	cmds = append(cmds, tickCmd(), sendMsgCmd(&modelMsg))
liming6's avatar
liming6 committed
84
85
86
87
88
89
90
91
92
93
94
	return tea.Batch(cmds...)
}

func (m *ModelMain) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := inputMsg.(type) {
	case tea.KeyMsg: // 键盘事件
		switch msg.String() {
		case "ctrl+c", "q":
			return m, tea.Quit
		}
	case TickMsg: // 定时事件
liming6's avatar
liming6 committed
95
		updateModelInfo(m.modelMsg, time.Time(msg))
liming6's avatar
liming6 committed
96
97
98
		header, _ := m.Header.Update(m.modelMsg)
		dcuInfo, _ := m.DCUInfo.Update(m.modelMsg)
		sysLoad, _ := m.SysLoad.Update(m.modelMsg)
99
		pidinfo, _ := m.ProcessInfo.Update(m.modelMsg)
liming6's avatar
liming6 committed
100
		m.Header = header.(*ModelHeader)
liming6's avatar
liming6 committed
101
		m.DCUInfo = dcuInfo.(*ModelDCUInfo)
liming6's avatar
liming6 committed
102
		m.SysLoad = sysLoad.(*ModelSysLoad)
103
		m.ProcessInfo = pidinfo.(*ModelProcessInfo)
liming6's avatar
liming6 committed
104
		return m, tickCmd()
liming6's avatar
liming6 committed
105
106
107
	case ModelMsg: // 初始化
		header, _ := m.Header.Update(m.modelMsg)
		dcuInfo, _ := m.DCUInfo.Update(m.modelMsg)
liming6's avatar
liming6 committed
108
		sysLoad, _ := m.SysLoad.Update(m.modelMsg)
109
		pidinfo, _ := m.ProcessInfo.Update(m.modelMsg)
liming6's avatar
liming6 committed
110
111
		m.Header = header.(*ModelHeader)
		m.DCUInfo = dcuInfo.(*ModelDCUInfo)
liming6's avatar
liming6 committed
112
		m.SysLoad = sysLoad.(*ModelSysLoad)
113
		m.ProcessInfo = pidinfo.(*ModelProcessInfo)
liming6's avatar
liming6 committed
114
		return m, nil
115
	case tea.WindowSizeMsg: // 窗口尺寸变化
liming6's avatar
liming6 committed
116
		m.width, m.height = msg.Width, msg.Height
117
118
119
120
121
122
123
124
		header, _ := m.Header.Update(msg)
		dcuInfo, _ := m.DCUInfo.Update(msg)
		sysLoad, _ := m.SysLoad.Update(msg)
		pidinfo, _ := m.ProcessInfo.Update(msg)
		m.Header = header.(*ModelHeader)
		m.DCUInfo = dcuInfo.(*ModelDCUInfo)
		m.SysLoad = sysLoad.(*ModelSysLoad)
		m.ProcessInfo = pidinfo.(*ModelProcessInfo)
liming6's avatar
liming6 committed
125
		return m, nil
liming6's avatar
liming6 committed
126
127
128
129
130
	}
	return m, nil
}

func (m *ModelMain) View() string {
131
	return m.Header.View() + m.DCUInfo.View() + m.SysLoad.View() + m.ProcessInfo.View() + "\n"
liming6's avatar
liming6 committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
}

var myBorder = lipgloss.Border{
	Top:          "═",
	TopLeft:      "╒",
	TopRight:     "╕",
	Bottom:       "═",
	BottomLeft:   "╘",
	BottomRight:  "╛",
	Left:         "│",
	Right:        "│",
	MiddleLeft:   "├",
	MiddleRight:  "┤",
	Middle:       "┼",
	MiddleTop:    "┬",
	MiddleBottom: "┴",
}

liming6's avatar
liming6 committed
150
151
func initModelInfo(model *ModelMsg) error {
	model.t = time.Now()
liming6's avatar
liming6 committed
152
153
	model.MyVersion = DCUTopVersion
	if ver, err := gpu.GetHYVersionInfo(); err != nil {
liming6's avatar
liming6 committed
154
		return err
liming6's avatar
liming6 committed
155
	} else {
liming6's avatar
liming6 committed
156
		model.Version = ver
liming6's avatar
liming6 committed
157
	}
158
159
160
161
162
163
164
165
166
167
168
169
170
171
	model.DCUInfo = backend.DCUSInfoMap
	model.DCUPidInfo = backend.DCUSInfoMap.GetDCUProcessInfo2()
	if sinfo, err := utils.GetSysInfo(); err != nil {
		return err
	} else {
		model.systemInfo = sinfo
	}
	if err := model.DCUInfo.UpdateQuickInfo(); err != nil {
		return err
	}
	if err := model.DCUInfo.UpdateSlowInfo(); err != nil {
		return err
	}
	return nil
liming6's avatar
liming6 committed
172
173
}

liming6's avatar
liming6 committed
174
// updateModelInfo 更新模型信息
175
func updateModelInfo(modelMsg *ModelMsg, t time.Time) error {
liming6's avatar
liming6 committed
176
	modelMsg.t = t
177
178
179
180
181
182
183
184
185
186
	if sinfo, err := utils.GetSysInfo(); err != nil {
		return err
	} else {
		modelMsg.systemInfo = sinfo
	}
	modelMsg.DCUPidInfo = modelMsg.DCUInfo.GetDCUProcessInfo2()
	if err := modelMsg.DCUInfo.UpdateQuickInfo(); err != nil {
		return err
	}
	return nil
liming6's avatar
liming6 committed
187
}