StateValve (Core)
Namespace: Vortex.Core.StateValve
Сборка: ru.vortex.core.statevalve
Назначение
Реактивный вентиль состояния — примитив, сводящий N именованных булевых створок («ключей») в один булев итог по режиму свёртки + инверсия. Нейтрален к домену: оперирует «открыто/закрыто», смысл («закрыто = пауза») придаёт применяющий.
Это примитив, не система: инстанцируется через new (как ReactiveValue, DateTimeTimer), без шины, драйвера, контроллера и пресетов.
- N именованных створок «открыт/закрыт»
- Свёртка в один итог:
And/Or/Xor - Инверсия итога (NOT)
- Реактивный вывод
State : BoolDataпод owner-lock - fail-fast на пустой ключ
Зависимости
Vortex.Core.Extensions.ReactiveValues—BoolData
Модель
StateValve
├── State : BoolData ← реактивный итог (owner-lock), только чтение/подписка
├── Keys : IReadOnlyDictionary<string,bool> ← створки, для отладки
├── Open(string) / Close(string)
└── ctor(ValveMode mode = And, bool invert = false)
ValveMode { And, Or, Xor }
Свёртка (таблицы истинности, при наличии ключей)
| Режим | Открыт, если |
|---|---|
And |
открыты ВСЕ |
Or |
открыт ХОТЬ ОДИН |
Xor |
открыт РОВНО ОДИН (ноль или ≥2 открытых → закрыт) |
Пустой набор → открыт (вентиль не закрывали) — конвенция вентиля, единообразно во всех режимах, до инверсии. Итог: final = invert ? !raw : raw.
Контракт
Stateпишется только пересчётом послеOpen/Close(owner-lock; внешнийSetневозможен).- Пустой/
nullключ →ArgumentException(fail-fast, баг вызывающего). - Освобождение створки =
Open(id)— ключ остаётся в наборе открытым; удаления ключей нет.
Ре-энтрантность (однопоточно)
Клапан гардов не добавляет намеренно.
- Безобидная вложенность (подписчик на
Stateв колбэке зовётOpen/Close) отрабатывает:BoolDataдедупит (событие только на реальном изменении), порядок last-write-wins, сходящаяся цепочка затихает. - Осциллирующая (подписчик крутит ключ так, что итог переворачивается обратно) — ошибка композиции вызывающего: проявится stack overflow как fail-fast сигнал о встречной петле. Контракт: не сводить самоподдерживающийся цикл.
Использование
var valve = new StateValve(ValveMode.And); // «идёт» = все ключи открыты
valve.State.OnUpdate += open => SetPaused(!open);
valve.Close("tutor"); // закрыт → State = false
valve.Close("countdown"); // ещё один держит
valve.Open("tutor"); // отпустил, но countdown держит → всё ещё закрыт
valve.Open("countdown"); // все открыты → State = true
Unity-обёртка (StateValveHandler, пакет ru.vortex.unity.statevalve) добавляет настройку в инспекторе, whitelist-фильтр ключей и слабую привязку через IDataStorage.