|
@ -5,6 +5,7 @@ import ( |
|
|
"git.aiterp.net/lucifer3/server/commands" |
|
|
"git.aiterp.net/lucifer3/server/commands" |
|
|
"git.aiterp.net/lucifer3/server/device" |
|
|
"git.aiterp.net/lucifer3/server/device" |
|
|
"git.aiterp.net/lucifer3/server/events" |
|
|
"git.aiterp.net/lucifer3/server/events" |
|
|
|
|
|
"git.aiterp.net/lucifer3/server/internal/color" |
|
|
"git.aiterp.net/lucifer3/server/internal/gentools" |
|
|
"git.aiterp.net/lucifer3/server/internal/gentools" |
|
|
"github.com/google/uuid" |
|
|
"github.com/google/uuid" |
|
|
"sync" |
|
|
"sync" |
|
@ -18,6 +19,9 @@ func NewEffectEnforcer(resolver device.Resolver, sceneMap device.SceneMap) lucif |
|
|
sceneMap: sceneMap, |
|
|
sceneMap: sceneMap, |
|
|
list: make([]*effectEnforcerRun, 0, 16), |
|
|
list: make([]*effectEnforcerRun, 0, 16), |
|
|
index: make(map[string]*effectEnforcerRun, 8), |
|
|
index: make(map[string]*effectEnforcerRun, 8), |
|
|
|
|
|
|
|
|
|
|
|
supportFlags: make(map[string]device.SupportFlags), |
|
|
|
|
|
colorFlags: make(map[string]device.ColorFlags), |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return s |
|
|
return s |
|
@ -28,6 +32,9 @@ type effectEnforcer struct { |
|
|
resolver device.Resolver |
|
|
resolver device.Resolver |
|
|
sceneMap device.SceneMap |
|
|
sceneMap device.SceneMap |
|
|
|
|
|
|
|
|
|
|
|
supportFlags map[string]device.SupportFlags |
|
|
|
|
|
colorFlags map[string]device.ColorFlags |
|
|
|
|
|
|
|
|
started uint32 |
|
|
started uint32 |
|
|
|
|
|
|
|
|
list []*effectEnforcerRun |
|
|
list []*effectEnforcerRun |
|
@ -40,6 +47,22 @@ func (s *effectEnforcer) Active() bool { |
|
|
|
|
|
|
|
|
func (s *effectEnforcer) HandleEvent(_ *lucifer3.EventBus, event lucifer3.Event) { |
|
|
func (s *effectEnforcer) HandleEvent(_ *lucifer3.EventBus, event lucifer3.Event) { |
|
|
switch event := event.(type) { |
|
|
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: |
|
|
case events.DeviceReady: |
|
|
// If the device is managed by the effect enforcer, cause the effect to be
|
|
|
// If the device is managed by the effect enforcer, cause the effect to be
|
|
|
// re-ran.
|
|
|
// re-ran.
|
|
@ -127,6 +150,9 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) { |
|
|
deleteIDs = deleteIDs[:0] |
|
|
deleteIDs = deleteIDs[:0] |
|
|
|
|
|
|
|
|
s.mu.Lock() |
|
|
s.mu.Lock() |
|
|
|
|
|
colorFlags := s.colorFlags |
|
|
|
|
|
supportFlags := s.supportFlags |
|
|
|
|
|
|
|
|
for i, run := range s.list { |
|
|
for i, run := range s.list { |
|
|
if run.dead { |
|
|
if run.dead { |
|
|
deleteIDs = append(deleteIDs, run.id) |
|
|
deleteIDs = append(deleteIDs, run.id) |
|
@ -173,6 +199,51 @@ func (s *effectEnforcer) runLoop(bus *lucifer3.EventBus) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if len(batch) > 0 { |
|
|
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) |
|
|
bus.RunCommand(batch) |
|
|
batch = make(commands.SetStateBatch, 64) |
|
|
batch = make(commands.SetStateBatch, 64) |
|
|
} |
|
|
} |
|
|