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.

105 lines
2.8 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. case events.HardwareMetadata:
  50. patches = []Patch{{Device: &DevicePatch{ID: event.ID, HWMetadata: &event}}}
  51. case events.AssignmentCreated:
  52. patches = []Patch{{Assignment: &AssignmentPatch{
  53. ID: event.ID,
  54. Effect: &effects.Serializable{Effect: event.Effect},
  55. }}}
  56. case events.AssignmentRemoved:
  57. patches = []Patch{{Assignment: &AssignmentPatch{
  58. ID: event.ID,
  59. Delete: true,
  60. }}}
  61. case events.DeviceAssigned:
  62. // Un-assign from current assignment (if any)
  63. if d, ok := s.data.Devices[event.DeviceID]; ok && d.Assignment != nil {
  64. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  65. ID: *d.Assignment,
  66. RemoveDeviceID: &d.ID,
  67. }})
  68. }
  69. // Assign to current assignment (if it's not cleared)
  70. if event.AssignmentID != nil {
  71. patches = append(patches, Patch{Assignment: &AssignmentPatch{
  72. ID: *event.AssignmentID,
  73. AddDeviceID: &event.DeviceID,
  74. }})
  75. }
  76. // Always set the assignment
  77. patches = append(patches, Patch{Device: &DevicePatch{
  78. ID: event.DeviceID,
  79. Assignment: gentools.ShallowCopy(event.AssignmentID),
  80. ClearAssignment: event.AssignmentID == nil,
  81. }})
  82. }
  83. if len(patches) > 0 {
  84. s.mu.Lock()
  85. s.data = s.data.WithPatch(patches...)
  86. s.mu.Unlock()
  87. for _, patch := range patches {
  88. bus.RunEvent(patch)
  89. }
  90. }
  91. }