signals.cxx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <furi.h>
  2. #include "objects.h"
  3. #include "signals.h"
  4. void SignalManager::register_signal(int id, void* ctx) {
  5. // FURI_LOG_I("SIGNAL", "Registered signal, id = %d", id);
  6. signals.push_back({id, ctx, false});
  7. }
  8. void SignalManager::register_slot(int id, void* ctx) {
  9. // FURI_LOG_I("SIGNAL", "Registered slot, id = %d", id);
  10. slots.push_back({id, ctx, false});
  11. }
  12. // Send signal 'id' and account for type ALL and ANY
  13. void SignalManager::send(void* ctx) {
  14. FixedObject* obj = (FixedObject*)ctx;
  15. int id = obj->tx_id;
  16. if(id == INVALID_ID) {
  17. return;
  18. }
  19. // FURI_LOG_I("SIGNAL", "Attempting to send signal %d", id);
  20. bool signal = true;
  21. for(auto& s : signals) {
  22. if(s.id == id) {
  23. if(s.ctx == ctx) {
  24. s.triggered = true;
  25. if(((FixedObject*)(ctx))->tx_type == SignalType::ANY) {
  26. signal = true;
  27. break;
  28. }
  29. }
  30. signal = signal & s.triggered;
  31. }
  32. }
  33. if(signal) {
  34. // Send the signal to all objects who want it
  35. // FURI_LOG_I(
  36. // "SIGNAL",
  37. // "Signals for id=%d, and type=%s",
  38. // id,
  39. // ((FixedObject*)(ctx))->tx_type == SignalType::ALL ? "ALL" : "ANY");
  40. for(auto& s : slots) {
  41. if(s.id == id) {
  42. ((FixedObject*)(s.ctx))->signal_receive();
  43. }
  44. }
  45. // Clear our internal state of what triggered (used for type ALL)
  46. reset(id);
  47. // Let the signal initiating objects know that we have sent the signal
  48. for(auto& s : signals) {
  49. if(s.id == id) {
  50. ((FixedObject*)(s.ctx))->signal_send();
  51. }
  52. }
  53. }
  54. }
  55. void SignalManager::reset(int id) {
  56. for(auto& s : signals) {
  57. if(s.id == id) {
  58. s.triggered = false;
  59. }
  60. }
  61. }
  62. // better data structures would make this function more efficient
  63. bool SignalManager::validate(char* err, std::size_t err_size) {
  64. // Verify that there is at least one slot for every signal
  65. for(const auto& signal : signals) {
  66. bool found = false;
  67. for(const auto& slot : slots) {
  68. if(signal.id == slot.id) {
  69. found = true;
  70. break;
  71. }
  72. }
  73. if(!found) {
  74. FURI_LOG_E("PB0 SIGNAL", "Signal %d has no slots!", signal.id);
  75. snprintf(err, err_size, "Signal %d\nhas no\nslots!", signal.id);
  76. return false;
  77. }
  78. }
  79. // Verify that there is at least one signal for every slot
  80. for(const auto& slot : slots) {
  81. bool found = false;
  82. for(const auto& signal : signals) {
  83. if(slot.id == signal.id) {
  84. found = true;
  85. break;
  86. }
  87. }
  88. if(!found) {
  89. FURI_LOG_E("PB0 SIGNAL", "Slot %d has no signals!", slot.id);
  90. snprintf(err, err_size, "Slot %d\nhas no\nsignals!", slot.id);
  91. return false;
  92. }
  93. }
  94. // Verify that all objects with the same signal id have the same trigger type
  95. bool valid_types = true;
  96. for(const auto& signal : signals) {
  97. const SignalType signal_type = ((FixedObject*)signal.ctx)->tx_type;
  98. for(const auto& s : signals) {
  99. FixedObject* s_obj = (FixedObject*)signal.ctx;
  100. if(signal.id == s.id && signal_type != s_obj->tx_type) {
  101. valid_types = false;
  102. FURI_LOG_E("PB0 SIGNAL", "Signal %d has differing type!", s.id);
  103. snprintf(err, err_size, "Signal %d\nhas diff\ntype!", s.id);
  104. break;
  105. }
  106. }
  107. if(!valid_types) {
  108. break;
  109. }
  110. }
  111. return valid_types;
  112. }