Skip to content

Commit 4727804

Browse files
authored
Merge pull request #5 from termkit/fix-go-routine-leak
Fix go routine leak
2 parents 99e516d + 21194c4 commit 4727804

File tree

3 files changed

+79
-64
lines changed

3 files changed

+79
-64
lines changed

header.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ type commonHeader struct {
103103

104104
func (h *header) Init() tea.Cmd {
105105
return h.Listen()
106-
//return nil
107106
}
108107

109108
func (h *header) Update(msg tea.Msg) (*header, tea.Cmd) {
@@ -119,6 +118,8 @@ func (h *header) Update(msg tea.Msg) (*header, tea.Cmd) {
119118
h.viewport.Height = msg.Height
120119

121120
h.calculateTitleLength()
121+
122+
cmds = append(cmds, h.Listen())
122123
case tea.KeyMsg:
123124
switch {
124125
case key.Matches(msg, h.keyMap.SwitchTabLeft):
@@ -130,9 +131,9 @@ func (h *header) Update(msg tea.Msg) (*header, tea.Cmd) {
130131
h.currentTab = min(h.currentTab+1, len(h.headers)-1)
131132
}
132133
}
133-
}
134134

135-
cmds = append(cmds, h.Listen())
135+
cmds = append(cmds, h.Listen())
136+
}
136137

137138
return h, tea.Batch(cmds...)
138139
}

skeleton.go

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -308,25 +308,41 @@ func (s *Skeleton) deletePage(key string) {
308308

309309
// AddWidget adds a new widget to the Skeleton.
310310
func (s *Skeleton) AddWidget(key string, value string) *Skeleton {
311-
s.widget.AddWidget(key, value)
311+
go func() {
312+
s.updateChan <- AddNewWidget{
313+
Key: key,
314+
Value: value,
315+
}
316+
}()
312317
return s
313318
}
314319

315320
// UpdateWidgetValue updates the Value content by the given key.
316321
// Adds the widget if it doesn't exist.
317322
func (s *Skeleton) UpdateWidgetValue(key string, value string) *Skeleton {
318-
// if widget not exists, add it
319-
if s.widget.GetWidget(key) == nil {
320-
s.widget.AddWidget(key, value)
321-
}
323+
go func() {
324+
// if widget not exists, add it
325+
if s.widget.GetWidget(key) == nil {
326+
s.AddWidget(key, value)
327+
}
328+
329+
s.updateChan <- UpdateWidgetContent{
330+
Key: key,
331+
Value: value,
332+
}
333+
}()
322334

323-
s.widget.UpdateWidgetValue(key, value)
324335
return s
325336
}
326337

327338
// DeleteWidget deletes the Value by the given key.
328339
func (s *Skeleton) DeleteWidget(key string) *Skeleton {
329-
s.widget.DeleteWidget(key)
340+
go func() {
341+
s.updateChan <- DeleteWidget{
342+
Key: key,
343+
}
344+
}()
345+
330346
return s
331347
}
332348

@@ -364,6 +380,37 @@ func (s *Skeleton) IAMActivePageCmd() tea.Cmd {
364380
}
365381
}
366382

383+
func (s *Skeleton) switchPage(cmds []tea.Cmd, position string) []tea.Cmd {
384+
switch position {
385+
case "left":
386+
if !s.IsTabsLocked() {
387+
s.currentTab = max(s.currentTab-1, 0)
388+
cmds = append(cmds, s.IAMActivePageCmd())
389+
}
390+
case "right":
391+
if !s.IsTabsLocked() {
392+
s.currentTab = min(s.currentTab+1, len(s.pages)-1)
393+
cmds = append(cmds, s.IAMActivePageCmd())
394+
}
395+
}
396+
397+
return cmds
398+
}
399+
400+
func (s *Skeleton) updateSkeleton(msg tea.Msg, cmd tea.Cmd, cmds []tea.Cmd) []tea.Cmd {
401+
s.header, cmd = s.header.Update(msg)
402+
cmds = append(cmds, cmd)
403+
404+
s.widget, cmd = s.widget.Update(msg)
405+
cmds = append(cmds, cmd)
406+
407+
s.pages[s.currentTab], cmd = s.pages[s.currentTab].Update(msg)
408+
cmds = append(cmds, cmd)
409+
410+
cmds = append(cmds, s.Listen()) // listen to the update channel
411+
return cmds
412+
}
413+
367414
func (s *Skeleton) Init() tea.Cmd {
368415
if len(s.pages) == 0 {
369416
panic("skeleton: no pages added, please add at least one page")
@@ -387,47 +434,41 @@ func (s *Skeleton) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
387434
}
388435
s.viewport.Width = msg.Width
389436
s.viewport.Height = msg.Height
437+
438+
cmds = s.updateSkeleton(msg, cmd, cmds)
390439
case tea.KeyMsg:
391440
switch {
392441
case key.Matches(msg, s.KeyMap.Quit):
393442
return s, tea.Quit
394443
case key.Matches(msg, s.KeyMap.SwitchTabLeft):
395-
if !s.IsTabsLocked() {
396-
s.currentTab = max(s.currentTab-1, 0)
397-
cmds = append(cmds, s.IAMActivePageCmd())
398-
}
444+
cmds = s.switchPage(cmds, "left")
399445
case key.Matches(msg, s.KeyMap.SwitchTabRight):
400-
if !s.IsTabsLocked() {
401-
s.currentTab = min(s.currentTab+1, len(s.pages)-1)
402-
cmds = append(cmds, s.IAMActivePageCmd())
403-
}
446+
cmds = s.switchPage(cmds, "right")
404447
}
448+
cmds = s.updateSkeleton(msg, cmd, cmds)
405449
case AddPage:
406450
cmds = append(cmds, msg.Page.Init()) // init the page
451+
cmds = s.updateSkeleton(msg, cmd, cmds)
407452
case UpdatePageTitle:
408453
s.updatePageTitle(msg.Key, msg.Title)
454+
cmds = s.updateSkeleton(msg, cmd, cmds)
409455
case DeletePage:
410456
s.deletePage(msg.Key)
411457
cmds = append(cmds, s.IAMActivePageCmd())
458+
cmds = s.updateSkeleton(msg, cmd, cmds)
412459
case DummyMsg:
413460
// do nothing, just to trigger the update
461+
cmds = s.updateSkeleton(msg, cmd, cmds)
414462
case HeaderSizeMsg:
415463
s.termSizeNotEnoughToHandleHeaders = msg.NotEnoughToHandleHeaders
416464
case WidgetSizeMsg:
417465
s.termSizeNotEnoughToHandleWidgets = msg.NotEnoughToHandleWidgets
466+
case AddNewWidget, UpdateWidgetContent, DeleteWidget:
467+
cmds = s.updateSkeleton(msg, cmd, cmds)
468+
default:
469+
cmds = s.updateSkeleton(msg, cmd, cmds)
418470
}
419471

