From fbc50c908658a8f7f1f9a09b995dda988e323020 Mon Sep 17 00:00:00 2001 From: Azareal Date: Sun, 12 Apr 2020 15:37:38 +1000 Subject: [PATCH] eliminate string allocs for HasWidgets add BuildWidgets3 to avoid string allocs and redundant w.Write calls in templates --- common/templates/templates.go | 12 ++++- common/widgets.go | 94 +++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/common/templates/templates.go b/common/templates/templates.go index 9e1903a9..35b26048 100644 --- a/common/templates/templates.go +++ b/common/templates/templates.go @@ -1149,7 +1149,8 @@ ArgLoop: leftParam = strings.TrimSuffix(strings.TrimPrefix(leftParam, "\""), "\"") id, ok := c.config.DockToID[leftParam] if ok { - litString("c.BuildWidget2("+strconv.Itoa(id)+","+rightParam+")", false) + out = "c.BuildWidget3(" + strconv.Itoa(id) + "," + rightParam + ")\n" + literal = true break ArgLoop } } @@ -1176,6 +1177,15 @@ ArgLoop: val = val3 // TODO: Refactor this + if leftParam[0] == '"' { + leftParam = strings.TrimSuffix(strings.TrimPrefix(leftParam, "\""), "\"") + id, ok := c.config.DockToID[leftParam] + if ok { + out = "c.HasWidgets2(" + strconv.Itoa(id) + "," + rightParam + ")" + literal = true + break ArgLoop + } + } out = "c.HasWidgets(" + leftParam + "," + rightParam + ")" literal = true break ArgLoop diff --git a/common/widgets.go b/common/widgets.go index 27d04683..8e318bcd 100644 --- a/common/widgets.go +++ b/common/widgets.go @@ -11,6 +11,7 @@ import ( "sync/atomic" min "github.com/Azareal/Gosora/common/templates" + "github.com/Azareal/Gosora/uutils" "github.com/pkg/errors" ) @@ -261,12 +262,12 @@ func BuildWidget2(dock int, h *Header) (sbody string) { widgets = Docks.Footer.Items } - for _, widget := range widgets { - if !widget.Enabled { + for _, w := range widgets { + if !w.Enabled { continue } - if widget.Allowed(h.Zone, h.ZoneID) { - item, err := widget.Build(h) + if w.Allowed(h.Zone, h.ZoneID) { + item, err := w.Build(h) if err != nil { LogError(err) } @@ -276,6 +277,91 @@ func BuildWidget2(dock int, h *Header) (sbody string) { return sbody } +func BuildWidget3(dock int, h *Header) { + if !h.Theme.HasDockByID(dock) { + return + } + // Let themes forcibly override this slot + if sbody := h.Theme.BuildDockByID(dock); sbody != "" { + h.Writer.Write(uutils.StringToBytes(sbody)) + return + } + + var widgets []*Widget + switch dock { + case 0: + widgets = Docks.LeftOfNav + case 1: + widgets = Docks.RightOfNav + case 2: + // 1 = id for the default menu + mhold, err := Menus.Get(1) + if err == nil { + err := mhold.Build(h.Writer, h.CurrentUser, h.Path) + if err != nil { + LogError(err) + } + } + return + case 3: + widgets = Docks.RightSidebar.Items + case 4: + widgets = Docks.Footer.Items + } + + for _, w := range widgets { + if !w.Enabled { + continue + } + if w.Allowed(h.Zone, h.ZoneID) { + item, err := w.Build(h) + if err != nil { + LogError(err) + } + if item != "" { + h.Writer.Write(uutils.StringToBytes(item)) + } + } + } +} + +// TODO: Find a more optimimal way of doing this... +func HasWidgets2(dock int, h *Header) bool { + if !h.Theme.HasDockByID(dock) { + return false + } + + // Let themes forcibly override this slot + // TODO: Optimise this bit + sbody := h.Theme.BuildDockByID(dock) + if sbody != "" { + return true + } + + var widgets []*Widget + switch dock { + case 0: + widgets = Docks.LeftOfNav + case 1: + widgets = Docks.RightOfNav + case 3: + widgets = Docks.RightSidebar.Items + case 4: + widgets = Docks.Footer.Items + } + + wcount := 0 + for _, widget := range widgets { + if !widget.Enabled { + continue + } + if widget.Allowed(h.Zone, h.ZoneID) { + wcount++ + } + } + return wcount > 0 +} + func getDockWidgets(dock string) (widgets []*Widget, err error) { rows, err := widgetStmts.getDockList.Query(dock) if err != nil {