// Шлюзы закрыты, кулдаун public static StateResult?COOLDOWN(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.ExternalDoor(open: false); ctx.Control.InternalDoor(open: false); ctx.Control.AuxDoors(open: false); ctx.Control.Airvents(pressurize: true); ctx.Control.Lights(LightMode.Red); break; case Event.TIMER: if (ctx.Status.IsObstructed) { return(ToState(OBSTRUCTED)); } if (ctx.Time >= MAX_PRESSURIZE_TIME) { return(ToState(IDLE)); } if (ctx.Status.AirVents.IsPressurized && ctx.Status.ExternalDoors.IsClosed && ctx.Status.InternalDoors.IsClosed) { return(ToState(IDLE)); } break; } return(null); }
// Шлюзы закрыты public static StateResult?IDLE(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.ExternalDoor(open: false); ctx.Control.InternalDoor(open: false); ctx.Control.AuxDoors(open: false); ctx.Control.Airvents(pressurize: true); ctx.Control.Lights(LightMode.Off); break; case Event.ENTER_SHIP_APPROACHED: return(ToState(ENTER_DEPRESSURIZING)); case Event.EXIT_SHIP_APPROACHED: return(ToState(EXIT_INNER_OPENING)); case Event.TIMER: if (ctx.Status.IsObstructed) { return(ToState(OBSTRUCTED)); } break; } return(null); }
// Сброс давления public static StateResult?ENTER_DEPRESSURIZING(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.Airvents(pressurize: false); ctx.Control.Lights(LightMode.Blink); break; case Event.TIMER: if (ctx.Status.IsObstructed) { return(ToState(OBSTRUCTED)); } if (ctx.Status.AirVents.IsDepressurized) { return(ToState(ENTER_OUTER_OPENING)); } if (ctx.Time >= MAX_DEPRESSURIZE_TIME) { return(ToState(ENTER_OUTER_OPENING, "Принуд. сброс давления")); } break; } return(null); }
// Дверь открыта (внутрь) public static StateResult?ENTER_INNER_OPEN(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.InternalDoor(open: true); break; case Event.ENTER_SHIP_LEFT: return(ToState(ENTER_INNER_CLOSING)); } return(null); }
// Закрытие двери (наружу) public static StateResult?ENTER_OUTER_CLOSING(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.ExternalDoor(open: false); break; case Event.TIMER: if (ctx.Status.ExternalDoors.IsClosed) { return(ToState(ENTER_PRESSURIZING)); } break; } return(null); }
// Обнаружено препятствие public static StateResult?OBSTRUCTED(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.Lights(LightMode.Red); break; case Event.TIMER: if (!ctx.Status.IsObstructed) { return(ToState(COOLDOWN)); } break; } return(null); }
// Закрытие внешней двери public static StateResult?WAIT_TIMED_OUT(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.InternalDoor(open: false); ctx.Control.ExternalDoor(open: false); ctx.Control.Lights(LightMode.Off); break; case Event.TIMER: if (ctx.Status.ExternalDoors.IsClosed && ctx.Status.InternalDoors.IsClosed) { return(ToState(COOLDOWN)); } break; } return(null); }
// Внешняя дверь открыта public static StateResult?EXIT_OUTER_OPEN(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: break; case Event.EXIT_SHIP_LEFT: return(ToState(EXIT_OUTER_CLOSING)); case Event.TIMER: if (ctx.Time >= MAX_WAIT_TIME) { return(ToState(WAIT_TIMED_OUT)); } break; } return(null); }
// Внутренняя дверь открыта public static StateResult?EXIT_INNER_OPEN(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.InternalDoor(open: true); break; case Event.EXIT_SHIP_INSIDE: return(ToState(EXIT_INNER_CLOSING)); case Event.TIMER: if (ctx.Time >= MAX_WAIT_TIME) { return(ToState(WAIT_TIMED_OUT)); } break; } return(null); }
// Открытие внутренней двери public static StateResult?EXIT_INNER_OPENING(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.InternalDoor(open: true); break; case Event.TIMER: if (ctx.Status.InternalDoors.IsOpen) { return(ToState(EXIT_INNER_OPEN)); } break; case Event.EXIT_SHIP_INSIDE: return(ToState(EXIT_INNER_CLOSING)); } return(null); }
// Закрытие внешней двери public static StateResult?EXIT_OUTER_CLOSING(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.ExternalDoor(open: false); break; case Event.TIMER: if (ctx.Status.IsObstructed) { return(ToState(OBSTRUCTED)); } if (ctx.Status.ExternalDoors.IsClosed) { return(ToState(COOLDOWN)); } break; } return(null); }
// Открытие внешней двери public static StateResult?EXIT_OUTER_OPENING(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.ExternalDoor(open: true); ctx.Control.Lights(LightMode.On); break; case Event.TIMER: if (ctx.Status.ExternalDoors.IsOpen) { return(ToState(EXIT_OUTER_OPEN)); } break; case Event.EXIT_SHIP_LEFT: return(ToState(EXIT_OUTER_CLOSING)); } return(null); }
// Набор давления public static StateResult?ENTER_PRESSURIZING(ref StateCtx ctx) { switch (ctx.Event) { case Event.INIT: ctx.Control.Airvents(pressurize: true); ctx.Control.Lights(LightMode.Blink); break; case Event.TIMER: if (ctx.Status.AirVents.IsPressurized) { return(ToState(ENTER_INNER_OPENING)); } if (ctx.Time >= MAX_PRESSURIZE_TIME) { return(ToState(ENTER_INNER_OPENING, "Принуд. набор давления")); } break; } return(null); }
public void Update(IController control, Event e, ref AirlockStatus status) { if (state == null || e == Event.RESET) { state = IDLE; stateTime = DateTime.UtcNow; Update(control, Event.INIT, ref status); if (e == Event.RESET) { return; } } var ctx = new StateCtx { Event = e, Status = status, Control = control, Time = (DateTime.UtcNow - stateTime).TotalSeconds }; var result = state(ref ctx); if (result != null) { description = result.Value.Description; if (state != result.Value.NextState) { state = result.Value.NextState; stateTime = DateTime.UtcNow; Update(control, Event.INIT, ref status); } } }