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.

124 lines
3.5 KiB

  1. package uistate
  2. import (
  3. "git.aiterp.net/lucifer3/server/device"
  4. "git.aiterp.net/lucifer3/server/effects"
  5. "git.aiterp.net/lucifer3/server/events"
  6. "git.aiterp.net/lucifer3/server/internal/color"
  7. "git.aiterp.net/lucifer3/server/internal/gentools"
  8. "github.com/google/uuid"
  9. )
  10. type Data struct {
  11. Devices map[string]Device `json:"devices"`
  12. Assignments map[uuid.UUID]Assignment `json:"assignments"`
  13. }
  14. func (d *Data) WithPatch(patches ...Patch) Data {
  15. newData := d.Copy()
  16. for _, patch := range patches {
  17. if patch.Device != nil {
  18. pd := d.ensureDevice(patch.Device.ID)
  19. gentools.ApplyUpdateSlice(&pd.Aliases, patch.Device.SetAliases)
  20. gentools.ApplyUpdate(&pd.Name, patch.Device.Name)
  21. gentools.ApplyUpdatePtr(&pd.HWState, patch.Device.HWState)
  22. gentools.ApplyUpdatePtr(&pd.HWMetadata, patch.Device.HWMetadata)
  23. gentools.ApplyUpdatePtr(&pd.DesiredState, patch.Device.DesiredState)
  24. gentools.ApplyUpdatePtr(&pd.Assignment, patch.Device.Assignment)
  25. gentools.ApplyUpdatePtr(&pd.ActiveColorRGB, patch.Device.ActiveColorRGB)
  26. if patch.Device.AddAlias != nil {
  27. pd.Aliases = append(pd.Aliases[:0:0], pd.Aliases...)
  28. pd.Aliases = append(pd.Aliases, *patch.Device.AddAlias)
  29. }
  30. if patch.Device.RemoveAlias != nil {
  31. for i, alias := range pd.Aliases {
  32. if alias == *patch.Device.RemoveAlias {
  33. pd.Aliases = append(pd.Aliases[:0:0], pd.Aliases...)
  34. pd.Aliases = append(pd.Aliases[:i], pd.Aliases[i+1:]...)
  35. break
  36. }
  37. }
  38. }
  39. if patch.Device.ClearAssignment {
  40. pd.Assignment = nil
  41. }
  42. if patch.Device.ClearActiveColorRGB {
  43. pd.ActiveColorRGB = nil
  44. }
  45. if patch.Device.Delete {
  46. delete(newData.Devices, pd.ID)
  47. } else {
  48. newData.Devices[pd.ID] = pd
  49. }
  50. }
  51. if patch.Assignment != nil {
  52. pa := d.ensureAssignment(patch.Assignment.ID)
  53. gentools.ApplyUpdatePtr(&pa.Effect, patch.Assignment.Effect)
  54. if patch.Assignment.AddDeviceID != nil {
  55. pa.DeviceIDs = append(pa.DeviceIDs[:0:0], pa.DeviceIDs...)
  56. pa.DeviceIDs = append(pa.DeviceIDs, *patch.Assignment.AddDeviceID)
  57. }
  58. if patch.Assignment.RemoveDeviceID != nil {
  59. for i, id := range pa.DeviceIDs {
  60. if id == *patch.Assignment.RemoveDeviceID {
  61. pa.DeviceIDs = append(pa.DeviceIDs[:0:0], pa.DeviceIDs...)
  62. pa.DeviceIDs[i] = ""
  63. break
  64. }
  65. }
  66. }
  67. if patch.Assignment.Delete {
  68. delete(newData.Assignments, pa.ID)
  69. } else {
  70. newData.Assignments[pa.ID] = pa
  71. }
  72. }
  73. }
  74. return newData
  75. }
  76. func (d *Data) Copy() Data {
  77. return Data{
  78. Devices: gentools.CopyMap(d.Devices),
  79. Assignments: gentools.CopyMap(d.Assignments),
  80. }
  81. }
  82. func (d *Data) ensureDevice(id string) Device {
  83. if device, ok := d.Devices[id]; ok {
  84. return device
  85. } else {
  86. return Device{ID: id}
  87. }
  88. }
  89. func (d *Data) ensureAssignment(id uuid.UUID) Assignment {
  90. if assignment, ok := d.Assignments[id]; ok {
  91. return assignment
  92. } else {
  93. return Assignment{ID: id}
  94. }
  95. }
  96. type Device struct {
  97. ID string `json:"id"`
  98. Name string `json:"name"`
  99. HWMetadata *events.HardwareMetadata `json:"hwMetadata"`
  100. HWState *events.HardwareState `json:"hwState"`
  101. ActiveColorRGB *color.RGB `json:"activeColorRgb"`
  102. DesiredState *device.State `json:"desiredState"`
  103. Aliases []string `json:"aliases"`
  104. Assignment *uuid.UUID `json:"assignment"`
  105. }
  106. type Assignment struct {
  107. ID uuid.UUID `json:"id"`
  108. DeviceIDs []string `json:"deviceIds"`
  109. Effect *effects.Serializable `json:"effect"`
  110. }