This signal is protecting the points-end of a turnout.
Depending on whether the turnout is thrown or closed, the
train will take two different routes, and the
signal will protect different next blocks.
void doFacing() {
int appearance = SignalHead.GREEN;
int oldAppearance = ((SignalHead)outputs[0]).getAppearance();
// find downstream appearance, being pessimistic if we're not sure of the state
int s = SignalHead.GREEN;
if (watchTurnout!=null && watchTurnout.getBean().getKnownState() != Turnout.THROWN)
s = slowerOf(s, fastestColor1());
if (watchTurnout!=null && watchTurnout.getBean().getKnownState() != Turnout.CLOSED)
s = slowerOf(s, fastestColor2());
// check for yellow, flashing yellow overriding green
if (protectWithFlashing && s==SignalHead.YELLOW)
appearance = SignalHead.FLASHYELLOW;
if (s==SignalHead.RED || s==SignalHead.FLASHRED)
appearance = SignalHead.YELLOW;
// if distant signal, show exactly what the home signal does
if (distantSignal)
appearance = s;
// if limited speed and green or flashing yellow, reduce to yellow
if (watchTurnout!=null && limitSpeed1 && watchTurnout.getBean().getKnownState()!=Turnout.THROWN)
appearance = slowerOf(appearance, SignalHead.YELLOW);
if (watchTurnout!=null && limitSpeed2 && watchTurnout.getBean().getKnownState()!=Turnout.CLOSED)
appearance = slowerOf(appearance, SignalHead.YELLOW);
// check for red overriding yellow or green
if (watchSensor1!=null && watchSensor1.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor2!=null && watchSensor2.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor3!=null && watchSensor3.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor4!=null && watchSensor4.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if ((watchTurnout!=null && watchTurnout.getBean().getKnownState() == Turnout.CLOSED)
&& ((watchedSensor1!=null && watchedSensor1.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
if ((watchTurnout!=null && watchTurnout.getBean().getKnownState() == Turnout.CLOSED) && ((watchedSensor1Alt!=null && watchedSensor1Alt.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
if ((watchTurnout!=null && watchTurnout.getBean().getKnownState() == Turnout.THROWN) && ((watchedSensor2!=null && watchedSensor2.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
if ((watchTurnout!=null && watchTurnout.getBean().getKnownState() == Turnout.THROWN) && ((watchedSensor2Alt!=null && watchedSensor2Alt.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
// check if turnout in motion, if so force red
if (watchTurnout!=null && (watchTurnout.getBean().getKnownState() != watchTurnout.getBean().getCommandedState()) )
appearance = SignalHead.RED;
if (watchTurnout!=null && (watchTurnout.getBean().getKnownState() != Turnout.THROWN) && (watchTurnout.getBean().getKnownState() != Turnout.CLOSED) ) // checking for other states
appearance = SignalHead.RED;
// check if signal if held, forcing a red aspect by this calculation
if (((SignalHead)outputs[0]).getHeld())
appearance = SignalHead.RED;
// handle approach lighting
doApproach();
// show result if changed
if (appearance != oldAppearance)
((SignalHead)outputs[0]).setAppearance(appearance);
}