Skip to content

Исправление багов конечного автомата в модуле ActionButtons - #2

Open
goosecrew wants to merge 1 commit into
bthos:mainfrom
goosecrew:fix/action-buttons-state-machine
Open

Исправление багов конечного автомата в модуле ActionButtons#2
goosecrew wants to merge 1 commit into
bthos:mainfrom
goosecrew:fix/action-buttons-state-machine

Conversation

@goosecrew

Copy link
Copy Markdown

Что изменено

Конечный автомат кнопки в wb-rules-modules/module_ActionButtons.js укреплён против реальных сбоев и ошибок конфигурации; версия модуля поднята до 0.4.0, требования задокументированы в README. Публичный API не изменён (onButtonPress(trigger, action, timeToNextPress, timeOfLongPress, intervalOfRepeat)), модуль остаётся на строгом ES5 (движок Duktape).

Исправленные баги

  • Исключение в пользовательском действии ломало счётчик кликов. Счётчик сбрасывался только после вызова обработчиков, поэтому упавший обработчик singlePress превращал следующий одиночный клик в двойной. Теперь состояние сбрасывается до вызова пользовательских колбэков (то же сделано для флагов длинного нажатия и longRelease).
  • «Зомби»-интервал повтора. Интервал повтора longPress останавливал себя сам по флагу внутри собственного колбэка, а его хэндл мог быть перезаписан следующим длинным нажатием (потерянное событие отпускания либо intervalOfRepeat, сравнимый с timeOfLongPress). Осиротевший интервал продолжал выполнять действие бесконечно. Теперь интервал явно очищается при отпускании, при каждом новом нажатии и перед запуском нового.
  • Фантомный longPress после рассинхронизации состояния. Ветка «отпускание после длинного нажатия» не очищала взведённый timerLongPress: после потерянного события отпускания короткий клик порождал ложный longPress спустя секунду. Теперь эта ветка очищает оба таймера.
  • Фантомный singlePress после рестарта движка правил. Событие отпускания без предшествующего нажатия (wb-rules перезапустился, пока кнопка была зажата) засчитывалось как клик. Теперь оно игнорируется.
  • Случайная глобальная переменная actionRepeatCounter (её объявление var было закомментировано) — удалена.

Устойчивость и удобство

  • Валидация при регистрации: некорректные trigger/action отклоняются с log.error; опечатки в ключах действий (например, singlepress) дают предупреждение вместо молчаливого игнорирования; некорректные тайминги (NaN, строки, ноль/отрицательные значения, Infinity) откатываются к значениям по умолчанию.
  • Устойчивость в рантайме: null вместо описания действия и не-массив в prop больше не роняют колбэк таймера.
  • Контролы, никогда не сообщающие отпускание (тип pushbutton), детектируются на лету с одноразовым предупреждением в лог; ограничение задокументировано в README.
  • defineRule обёрнут в try/catch: повторная регистрация того же триггера логирует ошибку вместо срыва загрузки всего файла правил; onButtonPress теперь возвращает имя созданного правила (можно передавать в disableRule/enableRule) или null.
  • Убраны отладочные логи на каждое нажатие (спам в журнал правил и лишний износ флеш-памяти контроллера).

Тестирование

Проверено стендом на Node.js, эмулирующим окружение wb-rules (детерминированные виртуальные таймеры с числовыми id, перехват исключений колбэков «движком», заглушки defineRule/log): 66 проверок в 24 сценариях — одиночный/двойной/тройной клик, граница окна 300 мс, длинное нажатие с повтором и без, «клик, затем удержание», регрессионный сценарий на каждый исправленный баг, включая проверки «после сценария не осталось висящих таймеров». Отдельная проверка следит, что в модуле нет ES6-синтаксиса.

Сознательно сохранённое ограничение: контрол типа pushbutton с настроенным longRelease не может сам остановить повтор (события отпускания физически не существует) — модуль теперь хотя бы громко предупреждает, что такой контрол не поддерживается.

🤖 Generated with Claude Code

Автомат кнопки укреплён против отказов, которые случаются в реальной
эксплуатации:
- Счётчик кликов и флаги долгого нажатия сбрасываются ДО вызова
пользовательского обработчика. Раньше исключение внутри действия
превращало следующее одиночное нажатие в двойное или ломало автомат
целиком.
- Интервал повтора longPress останавливается явно: при отпускании,
при каждом новом нажатии и перед запуском следующего. Раньше ссылку
на интервал можно было перезаписать, пока старый ещё жив, и при
потерянном событии отпускания оставался зомби-интервал, вечно
выполняющий действие.
- В ветке отпускания после долгого нажатия сбрасывается отложенный
таймер долгого нажатия. Это убирает фантомный longPress, который
срабатывал через секунду после короткого клика при рассинхроне
состояния.
- Событие отпускания без предшествующего нажатия игнорируется
(случается, когда wb-rules перезапускается с зажатой кнопкой),
а не считается фантомным одиночным нажатием.
- Убрана случайная глобальная переменная actionRepeatCounter.
- Аргументы проверяются при регистрации: некорректные trigger и action
отклоняются, опечатки в именах действий вызывают предупреждение
вместо молчаливого игнорирования, невалидные тайминги заменяются
значениями по умолчанию. В рантайме допускаются null-элементы
действий и prop, не являющийся массивом.
- Контролы, которые никогда не сообщают об отпускании (тип
pushbutton), распознаются: пишется однократное предупреждение,
ограничение описано в README.
- defineRule обёрнут в try/catch, поэтому повторная регистрация больше
не прерывает загрузку всего файла правил; при успехе возвращается
имя правила.
- Убрано отладочное логирование на каждое нажатие (мусор в журнале и
износ флеш-памяти).
Проверено на стенде под Node.js, эмулирующем окружение wb-rules
(виртуальные таймеры, обработка исключений на стороне движка):
66 проверок в 24 сценариях, включая регрессионный тест на каждый
исправленный баг. Публичный API не изменился, модуль остаётся строгим
ES5 (Duktape).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@goosecrew
goosecrewforce-pushed the fix/action-buttons-state-machine branch from 6d4b5b2 to 56242f9CompareAugust 25, 2026 18:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@goosecrew