Skip to content

Commit

Permalink
Merge pull request #39 from linkdata/ui-primitive-helpers
Browse files Browse the repository at this point in the history
UI primitive helpers
  • Loading branch information
linkdata authored Apr 26, 2024
2 parents 094d910 + e262cf5 commit 55eb273
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 3 deletions.
12 changes: 10 additions & 2 deletions jaws.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,9 +497,17 @@ func (jw *Jaws) ServeWithTimeout(requestTimeout time.Duration) {
if maintenanceInterval < minInterval {
maintenanceInterval = minInterval
}
t := time.NewTicker(maintenanceInterval)
defer t.Stop()

subs := map[chan Message]*Request{}
t := time.NewTicker(maintenanceInterval)

defer func() {
t.Stop()
for ch, rq := range subs {
rq.cancel(nil)
close(ch)
}
}()

killSub := func(msgCh chan Message) {
if _, ok := subs[msgCh]; ok {
Expand Down
1 change: 0 additions & 1 deletion request.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,6 @@ func (rq *Request) sendQueue(outboundMsgCh chan<- wsMsg) {

for i := range toSend {
select {
case <-rq.Jaws.doneCh:
case <-rq.Done():
case outboundMsgCh <- toSend[i]:
}
Expand Down
6 changes: 6 additions & 0 deletions rlocker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package jaws

type RLocker interface {
RLock()
RUnlock()
}
31 changes: 31 additions & 0 deletions uibool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package jaws

import "sync"

var _ BoolSetter = UiBool{}

// UiBool implements BoolSetter given a sync.Locker (or RLocker) and a bool pointer.
type UiBool struct {
L sync.Locker
P *bool
}

func (ui UiBool) JawsGetBool(e *Element) (val bool) {
if rl, ok := ui.L.(RLocker); ok {
rl.RLock()
val = *ui.P
rl.RUnlock()
return
}
ui.L.Lock()
val = *ui.P
ui.L.Unlock()
return
}

func (ui UiBool) JawsSetBool(e *Element, val bool) (err error) {
ui.L.Lock()
*ui.P = val
ui.L.Unlock()
return
}
28 changes: 28 additions & 0 deletions uibool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package jaws

import (
"sync"
"testing"
)

func TestUiBool(t *testing.T) {
var l sync.Mutex
var rl sync.RWMutex
var val bool

ui := UiBool{L: &l, P: &val}

if ui.JawsGetBool(nil) {
t.Fail()
}

if x := ui.JawsSetBool(nil, true); x != nil {
t.Error(x)
}

ui.L = &rl

if !ui.JawsGetBool(nil) {
t.Fail()
}
}
33 changes: 33 additions & 0 deletions uifloat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package jaws

import (
"sync"
)

var _ FloatSetter = UiFloat{}

// UiFloat implements FloatSetter given a sync.Locker (or RLocker) and a float64 pointer.
type UiFloat struct {
L sync.Locker
P *float64
}

func (ui UiFloat) JawsGetFloat(e *Element) (val float64) {
if rl, ok := ui.L.(RLocker); ok {
rl.RLock()
val = *ui.P
rl.RUnlock()
return
}
ui.L.Lock()
val = *ui.P
ui.L.Unlock()
return
}

func (ui UiFloat) JawsSetFloat(e *Element, val float64) (err error) {
ui.L.Lock()
*ui.P = val
ui.L.Unlock()
return
}
28 changes: 28 additions & 0 deletions uifloat_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package jaws

import (
"sync"
"testing"
)

func TestUiFloat(t *testing.T) {
var l sync.Mutex
var rl sync.RWMutex
var val float64

ui := UiFloat{L: &l, P: &val}

if ui.JawsGetFloat(nil) != 0 {
t.Fail()
}

if x := ui.JawsSetFloat(nil, -1); x != nil {
t.Error(x)
}

ui.L = &rl

if ui.JawsGetFloat(nil) != -1 {
t.Fail()
}
}
40 changes: 40 additions & 0 deletions uistring.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package jaws

import (
"html"
"html/template"
"sync"
)

var _ StringSetter = UiString{}

// UiString implements StringSetter and HtmlGetter given a sync.Locker (or RLocker) and a string pointer.
type UiString struct {
L sync.Locker
P *string
}

func (ui UiString) JawsGetString(e *Element) (val string) {
if rl, ok := ui.L.(RLocker); ok {
rl.RLock()
val = *ui.P
rl.RUnlock()
return
}
ui.L.Lock()
val = *ui.P
ui.L.Unlock()
return
}

func (ui UiString) JawsSetString(e *Element, val string) (err error) {
ui.L.Lock()
*ui.P = val
ui.L.Unlock()
return
}

func (ui UiString) JawsGetHtml(e *Element) (val template.HTML) {
val = template.HTML(html.EscapeString(ui.JawsGetString(e))) // #nosec G203
return
}
28 changes: 28 additions & 0 deletions uistring_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package jaws

import (
"sync"
"testing"
)

func TestUiString(t *testing.T) {
var l sync.Mutex
var rl sync.RWMutex
var val string

ui := UiString{L: &l, P: &val}

if ui.JawsGetString(nil) != "" {
t.Fail()
}

if x := ui.JawsSetString(nil, "foo<"); x != nil {
t.Error(x)
}

ui.L = &rl

if ui.JawsGetHtml(nil) != "foo&lt;" {
t.Fail()
}
}

0 comments on commit 55eb273

Please sign in to comment.