Skip to content

Commit

Permalink
Merge pull request #5 from termkit/fix-go-routine-leak
Browse files Browse the repository at this point in the history
Fix go routine leak
  • Loading branch information
canack authored Sep 1, 2024
2 parents 99e516d + 21194c4 commit 4727804
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 64 deletions.
7 changes: 4 additions & 3 deletions header.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ type commonHeader struct {

func (h *header) Init() tea.Cmd {
return h.Listen()
//return nil
}

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

h.calculateTitleLength()

cmds = append(cmds, h.Listen())
case tea.KeyMsg:
switch {
case key.Matches(msg, h.keyMap.SwitchTabLeft):
Expand All @@ -130,9 +131,9 @@ func (h *header) Update(msg tea.Msg) (*header, tea.Cmd) {
h.currentTab = min(h.currentTab+1, len(h.headers)-1)
}
}
}

cmds = append(cmds, h.Listen())
cmds = append(cmds, h.Listen())
}

return h, tea.Batch(cmds...)
}
Expand Down
93 changes: 67 additions & 26 deletions skeleton.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,25 +308,41 @@ func (s *Skeleton) deletePage(key string) {

// AddWidget adds a new widget to the Skeleton.
func (s *Skeleton) AddWidget(key string, value string) *Skeleton {
s.widget.AddWidget(key, value)
go func() {
s.updateChan <- AddNewWidget{
Key: key,
Value: value,
}
}()
return s
}

// UpdateWidgetValue updates the Value content by the given key.
// Adds the widget if it doesn't exist.
func (s *Skeleton) UpdateWidgetValue(key string, value string) *Skeleton {
// if widget not exists, add it
if s.widget.GetWidget(key) == nil {
s.widget.AddWidget(key, value)
}
go func() {
// if widget not exists, add it
if s.widget.GetWidget(key) == nil {
s.AddWidget(key, value)
}

s.updateChan <- UpdateWidgetContent{
Key: key,
Value: value,
}
}()

s.widget.UpdateWidgetValue(key, value)
return s
}

// DeleteWidget deletes the Value by the given key.
func (s *Skeleton) DeleteWidget(key string) *Skeleton {
s.widget.DeleteWidget(key)
go func() {
s.updateChan <- DeleteWidget{
Key: key,
}
}()

return s
}

Expand Down Expand Up @@ -364,6 +380,37 @@ func (s *Skeleton) IAMActivePageCmd() tea.Cmd {
}
}

func (s *Skeleton) switchPage(cmds []tea.Cmd, position string) []tea.Cmd {
switch position {
case "left":
if !s.IsTabsLocked() {
s.currentTab = max(s.currentTab-1, 0)
cmds = append(cmds, s.IAMActivePageCmd())
}
case "right":
if !s.IsTabsLocked() {
s.currentTab = min(s.currentTab+1, len(s.pages)-1)
cmds = append(cmds, s.IAMActivePageCmd())
}
}

return cmds
}

func (s *Skeleton) updateSkeleton(msg tea.Msg, cmd tea.Cmd, cmds []tea.Cmd) []tea.Cmd {
s.header, cmd = s.header.Update(msg)
cmds = append(cmds, cmd)

s.widget, cmd = s.widget.Update(msg)
cmds = append(cmds, cmd)

s.pages[s.currentTab], cmd = s.pages[s.currentTab].Update(msg)
cmds = append(cmds, cmd)

cmds = append(cmds, s.Listen()) // listen to the update channel
return cmds
}

