eliminate string allocs for HasWidgets

add BuildWidgets3 to avoid string allocs and redundant w.Write calls in templates
This commit is contained in:
Azareal 2020-04-12 15:37:38 +10:00
parent 5fe0c8c95b
commit fbc50c9086
2 changed files with 101 additions and 5 deletions

View File

@ -1149,7 +1149,8 @@ ArgLoop:
leftParam = strings.TrimSuffix(strings.TrimPrefix(leftParam, "\""), "\"") leftParam = strings.TrimSuffix(strings.TrimPrefix(leftParam, "\""), "\"")
id, ok := c.config.DockToID[leftParam] id, ok := c.config.DockToID[leftParam]
if ok { if ok {
litString("c.BuildWidget2("+strconv.Itoa(id)+","+rightParam+")", false) out = "c.BuildWidget3(" + strconv.Itoa(id) + "," + rightParam + ")\n"
literal = true
break ArgLoop break ArgLoop
} }
} }
@ -1176,6 +1177,15 @@ ArgLoop:
val = val3 val = val3
// TODO: Refactor this // 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 + ")" out = "c.HasWidgets(" + leftParam + "," + rightParam + ")"
literal = true literal = true
break ArgLoop break ArgLoop

View File

@ -11,6 +11,7 @@ import (
"sync/atomic" "sync/atomic"
min "github.com/Azareal/Gosora/common/templates" min "github.com/Azareal/Gosora/common/templates"
"github.com/Azareal/Gosora/uutils"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -261,12 +262,12 @@ func BuildWidget2(dock int, h *Header) (sbody string) {
widgets = Docks.Footer.Items widgets = Docks.Footer.Items
} }
for _, widget := range widgets { for _, w := range widgets {
if !widget.Enabled { if !w.Enabled {
continue continue
} }
if widget.Allowed(h.Zone, h.ZoneID) { if w.Allowed(h.Zone, h.ZoneID) {
item, err := widget.Build(h) item, err := w.Build(h)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }
@ -276,6 +277,91 @@ func BuildWidget2(dock int, h *Header) (sbody string) {
return sbody 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) { func getDockWidgets(dock string) (widgets []*Widget, err error) {
rows, err := widgetStmts.getDockList.Query(dock) rows, err := widgetStmts.getDockList.Query(dock)
if err != nil { if err != nil {