LogicChainsSystem (Core)
Namespace: Vortex.Core.LogicChainsSystem.Bus, Vortex.Core.LogicChainsSystem.Model
Сборка: ru.vortex.logicchains
Платформа: .NET Standard 2.1+
Назначение
Система логических цепочек. Позволяет описывать последовательность этапов с действиями, переходами и условиями. Цепочка выполняется пошагово: при входе в этап срабатывают действия, затем активируются коннекторы с условиями перехода к следующему этапу.
Возможности:
- Граф этапов с направленными переходами (коннекторами)
- Действия (
LogicAction) при входе в этап - Условия (
Condition) на переходах — асинхронные, с callback-механизмом - Автоматические переходы (коннектор без условий)
- Сохранение/загрузка текущего этапа через
Record - Регистрация цепочек по GUID, multi-instance через
Database
Вне ответственности:
- Конкретные действия и условия — реализуются наследниками в Unity-слое
- Визуальное редактирование графа — пресеты в Unity-слое
- UI отображение прогресса
Зависимости
| Зависимость | Назначение |
|---|---|
Vortex.Core.System |
SystemModel |
Vortex.Core.DatabaseSystem |
Record, Database.GetNewRecord() |
Vortex.Core.Extensions |
Crypto.GetNewGuid(), DictionaryExt |
Vortex.Core.LoggerSystem |
Log.Print() для диагностики |
Vortex.Core.SettingsSystem |
Settings.Data().DebugMode для отладочных логов |
Архитектура
LogicChains (static bus)
├── Index: Dictionary<string, LogicChain>
├── AddChain(LogicChain) → guid
├── AddChain(presetGuid) → guid ← Database.GetNewRecord<LogicChain>
├── RunChain(guid) ← запуск / продолжение цепочки
└── CheckConditions(guid, connector) ← внутренняя проверка перехода
LogicChain : Record
├── ChainSteps: Dictionary<string, ChainStep>
├── StartStep: string (GUID)
├── CurrentStep: string (GUID)
├── GetDataForSave() → CurrentStep
└── LoadFromSaveData(data) → CurrentStep = data
ChainStep : SystemModel
├── Guid, Name, Description
├── Actions: LogicAction[] ← выполняются при входе в этап
└── Connectors: Connector[] ← переходы к другим этапам
Connector : SystemModel
├── TargetStepGuid: string
└── Conditions: Condition[] ← все должны быть true для перехода
LogicAction (abstract)
└── Invoke() ← действие при входе в этап
Condition (abstract)
├── Init(Action callback) ← запуск мониторинга
├── Check() → bool ← проверка выполнения
├── DeInit() ← остановка мониторинга
├── Start() ← внутренняя инициализация
└── RunCallback() ← уведомление о возможном выполнении
Жизненный цикл цепочки
AddChain → RunChain → [Enter Step]
├── Invoke Actions[]
└── For each Connector:
├── Conditions.Length == 0 → автопереход
└── Conditions[].Init(callback)
└── callback → CheckConditions
├── All Check() == true → переход
│ ├── DeInit all Conditions
│ ├── CurrentStep = TargetStepGuid
│ ├── target == "-1" → завершение
│ └── RunChain (следующий этап)
└── Any Check() == false → ожидание
Condition — асинхронная модель
Условие не опрашивается по таймеру. Init(callback) запускает наблюдение (подписка на событие, таймер и т.д.). При изменении состояния условие вызывает RunCallback(), что запускает CheckConditions — проверку всех условий коннектора. Если все Check() == true, переход выполняется.
Завершение цепочки
Коннектор с TargetStepGuid == "-1" (CompleteChainStep) завершает цепочку: она удаляется из Index. При DebugMode выводится лог.
Контракт
Вход
LogicChainдобавляется черезAddChain()— напрямую или по GUID пресета изDatabaseRunChain(guid)запускает выполнение
Выход
- Действия (
LogicAction.Invoke()) вызываются при входе в этап - Переходы выполняются автоматически при выполнении условий
- Цепочка завершается при переходе к
CompleteChainStep
API
| Метод | Описание |
|---|---|
LogicChains.AddChain(LogicChain) |
Регистрация цепочки, возвращает GUID |
LogicChains.AddChain(string presetGuid) |
Создание цепочки из пресета Database, возвращает GUID |
LogicChains.RunChain(string guid) |
Запуск или продолжение цепочки |
Константы
| Константа | Значение | Описание |
|---|---|---|
CompleteChainStep |
"-1" |
GUID-маркер завершения цепочки |
Сохранение
LogicChain : Record — сохраняет и восстанавливает CurrentStep. При загрузке RunChain продолжит с сохранённого этапа.
Ограничения
| Ограничение | Причина |
|---|---|
| Один активный этап на цепочку | CurrentStep — единственный указатель |
| Условия проверяются AND-логикой | Все Condition.Check() должны быть true |
| Первый подходящий коннектор побеждает | При автопереходе (0 условий) остальные коннекторы не проверяются |
| Нет отмены цепочки | Удаление из Index только при завершении |
| Цикличные цепочки допустимы | Нет защиты от бесконечных циклов |
Использование
Создание действия
public class ShowNotification : LogicAction
{
public string Message;
public override void Invoke()
{
NotificationSystem.Show(Message);
}
}
Создание условия
public class PlayerLevelReached : Condition
{
public int TargetLevel;
protected override void Start()
{
PlayerModel.OnLevelChanged += OnLevelChanged;
if (Check()) RunCallback();
}
private void OnLevelChanged(int level)
{
if (Check()) RunCallback();
}
public override bool Check() => PlayerModel.Level >= TargetLevel;
public override void DeInit() => PlayerModel.OnLevelChanged -= OnLevelChanged;
}
Запуск цепочки
// Из пресета Database
var guid = LogicChains.AddChain("preset-guid-from-database");
LogicChains.RunChain(guid);
// Из объекта
var chain = new LogicChain();
// ... настройка ChainSteps, StartStep ...
var guid = LogicChains.AddChain(chain);
LogicChains.RunChain(guid);
Граничные случаи
| Ситуация | Поведение |
|---|---|
GUID цепочки не найден в Index |
Log.Print(Error), выполнение прерывается |
StartStep не найден в ChainSteps |
Log.Print(Error), выполнение прерывается |
| Коннектор без условий | Автоматический переход к TargetStepGuid |
| Все условия коннектора выполнены | Переход, DeInit всех условий текущего этапа |
TargetStepGuid == "-1" |
Цепочка завершена, удалена из Index |
Исключение в CheckConditions |
Log.Print(Error), condition.DeInit() |
CurrentStep уже установлен при RunChain |
Продолжение с текущего этапа (не с StartStep) |
DebugMode активен |
Дополнительный лог при завершении цепочки |