001package jmri.jmrix.bidib; 002 003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 004 005import java.util.EnumSet; 006import java.util.HashMap; 007import jmri.DccLocoAddress; 008import jmri.DccThrottle; 009import jmri.LocoAddress; 010import jmri.SpeedStepMode; 011import jmri.ThrottleListener; 012import jmri.jmrix.AbstractThrottleManager; 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016/** 017 * BiDiB implementation of a ThrottleManager. 018 * <P> 019 * @author Bob Jacobsen Copyright (C) 2001 020 * @author Eckart Meyer Copyright (C) 2019 021 */ 022public class BiDiBThrottleManager extends AbstractThrottleManager { 023 024 /** 025 * Constructor. 026 * @param memo system connection memo 027 */ 028 public BiDiBThrottleManager(BiDiBSystemConnectionMemo memo) { 029 super(memo); 030 this.tc = memo.getBiDiBTrafficController(); 031 this.prefix = memo.getSystemPrefix(); 032 } 033 034 //protected HashMap<LocoAddress, BiDiBThrottle> throttles = new HashMap<LocoAddress, BiDiBThrottle>(); 035 protected HashMap<LocoAddress, BiDiBThrottle> throttles = new HashMap<>(); 036 BiDiBTrafficController tc = null; 037 String prefix = ""; 038 039 @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST",justification = "Cast safe by design") 040 @Override 041 public void requestThrottleSetup(LocoAddress a, boolean control) { 042 DccLocoAddress address = (DccLocoAddress) a; 043 BiDiBThrottle throttle; 044 log.debug("request BiDiBThrottle for {}", address); 045 // the BiDiB protocol doesn't require an interaction with the command 046 // station for this, so immediately trigger the callback. 047 048 // We have our own throttle list here to save the loco data when no throttle 049 // is active - JMRI completely forgets loco data after removing the last throttle 050 // for that loco (see AbstactThottleManager, HasMap addressThrottles) 051 // Perhaps we could fiddle with the dipose methods, but there is no example from 052 // other throttle manager. Instead, we use the variant from DCC++ here. 053 054 if (throttles.containsKey(address)) { 055 log.debug("BiDiB throttle found."); 056 throttle = throttles.get(address); 057 notifyThrottleKnown(throttle, address); 058 throttle.requestState(); //try to get loco state from command station 059 } else { 060 log.debug("create new BiDiB throttle."); 061 throttle = new BiDiBThrottle((BiDiBSystemConnectionMemo) adapterMemo, address); 062 throttles.put(address, throttle); 063 notifyThrottleKnown(throttle, address); 064 } 065 } 066 067 /* 068 * BiDiB based systems can have multiple throttles for the same 069 * device 070 */ 071 @Override 072 protected boolean singleUse() { 073 return false; 074 } 075 076 /** 077 * Addresses 0-10239 can be long 078 * 079 */ 080 @Override 081 public boolean canBeLongAddress(int address) { 082 return ((address >= 0) && (address <= 10239)); 083 } 084 085 /** 086 * The short addresses 1-127 are available 087 * 088 */ 089 @Override 090 public boolean canBeShortAddress(int address) { 091 return ((address >= 1) && (address <= 127)); 092 } 093 094 /** 095 * Are there any ambiguous addresses (short vs long) on this system? 096 */ 097 @Override 098 public boolean addressTypeUnique() { 099 return true; 100 } 101 102// @Override 103// public int supportedSpeedModes() { 104// return (DccThrottle.SpeedStepMode128 | DccThrottle.SpeedStepMode28 | DccThrottle.SpeedStepMode14); 105// //return (DccThrottle.SpeedStepMode14 ); 106// } 107 @Override 108 public EnumSet<SpeedStepMode> supportedSpeedModes() { 109 return EnumSet.of(SpeedStepMode.NMRA_DCC_128 110 , SpeedStepMode.NMRA_DCC_28 111 , SpeedStepMode.NMRA_DCC_14); 112 } 113 114/// just to see what happens... 115 @Override 116 public void dispatchThrottle(DccThrottle t, ThrottleListener l) { 117 log.debug("BiDiBThrottleManager.dispatchThrottle: {}, {}", t, l); 118 super.dispatchThrottle(t, l); 119 } 120 121 // called when "Release" button is pressed an also when Throttle window is close. 122 @Override 123 public void releaseThrottle(DccThrottle t, ThrottleListener l) { 124 log.debug("BiDiBThrottleManager.releaseThrottle: {}, {}", t, l); 125 super.releaseThrottle(t, l); 126 } 127/// 128 129 /** 130 * {@inheritDoc} 131 */ 132 @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST",justification = "Cast safe by design") 133 @Override 134 public boolean disposeThrottle(jmri.DccThrottle t, jmri.ThrottleListener l) { 135 if (super.disposeThrottle(t, l)) { 136 BiDiBThrottle bt = (BiDiBThrottle) t; 137 bt.throttleDispose(); 138 //throttles.remove(bt.locoAddress);//TEST - so a new instance will be created next time 139 return true; 140 } 141 return false; 142 } 143 144 private final static Logger log = LoggerFactory.getLogger(BiDiBThrottleManager.class); 145 146}