001package jmri.jmrix.xpa; 002 003import jmri.Turnout; 004import jmri.implementation.AbstractTurnout; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007import javax.annotation.concurrent.GuardedBy; 008 009/** 010 * Xpa+Modem implementation of the Turnout interface. 011 * <p> 012 * Based on XNetTurnout.java 013 * 014 * @author Paul Bender Copyright (C) 2004 015 */ 016public class XpaTurnout extends AbstractTurnout { 017 018 // Private data member to keep track of what turnout we control 019 private final int _number; 020 private final XpaTrafficController tc; 021 022 @GuardedBy("this") 023 protected int _mThrown = Turnout.THROWN; 024 @GuardedBy("this") 025 protected int _mClosed = Turnout.CLOSED; 026 027 /** 028 * Xpa turnouts use any address allowed as an accessory decoder address on 029 * the particular command station. 030 * 031 * @param number turnout number 032 * @param m connection turnout is associated with 033 */ 034 public XpaTurnout(int number, XpaSystemConnectionMemo m) { 035 super(m.getSystemPrefix() + "T" + number); 036 _number = number; 037 tc = m.getXpaTrafficController(); 038 } 039 040 public int getNumber() { 041 return _number; 042 } 043 044 /** 045 * {@inheritDoc} 046 */ 047 @Override 048 synchronized protected void forwardCommandChangeToLayout(int newState) { 049 XpaMessage m; 050 // sort out states 051 if ((newState & _mClosed) != 0) { 052 // first look for the double case, which we can't handle 053 if ((newState & _mThrown ) != 0) { 054 // this is the disaster case! 055 log.error("Cannot command both CLOSED and THROWN {}", newState); 056 return; 057 } else { 058 // send a CLOSED command 059 m = XpaMessage.getSwitchNormalMsg(_number); 060 } 061 } else { 062 // send a THROWN command (or CLOSED if inverted) 063 m = XpaMessage.getSwitchReverseMsg(_number); 064 } 065 tc.sendXpaMessage(m, null); 066 } 067 068 @Override 069 protected void turnoutPushbuttonLockout(boolean _pushButtonLockout) { 070 log.debug("Send command to {} Pushbutton PT{}", (_pushButtonLockout ? "Lock" : "Unlock"), _number); 071 } 072 073 /** 074 * {@inheritDoc} 075 */ 076 @Override 077 synchronized public void setInverted(boolean inverted) { 078 log.debug("Inverting Turnout State for turnout {}", getSystemName() ); 079 if (inverted) { 080 _mThrown = Turnout.CLOSED; 081 _mClosed = Turnout.THROWN; 082 } else { 083 _mThrown = Turnout.THROWN; 084 _mClosed = Turnout.CLOSED; 085 } 086 super.setInverted(inverted); 087 } 088 089 @Override 090 public boolean canInvert() { 091 return true; 092 } 093 094 private final static Logger log = LoggerFactory.getLogger(XpaTurnout.class); 095 096}