pooler now accepts channels

done channels used to clean up pooler if GUI goes down

InitPooler() added to Remote type, useful for reinitiating the Pooler.
For this reason Pooler now defined as singleton type.
This commit is contained in:
2022-12-08 10:50:00 +00:00
parent e01efb22eb
commit c4f00a3dbd
2 changed files with 115 additions and 70 deletions

View File

@@ -6,40 +6,14 @@ import (
log "github.com/sirupsen/logrus"
)
// observer defines the interface any registered observers must satisfy
type observer interface {
OnUpdate(subject string)
}
// publisher defines methods that support observers
// publisher defines the list of observer channels
type publisher struct {
observerList []observer
observers []chan string
}
// Register adds an observer to observerList
func (p *publisher) Register(o observer) {
p.observerList = append(p.observerList, o)
}
// Deregister removes an observer from observerList
func (p *publisher) Deregister(o observer) {
var indexToRemove int
for i, observer := range p.observerList {
if observer == o {
indexToRemove = i
break
}
}
p.observerList = append(p.observerList[:indexToRemove], p.observerList[indexToRemove+1:]...)
}
// notify updates observers of any changes
func (p *publisher) notify(subject string) {
for _, observer := range p.observerList {
observer.OnUpdate(subject)
}
// Register adds an observer channel to the channelList
func (p *publisher) Register(channel chan string) {
p.observers = append(p.observers, channel)
}
type event struct {
@@ -85,32 +59,81 @@ func (e *event) Remove(events ...string) {
}
}
// pooler continuously polls the dirty paramters
var p *pooler
// pooler continuously polls the dirty parameters
// it is expected to be run in a goroutine
type pooler struct {
k *kind
run bool
event *event
k *kind
run bool
event *event
pdirtyDone chan bool
mdirtyDone chan bool
midiDone chan bool
ldirtyDone chan bool
publisher
}
func newPooler(k *kind) *pooler {
p := &pooler{
k: k,
run: true,
event: newEvent(),
if p == nil {
p = &pooler{
k: k,
run: true,
event: newEvent(),
pdirtyDone: make(chan bool),
mdirtyDone: make(chan bool),
midiDone: make(chan bool),
ldirtyDone: make(chan bool),
}
go p.done()
go p.parameters()
go p.macrobuttons()
go p.midi()
go p.levels()
}
go p.parameters()
go p.macrobuttons()
go p.midi()
go p.levels()
return p
}
func (p *pooler) done() {
for {
select {
case _, ok := <-p.pdirtyDone:
if !ok {
p.pdirtyDone = nil
}
case _, ok := <-p.mdirtyDone:
if !ok {
p.mdirtyDone = nil
}
case _, ok := <-p.midiDone:
if !ok {
p.midiDone = nil
}
case _, ok := <-p.ldirtyDone:
if !ok {
p.ldirtyDone = nil
}
}
if p.pdirtyDone == nil && p.mdirtyDone == nil && p.midiDone == nil && p.ldirtyDone == nil {
for _, ch := range p.observers {
close(ch)
}
break
}
}
}
func (p *pooler) parameters() {
for p.run {
if p.event.pdirty && pdirty() {
p.notify("pdirty")
pdirty, err := pdirty()
if err != nil {
close(p.pdirtyDone)
break
}
if p.event.pdirty && pdirty {
for _, ch := range p.observers {
ch <- "pdirty"
}
}
time.Sleep(33 * time.Millisecond)
}
@@ -118,8 +141,15 @@ func (p *pooler) parameters() {
func (p *pooler) macrobuttons() {
for p.run {
if p.event.mdirty && mdirty() {
p.notify("mdirty")
mdirty, err := mdirty()
if err != nil {
close(p.mdirtyDone)
break
}
if p.event.mdirty && mdirty {
for _, ch := range p.observers {
ch <- "mdirty"
}
}
time.Sleep(33 * time.Millisecond)
}
@@ -127,8 +157,15 @@ func (p *pooler) macrobuttons() {
func (p *pooler) midi() {
for p.run {
if p.event.midi && getMidiMessage() {
p.notify("midi")
midi, err := getMidiMessage()
if err != nil {
close(p.midiDone)
break
}
if p.event.midi && midi {
for _, ch := range p.observers {
ch <- "midi"
}
}
time.Sleep(33 * time.Millisecond)
}
@@ -138,10 +175,17 @@ func (p *pooler) levels() {
_levelCache = newLevelCache(p.k)
for p.run {
if p.event.ldirty && ldirty(p.k) {
ldirty, err := ldirty(p.k)
if err != nil {
close(p.ldirtyDone)
break
}
if p.event.ldirty && ldirty {
update(_levelCache.stripLevels, _levelCache.stripLevelsBuff, (2*p.k.PhysIn)+(8*p.k.VirtIn))
update(_levelCache.busLevels, _levelCache.busLevelsBuff, 8*p.k.NumBus())
p.notify("ldirty")
for _, ch := range p.observers {
ch <- "ldirty"
}
}
time.Sleep(33 * time.Millisecond)
}