You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.1 KiB

  1. package uistate
  2. import (
  3. lucifer3 "git.aiterp.net/lucifer3/server"
  4. "git.aiterp.net/lucifer3/server/commands"
  5. "git.aiterp.net/lucifer3/server/effects"
  6. "git.aiterp.net/lucifer3/server/events"
  7. "git.aiterp.net/lucifer3/server/internal/gentools"
  8. "sync"
  9. )
  10. func NewService() lucifer3.ActiveService {
  11. return &service{}
  12. }
  13. type service struct {
  14. mu sync.Mutex
  15. data Data
  16. listener []chan Patch
  17. }
  18. func (s *service) Active() bool {
  19. return true
  20. }
  21. func (s *service) HandleCommand(bus *lucifer3.EventBus, command lucifer3.Command) {
  22. var patches []Patch
  23. switch command := command.(type) {
  24. case commands.SetState:
  25. patches = []Patch{{Device: &DevicePatch{ID: command.ID, DesiredState: &command.State}}}
  26. case commands.SetStateBatch:
  27. for id, state := range command {
  28. patches = []Patch{{Device: &DevicePatch{ID: id, DesiredState: gentools.ShallowCopy(&state)}}}
  29. }
  30. }
  31. if len(patches) > 0 {
  32. s.mu.Lock()
  33. s.data = s.data.WithPatch(patches...)
  34. s.mu.Unlock()
  35. for _, patch := range patches {
  36. bus.RunEvent(patch)
  37. }
  38. }
  39. }
  40. func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) {
  41. var patches []Patch
  42. switch event := event.(type) {
  43. case events.AliasAdded:
  44. patches = []Patch{{Device: &DevicePatch{ID: event.ID, AddAlias: &event.Alias}}}
  45. case events.AliasRemoved:
  46. patches = []Patch{{Device: &DevicePatch{ID: event.ID, RemoveAlias: &event.Alias}}}
  47. case events.HardwareState:
  48. patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWState: &event}}}
  49. if event.State.Color != nil {
  50. rgb, _ := event.State.Color.ToRGB()
  51. patches = append(patches, Patch{Device: &DevicePatch{
  52. ID: event.ID,
  53. ActiveColorRGB: gentools.Ptr(rgb.RGB.Round()),
  54. }})
  55. } else {
  56. patches = append(patches, Patch{Device: &DevicePatch{
  57. ID: event.ID,
  58. ClearActiveColorRGB: false,
  59. }})
  60. }
  61. case events.HardwareMetadata:
  62. patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWMetadata: &event}}}
  63. case events.AssignmentCreated:
  64. patches = []Patch{{Assignment: &AssignmentPatch{
  65. ID: event.ID,
  66. Effect: &effects.Serializable{Effect: event.Effect},
  67. }}}
  68. case events.AssignmentRemoved:
  69. patches = []Patch{{Assignment: &AssignmentPatch{
  70. ID: event.ID,
  71. Delete: true,
  72. }}}
  73. case events.DeviceAssigned:
  74. // Un-assign from current assignment (if any)
  75. if d, ok := s.data.Devices[event.DeviceID]; ok && d.Assignment != nil {
  76. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  77. ID: *d.Assignment,
  78. RemoveDeviceID: &d.ID,
  79. }})
  80. }
  81. // Assign to current assignment (if it's not cleared)
  82. if event.AssignmentID != nil {
  83. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  84. ID: *event.AssignmentID,
  85. AddDeviceID: &event.DeviceID,
  86. }})
  87. }
  88. // Always set the assignment
  89. patches = append(patches, Patch{Device: &DevicePatch{
  90. ID: event.DeviceID,
  91. Assignment: gentools.ShallowCopy(event.AssignmentID),
  92. ClearAssignment: event.AssignmentID == nil,
  93. }})
  94. }
  95. if len(patches) > 0 {
  96. s.mu.Lock()
  97. s.data = s.data.WithPatch(patches...)
  98. s.mu.Unlock()
  99. for _, patch := range patches {
  100. bus.RunEvent(patch)
  101. }
  102. }
  103. }