func (s *Skeleton) Init() tea.Cmd {
if len(s.pages) == 0 {
panic("skeleton: no pages added, please add at least one page")
Expand All @@ -387,47 +434,41 @@ func (s *Skeleton) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
s.viewport.Width = msg.Width
s.viewport.Height = msg.Height

cmds = s.updateSkeleton(msg, cmd, cmds)
case tea.KeyMsg:
switch {
case key.Matches(msg, s.KeyMap.Quit):
return s, tea.Quit
case key.Matches(msg, s.KeyMap.SwitchTabLeft):
if !s.IsTabsLocked() {
s.currentTab = max(s.currentTab-1, 0)
cmds = append(cmds, s.IAMActivePageCmd())
}
cmds = s.switchPage(cmds, "left")
case key.Matches(msg, s.KeyMap.SwitchTabRight):
if !s.IsTabsLocked() {
s.currentTab = min(s.currentTab+1, len(s.pages)-1)
cmds = append(cmds, s.IAMActivePageCmd())
}
cmds = s.switchPage(cmds, "right")
}
cmds = s.updateSkeleton(msg, cmd, cmds)
case AddPage:
cmds = append(cmds, msg.Page.Init()) // init the page
cmds = s.updateSkeleton(msg, cmd, cmds)
case UpdatePageTitle:
s.updatePageTitle(msg.Key, msg.Title)
cmds = s.updateSkeleton(msg, cmd, cmds)
case DeletePage:
s.deletePage(msg.Key)
cmds = append(cmds, s.IAMActivePageCmd())
cmds = s.updateSkeleton(msg, cmd, cmds)
case DummyMsg:
// do nothing, just to trigger the update
cmds = s.updateSkeleton(msg, cmd, cmds)
case HeaderSizeMsg:
s.termSizeNotEnoughToHandleHeaders = msg.NotEnoughToHandleHeaders
case WidgetSizeMsg:
s.termSizeNotEnoughToHandleWidgets = msg.NotEnoughToHandleWidgets
case AddNewWidget, UpdateWidgetContent, DeleteWidget:
cmds = s.updateSkeleton(msg, cmd, cmds)
default:
cmds = s.updateSkeleton(msg, cmd, cmds)
}

s.header, cmd = s.header.Update(msg)
cmds = append(cmds, cmd)

s.widget, cmd = s.widget.Update(msg)
cmds = append(cmds, cmd)

s.pages[s.currentTab], cmd = s.pages[s.currentTab].Update(msg)
cmds = append(cmds, cmd)

cmds = append(cmds, s.Listen()) // listen to the update channel

return s, tea.Batch(cmds...)
}

Expand Down
43 changes: 8 additions & 35 deletions widget.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,6 @@ func (w *widget) SetRightPadding(padding int) *widget {
return w
}

func (w *widget) AddWidget(key string, value string) {
go func() {
w.updateChan <- AddNewWidget{
Key: key,
Value: value,
}
}()
}

// GetWidget returns the Value by the given key.
func (w *widget) GetWidget(key string) *commonWidget {
for _, widget := range w.widgets {
Expand All @@ -122,25 +113,6 @@ func (w *widget) GetWidget(key string) *commonWidget {
return nil
}

// UpdateWidgetValue updates the Value content by the given key.
func (w *widget) UpdateWidgetValue(key string, value string) {
go func() {
w.updateChan <- UpdateWidgetContent{
Key: key,
Value: value,
}
}()
}

// DeleteWidget deletes the Value by the given key.
func (w *widget) DeleteWidget(key string) {
go func() {
w.updateChan <- DeleteWidget{
Key: key,
}
}()
}

// DeleteAllWidgets deletes all the widgets.
func (w *widget) DeleteAllWidgets() {
w.widgets = nil
Expand Down Expand Up @@ -231,18 +203,19 @@ func (w *widget) Update(msg tea.Msg) (*widget, tea.Cmd) {
w.viewport.Height = msg.Height

w.calculateWidgetLength()

cmds = append(cmds, w.Listen())
case AddNewWidget:
w.addNewWidget(msg.Key, msg.Value)

cmds = append(cmds, w.Listen())
case UpdateWidgetContent:
w.updateWidgetContent(msg.Key, msg.Value)

cmds = append(cmds, w.Listen())
case DeleteWidget:
w.deleteWidget(msg.Key)
cmds = append(cmds, w.Listen())
}

cmds = append(cmds, w.Listen())

return w, tea.Batch(cmds...)
}

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

var renderedWidgets []string
for _, wgt := range w.widgets {
renderedWidgets = append(renderedWidgets, w.properties.widgetStyle.Render(wgt.Value))
var renderedWidgets = make([]string, len(w.widgets))
for i, wgt := range w.widgets {
renderedWidgets[i] = w.properties.widgetStyle.Render(wgt.Value)
}

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

0 comments on commit 4727804

Please sign in to comment.