001package jmri.jmrix.roco.z21; 002 003import java.util.Comparator; 004import java.util.ResourceBundle; 005 006import jmri.*; 007import jmri.jmrix.ConfiguringSystemConnectionMemo; 008import jmri.jmrix.lenz.XNetProgrammerManager; 009import jmri.util.NamedBeanComparator; 010 011import org.slf4j.Logger; 012import org.slf4j.LoggerFactory; 013 014/** 015 * Lightweight class to denote that a system is active, and provide general 016 * information. 017 * <p> 018 * Objects of specific subtypes are registered in the instance manager to 019 * activate their particular system. 020 * 021 * @author Bob Jacobsen Copyright (C) 2010 copied from NCE into PowerLine for 022 * multiple connections by 023 * @author Ken Cameron Copyright (C) 2011 copied from PowerLine into z21 by 024 * @author Paul Bender Copyright (C) 2013,2019,2020 025 */ 026public class Z21SystemConnectionMemo extends jmri.jmrix.DefaultSystemConnectionMemo implements ConfiguringSystemConnectionMemo { 027 028 private Z21XPressNetTunnel _xnettunnel = null; 029 private Z21LocoNetTunnel _loconettunnel = null; 030 031 public Z21SystemConnectionMemo() { 032 this("Z", "Z21"); 033 } 034 035 public Z21SystemConnectionMemo(String prefix, String userName) { 036 super(prefix, userName); 037 InstanceManager.store(this, Z21SystemConnectionMemo.class); // also register as specific type 038 init(); 039 } 040 041 /* 042 * Override the init function for any subtype specific 043 * registration into init. init is called by the generic contstructor. 044 */ 045 protected void init() { 046 // create and register the ComponentFactory 047 InstanceManager.store(componentFactory = new jmri.jmrix.roco.z21.swing.Z21ComponentFactory(this), 048 jmri.jmrix.swing.ComponentFactory.class); 049 } 050 051 jmri.jmrix.swing.ComponentFactory componentFactory = null; 052 053 /** 054 * Traffic Controller for this instance. 055 * @param newtc Z21 traffic controller. 056 */ 057 public void setTrafficController(Z21TrafficController newtc) { 058 _tc = newtc; 059 } 060 061 public Z21TrafficController getTrafficController() { 062 return _tc; 063 } 064 private Z21TrafficController _tc = null; 065 066 /** 067 * Reporter Manager for this instance. 068 * @param rm reporter manager. 069 */ 070 public void setReporterManager(Z21ReporterManager rm){ 071 store(rm, ReporterManager.class); 072 } 073 074 public Z21ReporterManager getReporterManager() { 075 return (Z21ReporterManager) classObjectMap.computeIfAbsent(ReporterManager.class, (Class<?> c) -> { return new Z21ReporterManager(this); }); 076 } 077 078 /** 079 * SensorManager for this instance. 080 * @param sm sensor manager. 081 */ 082 public void setSensorManager(Z21SensorManager sm){ 083 store(sm,SensorManager.class); 084 } 085 086 public Z21SensorManager getSensorManager() { 087 return (Z21SensorManager) classObjectMap.computeIfAbsent(SensorManager.class, (Class<?> c) -> { return new Z21SensorManager(this); }); 088 } 089 090 public XNetProgrammerManager getProgrammerManager() { 091 if (_xnettunnel!=null) { 092 // delegate to the XPressNet tunnel. 093 return _xnettunnel.getStreamPortController().getSystemConnectionMemo().getProgrammerManager(); 094 } 095 return null; 096 } 097 098 public void setProgrammerManager(XNetProgrammerManager p) { 099 } 100 101 /** 102 * Tells which managers this class provides. 103 */ 104 @Override 105 public boolean provides(Class<?> type) { 106 if (getDisabled()) { 107 return false; 108 } 109 if (type.equals(jmri.ReporterManager.class)){ 110 return true; 111 } 112 if (type.equals(jmri.SensorManager.class)){ 113 return true; 114 } 115 if (_xnettunnel!=null) { 116 // delegate to the XPressNet tunnel. 117 if(_xnettunnel.getStreamPortController().getSystemConnectionMemo().provides(type)) { 118 return true; 119 } // don't return false here, let the following code run 120 } 121 if (_loconettunnel!=null) { 122 // delegate to the LocoNet tunnel. 123 if(_loconettunnel.getStreamPortController().getSystemConnectionMemo().provides(type)) { 124 return true; 125 } // don't return false here, let the following code run 126 127 } 128 return super.provides(type); // nothing, by default 129 } 130 131 /** 132 * Provide manager by class. 133 */ 134 @Override 135 public <T> T get(Class<T> T) { 136 if (getDisabled()) { 137 return null; 138 } 139 if(T.equals(jmri.ReporterManager.class)){ 140 return super.get(T); 141 } 142 if(T.equals(jmri.SensorManager.class)){ 143 return super.get(T); 144 } 145 if (_xnettunnel!=null && _xnettunnel.getStreamPortController().getSystemConnectionMemo().provides(T) ) { 146 // delegate to the XPressNet tunnel. 147 return _xnettunnel.getStreamPortController().getSystemConnectionMemo().get(T); 148 } 149 if (_loconettunnel!=null && _loconettunnel.getStreamPortController().getSystemConnectionMemo().provides(T) ) { 150 // delegate to the LocoNet tunnel. 151 return _loconettunnel.getStreamPortController().getSystemConnectionMemo().get(T); 152 } 153 return null; // nothing, by default 154 } 155 156 /** 157 * Configure the common managers for z21 connections. This puts the common 158 * manager config in one place. 159 */ 160 @Override 161 public void configureManagers() { 162 log.debug("Called Configure Managers"); 163 164 RocoZ21CommandStation z21CommandStation = getRocoZ21CommandStation(); 165 166 // set the broadcast flags so we get messages we may want to hear 167 z21CommandStation.setXPressNetMessagesFlag(true); 168 z21CommandStation.setXPressNetLocomotiveMessagesFlag(true); 169 z21CommandStation.setLocoNetMessagesFlag(true); 170 z21CommandStation.setLocoNetLocomotiveMessagesFlag(true); 171 z21CommandStation.setLocoNetTurnoutMessagesFlag(true); 172 173 // and forward the flags to the command station 174 _tc.sendz21Message(Z21Message.getLanSetBroadcastFlagsRequestMessage( 175 z21CommandStation.getZ21BroadcastFlags()),null); 176 177 // add an LocoNet Tunnel 178 _loconettunnel = (Z21LocoNetTunnel) classObjectMap.computeIfAbsent(Z21LocoNetTunnel.class, (Class<?> c) -> new Z21LocoNetTunnel(this)); 179 180 // add an XpressNet Tunnel 181 _xnettunnel = (Z21XPressNetTunnel) classObjectMap.computeIfAbsent(Z21XPressNetTunnel.class, (Class<?> c) -> new Z21XPressNetTunnel(this)); 182 183 // set up the Reporter Manager 184 jmri.InstanceManager.setReporterManager(getReporterManager()); 185 186 // set up the SensorManager 187 jmri.InstanceManager.setSensorManager(getSensorManager()); 188 189 // but make sure the LocoNet memo is set (for one feedback message). 190 XNetProgrammerManager xpm = _xnettunnel.getStreamPortController().getSystemConnectionMemo().getProgrammerManager(); 191 if ( xpm instanceof Z21XNetProgrammerManager) { 192 ((Z21XNetProgrammerManager) xpm).setLocoNetMemo(_loconettunnel.getStreamPortController().getSystemConnectionMemo()); 193 } 194 195 // setup the PredefinedMeters 196 createPredefinedMeters(); 197 198 // setup the HeartBeat 199 getHeartBeat(); 200 201 register(); 202 } 203 204 @Override 205 protected ResourceBundle getActionModelResourceBundle() { 206 return ResourceBundle.getBundle("jmri.jmrix.roco.z21.z21ActionListBundle"); 207 } 208 209 @Override 210 public <B extends NamedBean> Comparator<B> getNamedBeanComparator(Class<B> type) { 211 return new NamedBeanComparator<>(); 212 } 213 214 /** 215 * Provide access to the Command Station for this particular connection. 216 * <p> 217 * NOTE: Command Station defaults to NULL 218 * @return command station, may be null. 219 */ 220 public CommandStation getCommandStation() { 221 return get(CommandStation.class); 222 } 223 224 public void setCommandStation(CommandStation c) { 225 store(c,CommandStation.class); 226 } 227 228 /** 229 * Provide access to the Roco Z21 Command Station for this particular 230 * connection. 231 * <p> 232 * NOTE: Command Station defaults to NULL 233 * @return Roco Z21 Command Station, may be null. 234 */ 235 public RocoZ21CommandStation getRocoZ21CommandStation() { 236 return (RocoZ21CommandStation) classObjectMap.computeIfAbsent(RocoZ21CommandStation.class, (Class<?> c) -> new RocoZ21CommandStation()); 237 } 238 239 public void setRocoZ21CommandStation(RocoZ21CommandStation c) { 240 store(c,RocoZ21CommandStation.class); 241 } 242 243 protected Z21PredefinedMeters predefinedMeters; 244 245 /** 246 * Provide access to the Roco Z21 MultiMeter for this particular 247 * connection. 248 * <p> 249 * NOTE: PredefinedMeters defaults to NULL 250 * @return PredefinedMeters, creates new if null. 251 */ 252 public Z21PredefinedMeters createPredefinedMeters() { 253 if (getDisabled()) { 254 return null; 255 } 256 if (predefinedMeters == null) { 257 InstanceManager.setMeterManager(new jmri.managers.AbstractMeterManager(this)); 258 predefinedMeters = new Z21PredefinedMeters(this); 259 } 260 return predefinedMeters; 261 } 262 263 /** 264 * Provide access to the Z21HeartBeat instance for this connection. 265 * <p> 266 * NOTE: HeartBeat defaults to NULL 267 * @return the HeartBeat, creates new if null. 268 */ 269 public Z21HeartBeat getHeartBeat() { 270 if(heartBeat == null){ 271 heartBeat = new Z21HeartBeat(this); 272 } 273 return heartBeat; 274 } 275 276 private Z21HeartBeat heartBeat = null; 277 278 void shutdownTunnel(){ 279 if (_xnettunnel!=null) { 280 _xnettunnel.dispose(); 281 _xnettunnel=null; 282 } 283 if (_loconettunnel!=null) { 284 _loconettunnel.dispose(); 285 _loconettunnel=null; 286 } 287 } 288 289 @Override 290 public void dispose() { 291 if(heartBeat!=null) { 292 heartBeat.dispose(); 293 } 294 shutdownTunnel(); 295 InstanceManager.deregister(this, Z21SystemConnectionMemo.class); 296 if (predefinedMeters != null) { 297 predefinedMeters.dispose(); 298 } 299 super.dispose(); 300 } 301 302 private final static Logger log = LoggerFactory.getLogger(Z21SystemConnectionMemo.class); 303 304}