package tui import ( "get-container/cmd/hytop/backend" "get-container/gpu" "get-container/utils" "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) const ( DCUTopVersion = "1.0.0" ) // ModelMsg 模型信息,在父组件和各个子组件间共享信息 type ModelMsg struct { t time.Time // 当前时间 Version *gpu.HYVersionInfo // gpu版本相关信息 DCUPidInfo map[int][]backend.DCUProcessInfo // 使用dcu的进程信息 systemInfo *utils.SysInfo // 系统信息 MyVersion string // 本软件的版本 DCUInfo *backend.DCUInfoMap // dcu相关信息 } type TickMsg time.Time // ModelMain tui主模型类 type ModelMain struct { width, height int // 终端尺寸 Header *ModelHeader DCUInfo *ModelDCUInfo SysLoad *ModelSysLoad ProcessInfo *ModelProcessInfo modelMsg *ModelMsg } func NewModelMain(width, height int) ModelMain { result := ModelMain{} result.width = width result.height = height result.Header = NewModelHeader() result.DCUInfo = NewModelDCUInfo(width, height) result.SysLoad = NewModelSysLoad(width) result.ProcessInfo = NewModelProcessInfo(width) return result } 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 { modelMsg := ModelMsg{} if err := initModelInfo(&modelMsg); err != nil { return tea.Quit } cmds := make([]tea.Cmd, 0) if c := m.Header.Init(); c != nil { cmds = append(cmds, c) } if c := m.DCUInfo.Init(); c != nil { cmds = append(cmds, c) } if c := m.SysLoad.Init(); c != nil { cmds = append(cmds, c) } if c := m.ProcessInfo.Init(); c != nil { cmds = append(cmds, c) } m.modelMsg = &modelMsg // 将调用初始化方法 cmds = append(cmds, tickCmd(), sendMsgCmd(&modelMsg)) 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: // 定时事件 updateModelInfo(m.modelMsg, time.Time(msg)) header, _ := m.Header.Update(m.modelMsg) dcuInfo, _ := m.DCUInfo.Update(m.modelMsg) sysLoad, _ := m.SysLoad.Update(m.modelMsg) pidinfo, _ := m.ProcessInfo.Update(m.modelMsg) m.Header = header.(*ModelHeader) m.DCUInfo = dcuInfo.(*ModelDCUInfo) m.SysLoad = sysLoad.(*ModelSysLoad) m.ProcessInfo = pidinfo.(*ModelProcessInfo) return m, tickCmd() case ModelMsg: // 初始化 header, _ := m.Header.Update(m.modelMsg) dcuInfo, _ := m.DCUInfo.Update(m.modelMsg) sysLoad, _ := m.SysLoad.Update(m.modelMsg) pidinfo, _ := m.ProcessInfo.Update(m.modelMsg) m.Header = header.(*ModelHeader) m.DCUInfo = dcuInfo.(*ModelDCUInfo) m.SysLoad = sysLoad.(*ModelSysLoad) m.ProcessInfo = pidinfo.(*ModelProcessInfo) return m, nil case tea.WindowSizeMsg: // 窗口尺寸变化 m.width, m.height = msg.Width, msg.Height 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) return m, nil } return m, nil } func (m *ModelMain) View() string { return m.Header.View() + m.DCUInfo.View() + m.SysLoad.View() + m.ProcessInfo.View() + "\n" } var myBorder = lipgloss.Border{ Top: "═", TopLeft: "╒", TopRight: "╕", Bottom: "═", BottomLeft: "╘", BottomRight: "╛", Left: "│", Right: "│", MiddleLeft: "├", MiddleRight: "┤", Middle: "┼", MiddleTop: "┬", MiddleBottom: "┴", } func initModelInfo(model *ModelMsg) error { model.t = time.Now() model.MyVersion = DCUTopVersion if ver, err := gpu.GetHYVersionInfo(); err != nil { return err } else { model.Version = ver } 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 } // updateModelInfo 更新模型信息 func updateModelInfo(modelMsg *ModelMsg, t time.Time) error { modelMsg.t = t 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 }