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.
 
 
 
 

182 line
4.9 KiB

  1. package appcontext
  2. import (
  3. "github.com/AFASystems/presence/internal/pkg/model"
  4. )
  5. // AppState provides centralized access to application state
  6. type AppState struct {
  7. beacons model.BeaconsList
  8. settings model.Settings
  9. beaconEvents model.BeaconEventList
  10. beaconsLookup map[string]struct{}
  11. latestList model.LatestBeaconsList
  12. }
  13. // NewAppState creates a new application context AppState with default values
  14. func NewAppState() *AppState {
  15. return &AppState{
  16. beacons: model.BeaconsList{
  17. Beacons: make(map[string]model.Beacon),
  18. },
  19. settings: model.Settings{
  20. Settings: model.SettingsVal{
  21. LocationConfidence: 4,
  22. LastSeenThreshold: 15,
  23. BeaconMetricSize: 30,
  24. HASendInterval: 5,
  25. HASendChangesOnly: false,
  26. RSSIEnforceThreshold: false,
  27. RSSIMinThreshold: 100,
  28. },
  29. },
  30. beaconEvents: model.BeaconEventList{
  31. Beacons: make(map[string]model.BeaconEvent),
  32. },
  33. beaconsLookup: make(map[string]struct{}),
  34. latestList: model.LatestBeaconsList{
  35. LatestList: make(map[string]model.Beacon),
  36. },
  37. }
  38. }
  39. // GetBeacons returns thread-safe access to beacons list
  40. func (m *AppState) GetBeacons() *model.BeaconsList {
  41. return &m.beacons
  42. }
  43. // GetSettings returns thread-safe access to settings
  44. func (m *AppState) GetSettings() *model.Settings {
  45. return &m.settings
  46. }
  47. // GetBeaconEvents returns thread-safe access to beacon events
  48. func (m *AppState) GetBeaconEvents() *model.BeaconEventList {
  49. return &m.beaconEvents
  50. }
  51. // GetBeaconsLookup returns thread-safe access to beacon lookup map
  52. func (m *AppState) GetBeaconsLookup() map[string]struct{} {
  53. return m.beaconsLookup
  54. }
  55. // GetLatestList returns thread-safe access to latest beacons list
  56. func (m *AppState) GetLatestList() *model.LatestBeaconsList {
  57. return &m.latestList
  58. }
  59. // AddBeaconToLookup adds a beacon ID to the lookup map
  60. func (m *AppState) AddBeaconToLookup(id string) {
  61. m.beaconsLookup[id] = struct{}{}
  62. }
  63. // RemoveBeaconFromLookup removes a beacon ID from the lookup map
  64. func (m *AppState) RemoveBeaconFromLookup(id string) {
  65. delete(m.beaconsLookup, id)
  66. }
  67. // BeaconExists checks if a beacon exists in the lookup
  68. func (m *AppState) BeaconExists(id string) bool {
  69. _, exists := m.beaconsLookup[id]
  70. return exists
  71. }
  72. // GetBeacon returns a beacon by ID (thread-safe)
  73. func (m *AppState) GetBeacon(id string) (model.Beacon, bool) {
  74. m.beacons.Lock.RLock()
  75. defer m.beacons.Lock.RUnlock()
  76. beacon, exists := m.beacons.Beacons[id]
  77. return beacon, exists
  78. }
  79. // UpdateBeacon updates a beacon in the list (thread-safe)
  80. func (m *AppState) UpdateBeacon(id string, beacon model.Beacon) {
  81. m.beacons.Lock.Lock()
  82. defer m.beacons.Lock.Unlock()
  83. m.beacons.Beacons[id] = beacon
  84. }
  85. // GetBeaconEvent returns a beacon event by ID (thread-safe)
  86. func (m *AppState) GetBeaconEvent(id string) (model.BeaconEvent, bool) {
  87. m.beaconEvents.Lock.RLock()
  88. defer m.beaconEvents.Lock.RUnlock()
  89. event, exists := m.beaconEvents.Beacons[id]
  90. return event, exists
  91. }
  92. // UpdateBeaconEvent updates a beacon event in the list (thread-safe)
  93. func (m *AppState) UpdateBeaconEvent(id string, event model.BeaconEvent) {
  94. m.beaconEvents.Lock.Lock()
  95. defer m.beaconEvents.Lock.Unlock()
  96. m.beaconEvents.Beacons[id] = event
  97. }
  98. // GetLatestBeacon returns the latest beacon by ID (thread-safe)
  99. func (m *AppState) GetLatestBeacon(id string) (model.Beacon, bool) {
  100. m.latestList.Lock.RLock()
  101. defer m.latestList.Lock.RUnlock()
  102. beacon, exists := m.latestList.LatestList[id]
  103. return beacon, exists
  104. }
  105. // UpdateLatestBeacon updates the latest beacon in the list (thread-safe)
  106. func (m *AppState) UpdateLatestBeacon(id string, beacon model.Beacon) {
  107. m.latestList.Lock.Lock()
  108. defer m.latestList.Lock.Unlock()
  109. m.latestList.LatestList[id] = beacon
  110. }
  111. // GetAllBeacons returns a copy of all beacons
  112. func (m *AppState) GetAllBeacons() map[string]model.Beacon {
  113. m.beacons.Lock.RLock()
  114. defer m.beacons.Lock.RUnlock()
  115. beacons := make(map[string]model.Beacon)
  116. for id, beacon := range m.beacons.Beacons {
  117. beacons[id] = beacon
  118. }
  119. return beacons
  120. }
  121. // GetAllLatestBeacons returns a copy of all latest beacons
  122. func (m *AppState) GetAllLatestBeacons() map[string]model.Beacon {
  123. m.latestList.Lock.RLock()
  124. defer m.latestList.Lock.RUnlock()
  125. beacons := make(map[string]model.Beacon)
  126. for id, beacon := range m.latestList.LatestList {
  127. beacons[id] = beacon
  128. }
  129. return beacons
  130. }
  131. // GetBeaconCount returns the number of tracked beacons
  132. func (m *AppState) GetBeaconCount() int {
  133. m.beacons.Lock.RLock()
  134. defer m.beacons.Lock.RUnlock()
  135. return len(m.beacons.Beacons)
  136. }
  137. // GetSettingsValue returns current settings as a value
  138. func (m *AppState) GetSettingsValue() model.SettingsVal {
  139. m.settings.Lock.RLock()
  140. defer m.settings.Lock.RUnlock()
  141. return m.settings.Settings
  142. }
  143. // UpdateSettings updates the system settings (thread-safe)
  144. func (m *AppState) UpdateSettings(newSettings model.SettingsVal) {
  145. m.settings.Lock.Lock()
  146. defer m.settings.Lock.Unlock()
  147. m.settings.Settings = newSettings
  148. }