| 57 | } |
| 58 | |
| 59 | void ActivityManager::loop() { |
| 60 | if (currentActivity) { |
| 61 | // Note: do not hold a lock here, the loop() method must be responsible for acquire one if needed |
| 62 | currentActivity->loop(); |
| 63 | } |
| 64 | |
| 65 | while (pendingAction != PendingAction::None) { |
| 66 | if (pendingAction == PendingAction::Pop) { |
| 67 | RenderLock lock; |
| 68 | |
| 69 | if (!currentActivity) { |
| 70 | // Should never happen in practice |
| 71 | LOG_ERR("ACT", "Pop set but currentActivity is null; ignoring pop request"); |
| 72 | pendingAction = PendingAction::None; |
| 73 | continue; |
| 74 | } |
| 75 | |
| 76 | ActivityResult pendingResult = std::move(currentActivity->result); |
| 77 | |
| 78 | // Destroy the current activity |
| 79 | exitActivity(lock); |
| 80 | pendingAction = PendingAction::None; |
| 81 | |
| 82 | if (stackActivities.empty()) { |
| 83 | LOG_DBG("ACT", "No more activities on stack, going home"); |
| 84 | lock.unlock(); // goHome may acquire its own lock |
| 85 | goHome(); |
| 86 | continue; // Will launch goHome immediately |
| 87 | |
| 88 | } else { |
| 89 | currentActivity = std::move(stackActivities.back()); |
| 90 | stackActivities.pop_back(); |
| 91 | LOG_DBG("ACT", "Popped from activity stack, new size = %zu", stackActivities.size()); |
| 92 | // Handle result if necessary |
| 93 | if (currentActivity->resultHandler) { |
| 94 | LOG_DBG("ACT", "Handling result for popped activity"); |
| 95 | |
| 96 | // Move it here to avoid the case where handler calling another startActivityForResult() |
| 97 | auto handler = std::move(currentActivity->resultHandler); |
| 98 | currentActivity->resultHandler = nullptr; |
| 99 | lock.unlock(); // Handler may acquire its own lock |
| 100 | handler(pendingResult); |
| 101 | } |
| 102 | |
| 103 | // Request an update to ensure the popped activity gets re-rendered |
| 104 | if (pendingAction == PendingAction::None) { |
| 105 | requestUpdate(); |
| 106 | } |
| 107 | |
| 108 | // Handler may request another pending action, we will handle it in the next loop iteration |
| 109 | continue; |
| 110 | } |
| 111 | |
| 112 | } else if (pendingActivity) { |
| 113 | // Current activity has requested a new activity to be launched |
| 114 | RenderLock lock; |
| 115 | |
| 116 | if (pendingAction == PendingAction::Replace) { |