Skip to content

Commit 0e1ed14

Browse files
committed
Trigger emergency even for briefly active inputs
This is especially relevant for the injected key presses, which predate the activation and immediately deactivate the input. The emergency check won't run between these two, so we need a flag for a pending emergency.
1 parent e75294d commit 0e1ed14

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

src/drivers/input/input_driver.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,25 @@ bool Input::Update(bool new_active, uint32_t predate) {
1414
const uint32_t now = xbot::service::system::getTimeMicros() - predate;
1515
if (new_active) {
1616
active_since = now;
17+
input_service.OnInputChanged(*this, true, 0);
18+
} else {
19+
const uint32_t duration = ActiveDuration(now);
20+
if (emergency_reason != 0 && duration >= emergency_delay_ms * 1'000) {
21+
emergency_pending = true;
22+
}
23+
input_service.OnInputChanged(*this, false, duration);
1724
}
18-
input_service.OnInputChanged(*this, new_active, ActiveDuration(now));
1925
chEvtBroadcastFlags(&mower_events, MowerEvents::INPUTS_CHANGED);
2026
return true;
2127
}
2228
return false;
2329
}
2430

31+
bool Input::GetAndClearPendingEmergency() {
32+
bool only_if_pending = true;
33+
return emergency_pending.compare_exchange_strong(only_if_pending, false);
34+
}
35+
2536
void Input::InjectPress(bool long_press) {
2637
InjectPress(input_service.GetPressDelay(long_press));
2738
}

src/drivers/input/input_driver.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct Input {
3434
}
3535

3636
bool Update(bool new_active, uint32_t predate = 0);
37+
bool GetAndClearPendingEmergency();
3738

3839
void InjectPress(bool long_press = false);
3940
void InjectPress(uint32_t duration);
@@ -43,9 +44,10 @@ struct Input {
4344
}
4445

4546
private:
46-
etl::atomic<bool> active = false;
47-
uint32_t active_since = 0;
48-
Input* next_for_driver_ = nullptr;
47+
etl::atomic<bool> active{false};
48+
etl::atomic<bool> emergency_pending{false};
49+
uint32_t active_since{0};
50+
Input* next_for_driver_{nullptr};
4951

5052
friend class InputDriver;
5153
friend struct InputIterable;

src/services/input_service/input_service.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,13 @@ etl::pair<uint16_t, uint32_t> InputService::GetEmergencyReasons(uint32_t now) {
223223
Lock lk(&mutex_);
224224
uint16_t reasons = 0;
225225
uint32_t block_time = UINT32_MAX;
226-
for (const auto& input : all_inputs_) {
227-
// TODO: What if the input was triggered so briefly that we couldn't observe it?
228-
if (input.emergency_reason == 0 || !input.IsActive()) continue;
229-
if (TimeoutReached(input.ActiveDuration(now), input.emergency_delay_ms * 1'000, block_time)) {
226+
for (auto& input : all_inputs_) {
227+
if (input.emergency_reason == 0) continue;
228+
if (input.GetAndClearPendingEmergency()) {
229+
reasons |= input.emergency_reason;
230+
block_time = 0;
231+
} else if (input.IsActive() &&
232+
TimeoutReached(input.ActiveDuration(now), input.emergency_delay_ms * 1'000, block_time)) {
230233
reasons |= input.emergency_reason;
231234
}
232235
}

0 commit comments

Comments
 (0)