TransitionController.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include <Transition.h>
  2. #include <FieldTransition.h>
  3. #include <ColorTransition.h>
  4. #include <ChangeFieldOnFinishTransition.h>
  5. #include <GroupStateField.h>
  6. #include <MiLightStatus.h>
  7. #include <TransitionController.h>
  8. #include <LinkedList.h>
  9. #include <functional>
  10. using namespace std::placeholders;
  11. TransitionController::TransitionController()
  12. : callback(std::bind(&TransitionController::transitionCallback, this, _1, _2, _3))
  13. , currentId(0)
  14. , defaultPeriod(500)
  15. { }
  16. void TransitionController::setDefaultPeriod(uint16_t defaultPeriod) {
  17. this->defaultPeriod = defaultPeriod;
  18. }
  19. void TransitionController::clearListeners() {
  20. observers.clear();
  21. }
  22. void TransitionController::addListener(Transition::TransitionFn fn) {
  23. observers.push_back(fn);
  24. }
  25. std::shared_ptr<Transition::Builder> TransitionController::buildColorTransition(const BulbId& bulbId, const ParsedColor& start, const ParsedColor& end) {
  26. return std::make_shared<ColorTransition::Builder>(
  27. currentId++,
  28. defaultPeriod,
  29. bulbId,
  30. callback,
  31. start,
  32. end
  33. );
  34. }
  35. std::shared_ptr<Transition::Builder> TransitionController::buildFieldTransition(const BulbId& bulbId, GroupStateField field, uint16_t start, uint16_t end) {
  36. return std::make_shared<FieldTransition::Builder>(
  37. currentId++,
  38. defaultPeriod,
  39. bulbId,
  40. callback,
  41. field,
  42. start,
  43. end
  44. );
  45. }
  46. std::shared_ptr<Transition::Builder> TransitionController::buildStatusTransition(const BulbId& bulbId, MiLightStatus status, uint8_t startLevel) {
  47. std::shared_ptr<Transition::Builder> transition;
  48. if (status == ON) {
  49. // Make sure bulb is on before transitioning brightness
  50. callback(bulbId, GroupStateField::STATUS, ON);
  51. transition = buildFieldTransition(bulbId, GroupStateField::LEVEL, startLevel, 100);
  52. } else {
  53. transition = std::make_shared<ChangeFieldOnFinishTransition::Builder>(
  54. currentId++,
  55. GroupStateField::STATUS,
  56. OFF,
  57. buildFieldTransition(bulbId, GroupStateField::LEVEL, startLevel, 0)
  58. );
  59. }
  60. return transition;
  61. }
  62. void TransitionController::addTransition(std::shared_ptr<Transition> transition) {
  63. activeTransitions.add(transition);
  64. }
  65. void TransitionController::transitionCallback(const BulbId& bulbId, GroupStateField field, uint16_t arg) {
  66. for (auto it = observers.begin(); it != observers.end(); ++it) {
  67. (*it)(bulbId, field, arg);
  68. }
  69. }
  70. void TransitionController::clear() {
  71. activeTransitions.clear();
  72. }
  73. void TransitionController::loop() {
  74. auto current = activeTransitions.getHead();
  75. while (current != nullptr) {
  76. auto next = current->next;
  77. Transition& t = *current->data;
  78. t.tick();
  79. if (t.isFinished()) {
  80. activeTransitions.remove(current);
  81. }
  82. current = next;
  83. }
  84. }
  85. ListNode<std::shared_ptr<Transition>>* TransitionController::getTransitions() {
  86. return activeTransitions.getHead();
  87. }
  88. ListNode<std::shared_ptr<Transition>>* TransitionController::findTransition(size_t id) {
  89. auto current = getTransitions();
  90. while (current != nullptr) {
  91. if (current->data->id == id) {
  92. return current;
  93. }
  94. current = current->next;
  95. }
  96. return nullptr;
  97. }
  98. Transition* TransitionController::getTransition(size_t id) {
  99. auto node = findTransition(id);
  100. if (node == nullptr) {
  101. return nullptr;
  102. } else {
  103. return node->data.get();
  104. }
  105. }
  106. bool TransitionController::deleteTransition(size_t id) {
  107. auto node = findTransition(id);
  108. if (node == nullptr) {
  109. return false;
  110. } else {
  111. activeTransitions.remove(node);
  112. return true;
  113. }
  114. }