Skip to content

Commit

Permalink
refactor: remove fragment & use bitwise
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsNotGoodName committed Apr 26, 2022
1 parent d3e6433 commit 64b54ef
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 241 deletions.
2 changes: 1 addition & 1 deletion core/bus/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (bs *BusServiceImpl) Handle(ctx context.Context, readC <-chan Command, writ
return
case msg := <-stateSub:
// Write state or state partial
if state.IsChangedAll(msg.Changed) {
if msg.Changed.Is(state.ChangedAll) {
writeCommand(ctx, writeC, newStateCommand(&msg.State))
} else {
writeCommand(ctx, writeC, newStatePartialCommand(state.GetPartial(&msg.State, msg.Changed)))
Expand Down
54 changes: 25 additions & 29 deletions core/middleware/preset.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,44 +37,40 @@ func (p *Preset) Update(ctx context.Context, preset *preset.Preset) error {
return nil
}

func (p *Preset) Apply(frag *state.Fragment) {
func (p *Preset) Apply(s *state.State, c state.Changed) state.Changed {
ctx := context.Background()

p.fragmentPresets(ctx, frag)

p.fragmentTitleAndURL(ctx, frag)
return c.Merge(p.fragmentPresets(ctx, s, c)).Merge(p.fragmentTitleAndURL(ctx, s, c))
}

func (p *Preset) fragmentPresets(ctx context.Context, frag *state.Fragment) {
if frag.Presets != nil {
for i := range frag.Presets {
titleNew := ""
urlNew := ""

preset, err := p.store.Get(ctx, frag.Presets[i].URL)
if err == nil {
titleNew = preset.TitleNew
urlNew = preset.URLNew
}
func (p *Preset) fragmentPresets(ctx context.Context, s *state.State, c state.Changed) state.Changed {
if !c.Is(state.ChangedPresets) {
return 0
}

frag.Presets[i].TitleNew = titleNew
frag.Presets[i].URLNew = urlNew
presets := s.Presets
for i := range presets {
p, err := p.store.Get(ctx, presets[i].URL)
if err != nil {
continue
}

presets[i].TitleNew = p.TitleNew
presets[i].URLNew = p.URLNew
}
}

func (p *Preset) fragmentTitleAndURL(ctx context.Context, frag *state.Fragment) {
if frag.URL != nil {
urlNew := ""
titleNew := ""
return s.SetPresets(presets)
}

preset, err := p.store.Get(ctx, *frag.URL)
if err == nil {
urlNew = preset.URLNew
titleNew = preset.TitleNew
}
func (p *Preset) fragmentTitleAndURL(ctx context.Context, s *state.State, c state.Changed) state.Changed {
if !c.Is(state.ChangedURL) {
return 0
}

frag.TitleNew = &titleNew
frag.URLNew = &urlNew
preset, err := p.store.Get(ctx, s.URL)
if err != nil {
return 0
}

return s.SetTitleNew(preset.TitleNew).Merge(s.SetURLNew(preset.URLNew))
}
4 changes: 2 additions & 2 deletions core/pubsub/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (sp *StatePub) unsubscribeFunc(sub *chan state.Message) func() {
}
}

func (sp *StatePub) Publish(s state.State, changed int) {
func (sp *StatePub) Publish(s state.State, changed state.Changed) {
sp.subsMapMu.Lock()

msg := state.Message{
Expand All @@ -60,7 +60,7 @@ func (sp *StatePub) Publish(s state.State, changed int) {
default:
select {
case old := <-*sub:
msg.Changed = state.MergeChanged(old.Changed, msg.Changed)
msg.Changed = old.Changed.Merge(msg.Changed)
*sub <- msg
case *sub <- msg:
}
Expand Down
16 changes: 7 additions & 9 deletions core/radio/radio.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ func (rs *RadioServiceImpl) SetVolume(ctx context.Context, radio Radio, volume i
return err
}

f := state.NewFragment(radio.UUID)
f.Volume = &volume

return radio.update(context.Background(), f)
return radio.update(context.Background(), func(s *state.State) state.Changed {
return s.SetVolume(volume)
})
}

func (rs *RadioServiceImpl) PlayPreset(ctx context.Context, radio Radio, preset int) error {
Expand Down Expand Up @@ -63,10 +62,9 @@ func (rs *RadioServiceImpl) RefreshVolume(ctx context.Context, radio Radio) erro
return err
}

f := state.NewFragment(radio.UUID)
f.Volume = &volume

return radio.update(ctx, f)
return radio.update(ctx, func(s *state.State) state.Changed {
return s.SetVolume(volume)
})
}

func (rs *RadioServiceImpl) Refresh(ctx context.Context, radio Radio) error {
Expand All @@ -75,7 +73,7 @@ func (rs *RadioServiceImpl) Refresh(ctx context.Context, radio Radio) error {
}

func (rs *RadioServiceImpl) GetState(ctx context.Context, radio Radio) (*state.State, error) {
return radio.read(ctx)
return radio.state(ctx)
}

func (rs *RadioServiceImpl) SetAudioSource(ctx context.Context, radio Radio, audioSource string) error {
Expand Down
22 changes: 10 additions & 12 deletions core/radio/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ func NewRunService(middleware state.Middleware, middlewarePub state.MiddlewarePu
}

func (rs *RunServiceImpl) Run(dctx context.Context, radio Radio, s state.State) {
handle := func(frag state.Fragment, changed int) {
rs.middleware.Apply(&frag)
if changed = s.Merge(frag) | changed; changed != 0 {
rs.statePub.Publish(s, changed)
handle := func(c state.Changed) {
c = c.Merge(rs.middleware.Apply(&s, c))
if c != 0 {
rs.statePub.Publish(s, c)
}
}
handle(s.Fragment(), state.ChangedAll)
handle(state.ChangedAll)

middlewareSub, middlewareUnsub := rs.middlewarePub.Subscribe()
ticker := time.NewTicker(60 * time.Second)
Expand All @@ -51,14 +51,12 @@ func (rs *RunServiceImpl) Run(dctx context.Context, radio Radio, s state.State)
}
}()
case <-middlewareSub:
handle(s.Fragment(), 0)
case radio.readC <- s:
case frag := <-radio.updateC:
handle(frag, 0)
handle(state.ChangedAll)
case radio.stateC <- s:
case fn := <-radio.updateFnC:
handle(fn(&s))
case event := <-radio.subscription.Events():
frag := state.NewFragment(radio.UUID)
parseEvent(event, &frag)
handle(frag, 0)
handle(parseEvent(event, &s))
}
}
}
22 changes: 11 additions & 11 deletions core/radio/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,46 +35,46 @@ type (
}

Radio struct {
UUID string // UUID of the radio.
client goupnp.ServiceClient // client is the SOAP client.
readC chan state.State // readC is used to read the state.
subscription upnpsub.Subscription // subscription to the UPnP event publisher.
updateC chan state.Fragment // updateC is used to update state.
UUID string // UUID of the radio.
client goupnp.ServiceClient // client is the SOAP client.
stateC chan state.State // stateC is used to read the state.
subscription upnpsub.Subscription // subscription to the UPnP event publisher.
updateFnC chan func(*state.State) state.Changed // updateFnC is used to update state.
}
)

func new(subscription upnpsub.Subscription, uuid string, client goupnp.ServiceClient) Radio {
return Radio{
UUID: uuid,
client: client,
readC: make(chan state.State),
stateC: make(chan state.State),
subscription: subscription,
updateC: make(chan state.Fragment),
updateFnC: make(chan func(*state.State) state.Changed),
}
}

func (r *Radio) Done() <-chan struct{} {
return r.subscription.Done()
}

func (r *Radio) read(ctx context.Context) (*state.State, error) {
func (r *Radio) state(ctx context.Context) (*state.State, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-r.Done():
return nil, core.ErrRadioClosed
case state := <-r.readC:
case state := <-r.stateC:
return &state, nil
}
}

func (r *Radio) update(ctx context.Context, frag state.Fragment) error {
func (r *Radio) update(ctx context.Context, updateFn func(*state.State) state.Changed) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-r.Done():
return core.ErrRadioClosed
case r.updateC <- frag:
case r.updateFnC <- updateFn:
return nil
}
}
24 changes: 16 additions & 8 deletions core/radio/upnpsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ type eventStateXML struct {
URL string `xml:"playback-details>stream>url"`
}

func parseEvent(event *upnpsub.Event, frag *state.Fragment) {
func parseEvent(event *upnpsub.Event, s *state.State) (changed state.Changed) {
for _, v := range event.Properties {
if v.Name == "PowerState" {
// Power change
power := v.Value == "On"
frag.Power = &power
changed = changed.Merge(s.SetPower(power))
} else if v.Name == "PlaybackXML" {
if v.Value == "" {
continue
Expand All @@ -34,27 +34,35 @@ func parseEvent(event *upnpsub.Event, frag *state.Fragment) {

// Status change
status := state.ParseStatus(esXML.State)
frag.Status = &status
changed = changed.Merge(s.SetStatus(status))

// Title change
title := esXML.Title
frag.Title = &title
changed = changed.Merge(s.SetTitle(title))

// URL change
url := esXML.URL
frag.URL = &url
changed = changed.Merge(s.SetURL(url))

// Metadata change
metadata := esXML.Metadata
frag.Metadata = &metadata
changed = changed.Merge(s.SetMetadata(metadata))
} else if v.Name == "IsMuted" {
// IsMuted change
isMuted := v.Value == "TRUE"
frag.IsMuted = &isMuted
changed = changed.Merge(s.SetIsMuted(isMuted))
} else if v.Name == "AudioSource" {
// AudioSource change
audioSource := v.Value
frag.AudioSource = &audioSource
c, err := s.SetAudioSource(audioSource)
if err != nil {
log.Println("radio.parseEvent:", err)
continue
}

changed = changed.Merge(c)
}
}

return changed
}
9 changes: 9 additions & 0 deletions core/state/changed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package state

func (c Changed) Is(check Changed) bool {
return c&check == check
}

func (c Changed) Merge(merge Changed) Changed {
return c | merge
}
50 changes: 0 additions & 50 deletions core/state/fragment.go

This file was deleted.

Loading

0 comments on commit 64b54ef

Please sign in to comment.