diff --git a/pkg/app/component.go b/pkg/app/component.go index 06171aca2..58c625709 100644 --- a/pkg/app/component.go +++ b/pkg/app/component.go @@ -361,7 +361,6 @@ func (c *Compo) updateRoot() error { Wrap(err) } - c.dispatcher().componentUpdated(c.self().(Composer)) return nil } diff --git a/pkg/app/dispatcher.go b/pkg/app/dispatcher.go index 4da9dac1e..10a90eb21 100644 --- a/pkg/app/dispatcher.go +++ b/pkg/app/dispatcher.go @@ -68,7 +68,7 @@ type Dispatcher interface { sessionStorage() BrowserStorage runsInServer() bool resolveStaticResource(string) string - componentUpdated(Composer) + removeFromUpdates(Composer) } // ClientDispatcher is the interface that describes a dispatcher that emulates a diff --git a/pkg/app/engine.go b/pkg/app/engine.go index ead536ff7..10bcfdc44 100644 --- a/pkg/app/engine.go +++ b/pkg/app/engine.go @@ -370,36 +370,19 @@ func (e *engine) scheduleComponentUpdate(n UI) { return } - var compo Composer - var depth int - - for { - if c, isCompo := n.(Composer); compo == nil && isCompo { - if _, isScheduled := e.updates[c]; isScheduled { - return - } - compo = c - } - - parent := n.parent() - if parent == nil { - break - } - - if compo != nil { - depth++ - } - n = parent + c := nearestCompo(n) + if c == nil { + return } - if compo == nil { + if _, isScheduled := e.updates[c]; isScheduled { return } - e.updates[compo] = struct{}{} + e.updates[c] = struct{}{} e.updateQueue = append(e.updateQueue, updateDescriptor{ - compo: compo, - priority: depth + 1, + compo: c, + priority: compoPriority(c), }) } @@ -412,23 +395,24 @@ func (e *engine) updateComponents() { for _, ud := range e.updateQueue { compo := ud.compo if !compo.Mounted() { + e.removeFromUpdates(compo) continue } - if _, isNotUpdated := e.updates[compo]; !isNotUpdated { + if _, requiresUpdate := e.updates[compo]; !requiresUpdate { continue } if err := compo.updateRoot(); err != nil { panic(err) } - e.componentUpdated(compo) + e.removeFromUpdates(compo) } e.updateQueue = e.updateQueue[:0] } -func (e *engine) componentUpdated(c Composer) { +func (e *engine) removeFromUpdates(c Composer) { delete(e.updates, c) } @@ -478,6 +462,23 @@ func sortUpdateDescriptors(d []updateDescriptor) { }) } +func nearestCompo(n UI) Composer { + for node := n; node != nil; node = node.parent() { + if c, isCompo := node.(Composer); isCompo { + return c + } + } + return nil +} + +func compoPriority(c Composer) int { + depth := 1 + for parent := c.parent(); parent != nil; parent = parent.parent() { + depth++ + } + return depth +} + type msgHandler struct { src UI function MsgHandler