001package jmri.jmrit.logixng.actions; 002 003import java.util.Locale; 004import java.util.Map; 005 006import jmri.InstanceManager; 007import jmri.JmriException; 008import jmri.jmrit.logixng.*; 009 010/** 011 * Executes an action when the expression is True. 012 * 013 * @author Daniel Bergqvist Copyright 2018 014 */ 015public class For extends AbstractDigitalAction 016 implements FemaleSocketListener { 017 018 private String _initActionSocketSystemName; 019 private String _whileExpressionSocketSystemName; 020 private String _afterEachActionSocketSystemName; 021 private String _doActionSocketSystemName; 022 private final FemaleDigitalActionSocket _initActionSocket; 023 private final FemaleDigitalExpressionSocket _whileExpressionSocket; 024 private final FemaleDigitalActionSocket _afterEachActionSocket; 025 private final FemaleDigitalActionSocket _doActionSocket; 026 027 public For(String sys, String user) { 028 super(sys, user); 029 _initActionSocket = InstanceManager.getDefault(DigitalActionManager.class) 030 .createFemaleSocket(this, this, Bundle.getMessage("For_SocketName_Init")); 031 _whileExpressionSocket = InstanceManager.getDefault(DigitalExpressionManager.class) 032 .createFemaleSocket(this, this, Bundle.getMessage("For_SocketName_While")); 033 _afterEachActionSocket = InstanceManager.getDefault(DigitalActionManager.class) 034 .createFemaleSocket(this, this, Bundle.getMessage("For_SocketName_AfterEach")); 035 _doActionSocket = InstanceManager.getDefault(DigitalActionManager.class) 036 .createFemaleSocket(this, this, Bundle.getMessage("For_SocketName_Do")); 037 } 038 039 @Override 040 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException { 041 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 042 String sysName = systemNames.get(getSystemName()); 043 String userName = userNames.get(getSystemName()); 044 if (sysName == null) sysName = manager.getAutoSystemName(); 045 For copy = new For(sysName, userName); 046 copy.setComment(getComment()); 047 return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames); 048 } 049 050 /** {@inheritDoc} */ 051 @Override 052 public Category getCategory() { 053 return Category.FLOW_CONTROL; 054 } 055 056 /** {@inheritDoc} */ 057 @Override 058 public void execute() throws JmriException { 059 _initActionSocket.execute(); 060 while (_whileExpressionSocket.evaluate()) { 061 try { 062 _doActionSocket.execute(); 063 } catch (BreakException e) { 064 break; 065 } catch (ContinueException e) { 066 // Do nothing, just catch it. 067 } 068 _afterEachActionSocket.execute(); 069 } 070 } 071 072 @Override 073 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 074 switch (index) { 075 case 0: 076 return _initActionSocket; 077 078 case 1: 079 return _whileExpressionSocket; 080 081 case 2: 082 return _afterEachActionSocket; 083 084 case 3: 085 return _doActionSocket; 086 087 default: 088 throw new IllegalArgumentException( 089 String.format("index has invalid value: %d", index)); 090 } 091 } 092 093 @Override 094 public int getChildCount() { 095 return 4; 096 } 097 098 @Override 099 public void connected(FemaleSocket socket) { 100 if (socket == _initActionSocket) { 101 _initActionSocketSystemName = socket.getConnectedSocket().getSystemName(); 102 } else if (socket == _whileExpressionSocket) { 103 _whileExpressionSocketSystemName = socket.getConnectedSocket().getSystemName(); 104 } else if (socket == _afterEachActionSocket) { 105 _afterEachActionSocketSystemName = socket.getConnectedSocket().getSystemName(); 106 } else if (socket == _doActionSocket) { 107 _doActionSocketSystemName = socket.getConnectedSocket().getSystemName(); 108 } else { 109 throw new IllegalArgumentException("unkown socket"); 110 } 111 } 112 113 @Override 114 public void disconnected(FemaleSocket socket) { 115 if (socket == _initActionSocket) { 116 _initActionSocketSystemName = null; 117 } else if (socket == _whileExpressionSocket) { 118 _whileExpressionSocketSystemName = null; 119 } else if (socket == _afterEachActionSocket) { 120 _afterEachActionSocketSystemName = null; 121 } else if (socket == _doActionSocket) { 122 _doActionSocketSystemName = null; 123 } else { 124 throw new IllegalArgumentException("unkown socket"); 125 } 126 } 127 128 @Override 129 public String getShortDescription(Locale locale) { 130 return Bundle.getMessage(locale, "For_Short"); 131 } 132 133 @Override 134 public String getLongDescription(Locale locale) { 135 return Bundle.getMessage(locale, "For_Long", 136 _initActionSocket.getName(), 137 _whileExpressionSocket.getName(), 138 _afterEachActionSocket.getName(), 139 _doActionSocket.getName()); 140 } 141 142 public FemaleDigitalActionSocket getInitActionSocket() { 143 return _initActionSocket; 144 } 145 146 public String getInitActionSocketSystemName() { 147 return _initActionSocketSystemName; 148 } 149 150 public void setInitActionSocketSystemName(String systemName) { 151 _initActionSocketSystemName = systemName; 152 } 153 154 public FemaleDigitalExpressionSocket getWhileExpressionSocket() { 155 return _whileExpressionSocket; 156 } 157 158 public String getWhileExpressionSocketSystemName() { 159 return _whileExpressionSocketSystemName; 160 } 161 162 public void setWhileExpressionSocketSystemName(String systemName) { 163 _whileExpressionSocketSystemName = systemName; 164 } 165 166 public FemaleDigitalActionSocket getAfterEachActionSocket() { 167 return _afterEachActionSocket; 168 } 169 170 public String getAfterEachExpressionSocketSystemName() { 171 return _afterEachActionSocketSystemName; 172 } 173 174 public void setAfterEachActionSocketSystemName(String systemName) { 175 _afterEachActionSocketSystemName = systemName; 176 } 177 178 public FemaleDigitalActionSocket getDoActionSocket() { 179 return _doActionSocket; 180 } 181 182 public String getDoExpressionSocketSystemName() { 183 return _doActionSocketSystemName; 184 } 185 186 public void setDoActionSocketSystemName(String systemName) { 187 _doActionSocketSystemName = systemName; 188 } 189 190 /** {@inheritDoc} */ 191 @Override 192 public void setup() { 193 try { 194 if ( !_initActionSocket.isConnected() 195 || !_initActionSocket.getConnectedSocket().getSystemName() 196 .equals(_initActionSocketSystemName)) { 197 198 String socketSystemName = _initActionSocketSystemName; 199 _initActionSocket.disconnect(); 200 if (socketSystemName != null) { 201 MaleSocket maleSocket = 202 InstanceManager.getDefault(DigitalActionManager.class) 203 .getBySystemName(socketSystemName); 204 _initActionSocket.disconnect(); 205 if (maleSocket != null) { 206 _initActionSocket.connect(maleSocket); 207 maleSocket.setup(); 208 } else { 209 log.error("cannot load digital action {}", socketSystemName); 210 } 211 } 212 } else { 213 _initActionSocket.getConnectedSocket().setup(); 214 } 215 216 if ( !_whileExpressionSocket.isConnected() 217 || !_whileExpressionSocket.getConnectedSocket().getSystemName() 218 .equals(_whileExpressionSocketSystemName)) { 219 220 String socketSystemName = _whileExpressionSocketSystemName; 221 _whileExpressionSocket.disconnect(); 222 if (socketSystemName != null) { 223 MaleSocket maleSocket = 224 InstanceManager.getDefault(DigitalExpressionManager.class) 225 .getBySystemName(socketSystemName); 226 if (maleSocket != null) { 227 _whileExpressionSocket.connect(maleSocket); 228 maleSocket.setup(); 229 } else { 230 log.error("cannot load digital expression {}", socketSystemName); 231 } 232 } 233 } else { 234 _whileExpressionSocket.getConnectedSocket().setup(); 235 } 236 237 if ( !_afterEachActionSocket.isConnected() 238 || !_afterEachActionSocket.getConnectedSocket().getSystemName() 239 .equals(_afterEachActionSocketSystemName)) { 240 241 String socketSystemName = _afterEachActionSocketSystemName; 242 _afterEachActionSocket.disconnect(); 243 if (socketSystemName != null) { 244 MaleSocket maleSocket = 245 InstanceManager.getDefault(DigitalActionManager.class) 246 .getBySystemName(socketSystemName); 247 _afterEachActionSocket.disconnect(); 248 if (maleSocket != null) { 249 _afterEachActionSocket.connect(maleSocket); 250 maleSocket.setup(); 251 } else { 252 log.error("cannot load digital action {}", socketSystemName); 253 } 254 } 255 } else { 256 _afterEachActionSocket.getConnectedSocket().setup(); 257 } 258 259 if ( !_doActionSocket.isConnected() 260 || !_doActionSocket.getConnectedSocket().getSystemName() 261 .equals(_doActionSocketSystemName)) { 262 263 String socketSystemName = _doActionSocketSystemName; 264 _doActionSocket.disconnect(); 265 if (socketSystemName != null) { 266 MaleSocket maleSocket = 267 InstanceManager.getDefault(DigitalActionManager.class) 268 .getBySystemName(socketSystemName); 269 _doActionSocket.disconnect(); 270 if (maleSocket != null) { 271 _doActionSocket.connect(maleSocket); 272 maleSocket.setup(); 273 } else { 274 log.error("cannot load digital action {}", socketSystemName); 275 } 276 } 277 } else { 278 _doActionSocket.getConnectedSocket().setup(); 279 } 280 } catch (SocketAlreadyConnectedException ex) { 281 // This shouldn't happen and is a runtime error if it does. 282 throw new RuntimeException("socket is already connected"); 283 } 284 } 285 286 /** {@inheritDoc} */ 287 @Override 288 public void registerListenersForThisClass() { 289 } 290 291 /** {@inheritDoc} */ 292 @Override 293 public void unregisterListenersForThisClass() { 294 } 295 296 /** {@inheritDoc} */ 297 @Override 298 public void disposeMe() { 299 } 300 301 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(For.class); 302 303}