fix: prevent ValvePairModel stuck-state by freezing prev_action during delay

This commit is contained in:
Huamonarch 2026-05-13 15:43:56 +08:00
parent 10bb9937d6
commit d9b4ee8eb3

View File

@ -36,25 +36,22 @@ struct ValvePairModel : IModel {
if (!action) return false; if (!action) return false;
bool action_now = action->evaluateBool(t); bool action_now = action->evaluateBool(t);
bool rising_edge = !prev_action && action_now;
bool falling_edge = prev_action && !action_now;
prev_action = action_now;
switch (state) { switch (state) {
case IDLE_LOW: case IDLE_LOW:
if (rising_edge) { if (!prev_action && action_now) {
bool over = ((double)rand() / RAND_MAX) < delay_over_prob; bool over = ((double)rand() / RAND_MAX) < delay_over_prob;
int base = over ? delay_over_ticks : on_delay_ticks; int base = over ? delay_over_ticks : on_delay_ticks;
delay_counter = base + (delay_jitter_ticks ? rand() % (delay_jitter_ticks + 1) : 0); delay_counter = base + (delay_jitter_ticks ? rand() % (delay_jitter_ticks + 1) : 0);
state = WAITING_RISE; state = WAITING_RISE;
} }
prev_action = action_now;
break; break;
case WAITING_RISE: case WAITING_RISE:
if (delay_counter > 0) { delay_counter--; } if (delay_counter > 0) { delay_counter--; }
else { state = HIGH; } else { state = HIGH; }
break; break;
case HIGH: case HIGH:
if (falling_edge) { if (prev_action && !action_now) {
bool over = ((double)rand() / RAND_MAX) < delay_over_prob; bool over = ((double)rand() / RAND_MAX) < delay_over_prob;
int base = over ? delay_over_ticks : off_delay_ticks; int base = over ? delay_over_ticks : off_delay_ticks;
delay_counter = base + (delay_jitter_ticks ? rand() % (delay_jitter_ticks + 1) : 0); delay_counter = base + (delay_jitter_ticks ? rand() % (delay_jitter_ticks + 1) : 0);
@ -62,6 +59,7 @@ struct ValvePairModel : IModel {
} else if (((double)rand() / RAND_MAX) < flash_prob) { } else if (((double)rand() / RAND_MAX) < flash_prob) {
return false; return false;
} }
prev_action = action_now;
break; break;
case WAITING_FALL: case WAITING_FALL:
if (delay_counter > 0) { delay_counter--; } if (delay_counter > 0) { delay_counter--; }