GroupStateStore.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include <GroupStateStore.h>
  2. #include <MiLightRemoteConfig.h>
  3. GroupStateStore::GroupStateStore(const size_t maxSize, const size_t flushRate)
  4. : cache(GroupStateCache(maxSize)),
  5. flushRate(flushRate),
  6. lastFlush(0)
  7. { }
  8. GroupState& GroupStateStore::get(const BulbId& id) {
  9. GroupState* state = cache.get(id);
  10. if (state == NULL) {
  11. trackEviction();
  12. GroupState loadedState = GroupState::defaultState(id.deviceType);
  13. persistence.get(id, loadedState);
  14. state = cache.set(id, loadedState);
  15. }
  16. return *state;
  17. }
  18. GroupState& GroupStateStore::get(const uint16_t deviceId, const uint8_t groupId, const MiLightRemoteType deviceType) {
  19. BulbId bulbId(deviceId, groupId, deviceType);
  20. return get(bulbId);
  21. }
  22. // save state for a bulb. If id.groupId == 0, will iternate across all groups
  23. // and individually save each group (recursively)
  24. GroupState& GroupStateStore::set(const BulbId &id, const GroupState& state) {
  25. GroupState& storedState = get(id);
  26. storedState = state;
  27. if (id.groupId == 0) {
  28. const MiLightRemoteConfig* remote = MiLightRemoteConfig::fromType(id.deviceType);
  29. BulbId individualBulb(id);
  30. for (size_t i = 1; i <= remote->numGroups; i++) {
  31. individualBulb.groupId = i;
  32. set(individualBulb, state);
  33. }
  34. }
  35. return storedState;
  36. }
  37. GroupState& GroupStateStore::set(const uint16_t deviceId, const uint8_t groupId, const MiLightRemoteType deviceType, const GroupState& state) {
  38. BulbId bulbId(deviceId, groupId, deviceType);
  39. return set(bulbId, state);
  40. }
  41. void GroupStateStore::trackEviction() {
  42. if (cache.isFull()) {
  43. evictedIds.add(cache.getLru());
  44. }
  45. }
  46. bool GroupStateStore::flush() {
  47. ListNode<GroupCacheNode*>* curr = cache.getHead();
  48. bool anythingFlushed = false;
  49. while (curr != NULL && curr->data->state.isDirty() && !anythingFlushed) {
  50. persistence.set(curr->data->id, curr->data->state);
  51. curr->data->state.clearDirty();
  52. #ifdef STATE_DEBUG
  53. BulbId bulbId = curr->data->id;
  54. printf(
  55. "Flushing dirty state for 0x%04X / %d / %s\n",
  56. bulbId.deviceId,
  57. bulbId.groupId,
  58. MiLightRemoteConfig::fromType(bulbId.deviceType)->name.c_str()
  59. );
  60. #endif
  61. curr = curr->next;
  62. anythingFlushed = true;
  63. }
  64. while (evictedIds.size() > 0 && !anythingFlushed) {
  65. persistence.clear(evictedIds.shift());
  66. anythingFlushed = true;
  67. }
  68. return anythingFlushed;
  69. }
  70. void GroupStateStore::limitedFlush() {
  71. unsigned long now = millis();
  72. if ((lastFlush + flushRate) < now) {
  73. if (flush()) {
  74. lastFlush = now;
  75. }
  76. }
  77. }