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.AnalogActionManager; 009import jmri.jmrit.logixng.AnalogExpressionManager; 010import jmri.jmrit.logixng.Base; 011import jmri.jmrit.logixng.Category; 012import jmri.jmrit.logixng.DigitalActionManager; 013import jmri.jmrit.logixng.FemaleAnalogActionSocket; 014import jmri.jmrit.logixng.FemaleAnalogExpressionSocket; 015import jmri.jmrit.logixng.FemaleSocket; 016import jmri.jmrit.logixng.FemaleSocketListener; 017import jmri.jmrit.logixng.MaleSocket; 018import jmri.jmrit.logixng.SocketAlreadyConnectedException; 019 020/** 021 * Executes an analog action with the result of an analog expression. 022 * 023 * @author Daniel Bergqvist Copyright 2018 024 */ 025public class DoAnalogAction 026 extends AbstractDigitalAction 027 implements FemaleSocketListener { 028 029 private String _analogExpressionSocketSystemName; 030 private String _analogActionSocketSystemName; 031 private final FemaleAnalogExpressionSocket _analogExpressionSocket; 032 private final FemaleAnalogActionSocket _analogActionSocket; 033 034 public DoAnalogAction(String sys, String user) { 035 super(sys, user); 036 _analogExpressionSocket = InstanceManager.getDefault(AnalogExpressionManager.class) 037 .createFemaleSocket(this, this, "E"); 038 _analogActionSocket = InstanceManager.getDefault(AnalogActionManager.class) 039 .createFemaleSocket(this, this, "A"); 040 } 041 042 @Override 043 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException { 044 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 045 String sysName = systemNames.get(getSystemName()); 046 String userName = userNames.get(getSystemName()); 047 if (sysName == null) sysName = manager.getAutoSystemName(); 048 DoAnalogAction copy = new DoAnalogAction(sysName, userName); 049 copy.setComment(getComment()); 050 return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames); 051 } 052 053 /** {@inheritDoc} */ 054 @Override 055 public Category getCategory() { 056 return Category.COMMON; 057 } 058 059 /** {@inheritDoc} */ 060 @Override 061 public void execute() throws JmriException { 062 double result = _analogExpressionSocket.evaluate(); 063 064 _analogActionSocket.setValue(result); 065 } 066 067 @Override 068 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 069 switch (index) { 070 case 0: 071 return _analogExpressionSocket; 072 073 case 1: 074 return _analogActionSocket; 075 076 default: 077 throw new IllegalArgumentException( 078 String.format("index has invalid value: %d", index)); 079 } 080 } 081 082 @Override 083 public int getChildCount() { 084 return 2; 085 } 086 087 @Override 088 public void connected(FemaleSocket socket) { 089 if (socket == _analogExpressionSocket) { 090 _analogExpressionSocketSystemName = socket.getConnectedSocket().getSystemName(); 091 } else if (socket == _analogActionSocket) { 092 _analogActionSocketSystemName = socket.getConnectedSocket().getSystemName(); 093 } else { 094 throw new IllegalArgumentException("unkown socket"); 095 } 096 } 097 098 @Override 099 public void disconnected(FemaleSocket socket) { 100 if (socket == _analogExpressionSocket) { 101 _analogExpressionSocketSystemName = null; 102 } else if (socket == _analogActionSocket) { 103 _analogActionSocketSystemName = null; 104 } else { 105 throw new IllegalArgumentException("unkown socket"); 106 } 107 } 108 109 @Override 110 public String getShortDescription(Locale locale) { 111 return Bundle.getMessage(locale, "DoAnalogAction_Short"); 112 } 113 114 @Override 115 public String getLongDescription(Locale locale) { 116 return Bundle.getMessage(locale, "DoAnalogAction_Long", _analogExpressionSocket.getName(), _analogActionSocket.getName()); 117 } 118 119 public FemaleAnalogActionSocket getAnalogActionSocket() { 120 return _analogActionSocket; 121 } 122 123 public String getAnalogActionSocketSystemName() { 124 return _analogActionSocketSystemName; 125 } 126 127 public void setAnalogActionSocketSystemName(String systemName) { 128 _analogActionSocketSystemName = systemName; 129 } 130 131 public FemaleAnalogExpressionSocket getAnalogExpressionSocket() { 132 return _analogExpressionSocket; 133 } 134 135 public String getAnalogExpressionSocketSystemName() { 136 return _analogExpressionSocketSystemName; 137 } 138 139 public void setAnalogExpressionSocketSystemName(String systemName) { 140 _analogExpressionSocketSystemName = systemName; 141 } 142 143 /** {@inheritDoc} */ 144 @Override 145 public void setup() { 146 try { 147 if (!_analogExpressionSocket.isConnected() 148 || !_analogExpressionSocket.getConnectedSocket().getSystemName() 149 .equals(_analogExpressionSocketSystemName)) { 150 151 String socketSystemName = _analogExpressionSocketSystemName; 152 153 _analogExpressionSocket.disconnect(); 154 155 if (socketSystemName != null) { 156 MaleSocket maleSocket = 157 InstanceManager.getDefault(AnalogExpressionManager.class) 158 .getBySystemName(socketSystemName); 159 if (maleSocket != null) { 160 _analogExpressionSocket.connect(maleSocket); 161 maleSocket.setup(); 162 } else { 163 log.error("cannot load analog expression {}", socketSystemName); 164 } 165 } 166 } else { 167 _analogExpressionSocket.getConnectedSocket().setup(); 168 } 169 170 if (!_analogActionSocket.isConnected() 171 || !_analogActionSocket.getConnectedSocket().getSystemName() 172 .equals(_analogActionSocketSystemName)) { 173 174 String socketSystemName = _analogActionSocketSystemName; 175 176 _analogActionSocket.disconnect(); 177 178 if (socketSystemName != null) { 179 MaleSocket maleSocket = 180 InstanceManager.getDefault(AnalogActionManager.class) 181 .getBySystemName(socketSystemName); 182 if (maleSocket != null) { 183 _analogActionSocket.connect(maleSocket); 184 maleSocket.setup(); 185 } else { 186 log.error("cannot load analog action {}", socketSystemName); 187 } 188 } 189 } else { 190 _analogActionSocket.getConnectedSocket().setup(); 191 } 192 } catch (SocketAlreadyConnectedException ex) { 193 // This shouldn't happen and is a runtime error if it does. 194 throw new RuntimeException("socket is already connected"); 195 } 196 } 197 198 /** {@inheritDoc} */ 199 @Override 200 public void registerListenersForThisClass() { 201 } 202 203 /** {@inheritDoc} */ 204 @Override 205 public void unregisterListenersForThisClass() { 206 } 207 208 /** {@inheritDoc} */ 209 @Override 210 public void disposeMe() { 211 } 212 213 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DoAnalogAction.class); 214 215}