summaryrefslogtreecommitdiff
path: root/internal/tui/flamegraph/model.go
blob: dd77201edf3cec57f92798543ff120b4ba203e39 (plain)
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
package flamegraph

import (
	"image/color"
	coreflamegraph "ior/internal/flamegraph"
	common "ior/internal/tui/common"

	tea "charm.land/bubbletea/v2"
)

type snapshotNode struct {
	Name     string          `json:"n"`
	Value    uint64          `json:"v"`
	Total    uint64          `json:"t"`
	Children []*snapshotNode `json:"c,omitempty"`
}

type zoomState struct {
	path        string
	selectedIdx int
}

type frameSpring struct{}

// Model is the Bubble Tea model for the TUI flamegraph tab.
type Model struct {
	liveTrie    *coreflamegraph.LiveTrie
	lastVersion uint64
	snapshot    *snapshotNode

	frames       []tuiFrame
	targetFrames []tuiFrame
	width        int
	height       int

	selectedIdx int
	zoomStack   []zoomState
	zoomRoot    *snapshotNode

	searchActive bool
	searchQuery  string
	matchIndices map[int]bool

	fieldPresets [][]string
	fieldIndex   int

	springs []frameSpring
	paused  bool
	isDark  bool
}

// tuiFrame stores one terminal flamegraph frame cell.
type tuiFrame struct {
	Name    string
	Col     int
	Row     int
	Width   int
	Total   uint64
	Percent float64
	Fill    color.Color
	Depth   int
	Path    string
}

// NewModel constructs a flamegraph tab model with default state.
func NewModel(liveTrie *coreflamegraph.LiveTrie) Model {
	return Model{
		liveTrie:     liveTrie,
		matchIndices: make(map[int]bool),
		fieldPresets: [][]string{
			{"comm", "path"},
			{"tracepoint", "comm", "path"},
			{"pid", "tid", "comm", "path"},
		},
		isDark: true,
	}
}

// Init starts the flamegraph model.
func (m Model) Init() tea.Cmd {
	return nil
}

// Update handles incoming messages.
func (m Model) Update(tea.Msg) (tea.Model, tea.Cmd) {
	return m, nil
}

// View renders the flamegraph viewport.
func (m Model) View() tea.View {
	content := common.PanelStyle.Render("Flame: model scaffold")
	return tea.NewView(content)
}

// SetViewport updates model render dimensions.
func (m *Model) SetViewport(width, height int) {
	m.width = width
	m.height = height
}

// SetDarkMode sets the active color theme mode.
func (m *Model) SetDarkMode(isDark bool) {
	m.isDark = isDark
}