420-
s.header, cmd = s.header.Update(msg)
421-
cmds = append(cmds, cmd)
422-
423-
s.widget, cmd = s.widget.Update(msg)
424-
cmds = append(cmds, cmd)
425-
426-
s.pages[s.currentTab], cmd = s.pages[s.currentTab].Update(msg)
427-
cmds = append(cmds, cmd)
428-
429-
cmds = append(cmds, s.Listen()) // listen to the update channel
430-
431472
return s, tea.Batch(cmds...)
432473
}
433474

widget.go

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,6 @@ func (w *widget) SetRightPadding(padding int) *widget {
102102
return w
103103
}
104104

105-
func (w *widget) AddWidget(key string, value string) {
106-
go func() {
107-
w.updateChan <- AddNewWidget{
108-
Key: key,
109-
Value: value,
110-
}
111-
}()
112-
}
113-
114105
// GetWidget returns the Value by the given key.
115106
func (w *widget) GetWidget(key string) *commonWidget {
116107
for _, widget := range w.widgets {
@@ -122,25 +113,6 @@ func (w *widget) GetWidget(key string) *commonWidget {
122113
return nil
123114
}
124115

125-
// UpdateWidgetValue updates the Value content by the given key.
126-
func (w *widget) UpdateWidgetValue(key string, value string) {
127-
go func() {
128-
w.updateChan <- UpdateWidgetContent{
129-
Key: key,
130-
Value: value,
131-
}
132-
}()
133-
}
134-
135-
// DeleteWidget deletes the Value by the given key.
136-
func (w *widget) DeleteWidget(key string) {
137-
go func() {
138-
w.updateChan <- DeleteWidget{
139-
Key: key,
140-
}
141-
}()
142-
}
143-
144116
// DeleteAllWidgets deletes all the widgets.
145117
func (w *widget) DeleteAllWidgets() {
146118
w.widgets = nil
@@ -231,18 +203,19 @@ func (w *widget) Update(msg tea.Msg) (*widget, tea.Cmd) {
231203
w.viewport.Height = msg.Height
232204

233205
w.calculateWidgetLength()
206+
207+
cmds = append(cmds, w.Listen())
234208
case AddNewWidget:
235209
w.addNewWidget(msg.Key, msg.Value)
236-
210+
cmds = append(cmds, w.Listen())
237211
case UpdateWidgetContent:
238212
w.updateWidgetContent(msg.Key, msg.Value)
239-
213+
cmds = append(cmds, w.Listen())
240214
case DeleteWidget:
241215
w.deleteWidget(msg.Key)
216+
cmds = append(cmds, w.Listen())
242217
}
243218

244-
cmds = append(cmds, w.Listen())
245-
246219
return w, tea.Batch(cmds...)
247220
}
248221

@@ -279,9 +252,9 @@ func (w *widget) View() string {
279252
line := strings.Repeat("─", requiredLineCount)
280253
line = lipgloss.NewStyle().Foreground(lipgloss.Color(w.properties.borderColor)).Render(line)
281254

282-
var renderedWidgets []string
283-
for _, wgt := range w.widgets {
284-
renderedWidgets = append(renderedWidgets, w.properties.widgetStyle.Render(wgt.Value))
255+
var renderedWidgets = make([]string, len(w.widgets))
256+
for i, wgt := range w.widgets {
257+
renderedWidgets[i] = w.properties.widgetStyle.Render(wgt.Value)
285258
}
286259

287260
leftCorner := lipgloss.JoinVertical(lipgloss.Top, "│", "╰")

0 commit comments

Comments
 (0)