add state filtering to effect enforcer.
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"git.aiterp.net/lucifer3/server/commands"
|
||||
"git.aiterp.net/lucifer3/server/device"
|
||||
"git.aiterp.net/lucifer3/server/events"
|
||||
"git.aiterp.net/lucifer3/server/internal/color"
|
||||
"git.aiterp.net/lucifer3/server/internal/gentools"
|
||||
"github.com/google/uuid"
|
||||
"sync"
|
||||
@@ -18,6 +19,9 @@ func NewEffectEnforcer(resolver device.Resolver, sceneMap device.SceneMap) lucif
|
||||
sceneMap: sceneMap,
|
||||
list: make([]*effectEnforcerRun, 0, 16),
|
||||
index: make(map[string]*effectEnforcerRun, 8),
|
||||
|
||||
supportFlags: make(map[string]device.SupportFlags),
|
||||
colorFlags: make(map[string]device.ColorFlags),
|
||||
}
|
||||
|
||||
return s
|
||||
@@ -28,6 +32,9 @@ type effectEnforcer struct {
|
||||
resolver device.Resolver
|
||||
sceneMap device.SceneMap
|
||||
|
||||
supportFlags map[string]device.SupportFlags
|
||||
colorFlags map[string]device.ColorFlags
|
||||
|
||||
started uint32
|
||||
|
||||
list []*effectEnforcerRun
|
||||
@@ -40,6 +47,22 @@ func (s *effectEnforcer) Active() bool {
|
||||
|
||||
func (s *effectEnforcer) HandleEvent(_ *lucifer3.EventBus, event lucifer3.Event) {
|
||||
switch event := event.(type) {
|
||||
case events.HardwareState:
|
||||
s.mu.Lock()
|
||||
colorFlags := s.colorFlags
|
||||
supportFlags := s.supportFlags
|
||||
s.mu.Unlock()
|
||||
|
||||
colorFlags = gentools.CopyMap(colorFlags)
|
||||
supportFlags = gentools.CopyMap(supportFlags)
|
||||
colorFlags[event.ID] = event.ColorFlags
|
||||
supportFlags[event.ID] = event.SupportFlags
|
||||
|
||||
s.mu.Lock()
|
||||
s.colorFlags = colorFlags
|
||||
s.supportFlags = supportFlags
|
||||
s.mu.Unlock()
|
||||
|
||||
case events.DeviceReady:
|
||||
// If the device is managed by the effect enforcer, cause the effect to be
|
||||
// re-ran.
|
||||
@@ -127,6 +150,9 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) {
|
||||
deleteIDs = deleteIDs[:0]
|
||||
|
||||
s.mu.Lock()
|
||||
colorFlags := s.colorFlags
|
||||
supportFlags := s.supportFlags
|
||||
|
||||
for i, run := range s.list {
|
||||
if run.dead {
|
||||
deleteIDs = append(deleteIDs, run.id)
|
||||
@@ -173,6 +199,51 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) {
|
||||
}
|
||||
|
||||
if len(batch) > 0 {
|
||||
for id, state := range batch {
|
||||
sf := supportFlags[id]
|
||||
|
||||
if state.Power != nil && !sf.HasAny(device.SFlagPower) {
|
||||
state.Power = nil
|
||||
}
|
||||
if state.Temperature != nil && !sf.HasAny(device.SFlagTemperature) {
|
||||
state.Temperature = nil
|
||||
}
|
||||
if state.Intensity != nil && !sf.HasAny(device.SFlagIntensity) {
|
||||
state.Intensity = nil
|
||||
}
|
||||
if state.Color != nil && !sf.HasAny(device.SFlagColor) {
|
||||
state.Color = nil
|
||||
} else {
|
||||
cf := colorFlags[id]
|
||||
invalid := (state.Color.K != nil && !cf.HasAll(device.CFlagKelvin)) ||
|
||||
(state.Color.XY != nil && !cf.HasAll(device.CFlagXY)) ||
|
||||
(state.Color.RGB != nil && !cf.HasAll(device.CFlagRGB)) ||
|
||||
(state.Color.HS != nil && !cf.HasAll(device.CFlagHS))
|
||||
|
||||
if invalid {
|
||||
var converted color.Color
|
||||
var ok bool
|
||||
|
||||
switch {
|
||||
case cf.HasAny(device.CFlagXY):
|
||||
converted, ok = state.Color.ToXY()
|
||||
case cf.HasAny(device.CFlagRGB):
|
||||
converted, ok = state.Color.ToRGB()
|
||||
case cf.HasAny(device.CFlagHS):
|
||||
converted, ok = state.Color.ToHS()
|
||||
}
|
||||
|
||||
if !ok {
|
||||
state.Color = nil
|
||||
} else {
|
||||
state.Color = &converted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
batch[id] = state
|
||||
}
|
||||
|
||||
bus.RunCommand(batch)
|
||||
batch = make(commands.SetStateBatch, 64)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user