001package jmri.jmrit.logixng.util.parser.functions; 002 003import java.util.HashSet; 004import java.util.List; 005import java.util.Set; 006 007import jmri.*; 008import jmri.jmrit.logix.OBlockManager; 009import jmri.jmrit.logixng.SymbolTable; 010import jmri.jmrit.logixng.util.parser.*; 011import jmri.util.TypeConversionUtil; 012 013import org.openide.util.lookup.ServiceProvider; 014 015/** 016 * Implementation of layout functions. 017 * 018 * @author Daniel Bergqvist 2021 019 */ 020@ServiceProvider(service = FunctionFactory.class) 021public class LayoutFunctions implements FunctionFactory { 022 023 @Override 024 public String getModule() { 025 return "Layout"; 026 } 027 028 @Override 029 public Set<Function> getFunctions() { 030 Set<Function> functionClasses = new HashSet<>(); 031 032 addTurnoutExistsFunction(functionClasses); 033 addGetTurnoutStateFunction(functionClasses); 034 addSetTurnoutStateFunction(functionClasses); 035 addSensorExistsFunction(functionClasses); 036 addGetSensorStateFunction(functionClasses); 037 addSetSensorStateFunction(functionClasses); 038 addLightExistsFunction(functionClasses); 039 addGetLightStateFunction(functionClasses); 040 addSetLightStateFunction(functionClasses); 041 addSignalHeadExistsFunction(functionClasses); 042 addGetSignalHeadAppearanceFunction(functionClasses); 043 addSetSignalHeadAppearanceFunction(functionClasses); 044 addSignalMastExistsFunction(functionClasses); 045 addGetSignalMastAspectFunction(functionClasses); 046 addSetSignalMastAspectFunction(functionClasses); 047 048 return functionClasses; 049 } 050 051 @Override 052 public Set<Constant> getConstants() { 053 Set<Constant> constantClasses = new HashSet<>(); 054 constantClasses.add(new Constant(getModule(), "Unknown", NamedBean.UNKNOWN)); 055 constantClasses.add(new Constant(getModule(), "Inconsistent", NamedBean.INCONSISTENT)); 056 057 constantClasses.add(new Constant(getModule(), "Off", Light.OFF)); 058 constantClasses.add(new Constant(getModule(), "On", Light.ON)); 059 060 constantClasses.add(new Constant(getModule(), "Inactive", Sensor.INACTIVE)); 061 constantClasses.add(new Constant(getModule(), "Active", Sensor.ACTIVE)); 062 063 constantClasses.add(new Constant(getModule(), "Closed", Turnout.CLOSED)); 064 constantClasses.add(new Constant(getModule(), "Thrown", Turnout.THROWN)); 065 constantClasses.add(new Constant(getModule(), "CabLockout", Turnout.CABLOCKOUT)); 066 constantClasses.add(new Constant(getModule(), "PushButtonLockout", Turnout.PUSHBUTTONLOCKOUT)); 067 constantClasses.add(new Constant(getModule(), "Unlocked", Turnout.UNLOCKED)); 068 constantClasses.add(new Constant(getModule(), "Locked", Turnout.LOCKED)); 069 070 constantClasses.add(new Constant(getModule(), "Dark", SignalHead.DARK)); 071 constantClasses.add(new Constant(getModule(), "Red", SignalHead.RED)); 072 constantClasses.add(new Constant(getModule(), "FlashRed", SignalHead.FLASHRED)); 073 constantClasses.add(new Constant(getModule(), "Yellow", SignalHead.YELLOW)); 074 constantClasses.add(new Constant(getModule(), "FlashYellow", SignalHead.FLASHYELLOW)); 075 constantClasses.add(new Constant(getModule(), "Green", SignalHead.GREEN)); 076 constantClasses.add(new Constant(getModule(), "FlashGreen", SignalHead.FLASHGREEN)); 077 constantClasses.add(new Constant(getModule(), "Lunar", SignalHead.LUNAR)); 078 constantClasses.add(new Constant(getModule(), "FlashLunar", SignalHead.FLASHLUNAR)); 079 constantClasses.add(new Constant(getModule(), "Held", SignalHead.HELD)); 080 081 constantClasses.add(new Constant(getModule(), "sensors", InstanceManager.getNullableDefault(SensorManager.class))); 082 constantClasses.add(new Constant(getModule(), "turnouts", InstanceManager.getNullableDefault(TurnoutManager.class))); 083 constantClasses.add(new Constant(getModule(), "lights", InstanceManager.getNullableDefault(LightManager.class))); 084 constantClasses.add(new Constant(getModule(), "signals", InstanceManager.getNullableDefault(SignalHeadManager.class))); 085 constantClasses.add(new Constant(getModule(), "masts", InstanceManager.getNullableDefault(SignalMastManager.class))); 086 constantClasses.add(new Constant(getModule(), "routes", InstanceManager.getNullableDefault(RouteManager.class))); 087 constantClasses.add(new Constant(getModule(), "blocks", InstanceManager.getNullableDefault(BlockManager.class))); 088 constantClasses.add(new Constant(getModule(), "oblocks", InstanceManager.getNullableDefault(OBlockManager.class))); 089 constantClasses.add(new Constant(getModule(), "reporters", InstanceManager.getNullableDefault(ReporterManager.class))); 090 constantClasses.add(new Constant(getModule(), "memories", InstanceManager.getNullableDefault(MemoryManager.class))); 091 constantClasses.add(new Constant(getModule(), "powermanager", InstanceManager.getNullableDefault(PowerManager.class))); 092 constantClasses.add(new Constant(getModule(), "addressedProgrammers", InstanceManager.getNullableDefault(AddressedProgrammerManager.class))); 093 constantClasses.add(new Constant(getModule(), "globalProgrammers", InstanceManager.getNullableDefault(GlobalProgrammerManager.class))); 094 constantClasses.add(new Constant(getModule(), "dcc", InstanceManager.getNullableDefault(CommandStation.class))); 095 constantClasses.add(new Constant(getModule(), "audio", InstanceManager.getNullableDefault(AudioManager.class))); 096 constantClasses.add(new Constant(getModule(), "shutdown", InstanceManager.getNullableDefault(ShutDownManager.class))); 097 constantClasses.add(new Constant(getModule(), "layoutblocks", InstanceManager.getNullableDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager.class))); 098 constantClasses.add(new Constant(getModule(), "warrants", InstanceManager.getNullableDefault(jmri.jmrit.logix.WarrantManager.class))); 099 constantClasses.add(new Constant(getModule(), "sections", InstanceManager.getNullableDefault(SectionManager.class))); 100 constantClasses.add(new Constant(getModule(), "transits", InstanceManager.getNullableDefault(TransitManager.class))); 101 102 constantClasses.add(new Constant(getModule(), "InstanceManager", InstanceManager.getDefault())); 103 104// constantClasses.add(new Constant(getModule(), "FileUtil", FileUtilSupport.getDefault()); 105 106 return constantClasses; 107 } 108 109 @Override 110 public String getConstantDescription() { 111 return Bundle.getMessage("Layout.ConstantDescriptions"); 112 } 113 114 private void addTurnoutExistsFunction(Set<Function> functionClasses) { 115 functionClasses.add(new AbstractFunction(this, "turnoutExists", Bundle.getMessage("LayoutFunctions.turnoutExists_Descr")) { 116 @Override 117 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 118 throws CalculateException, JmriException { 119 if (parameterList.isEmpty()) { 120 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 121 } 122 123 String name = TypeConversionUtil.convertToString( 124 parameterList.get(0).calculate(symbolTable), false); 125 126 Turnout t = InstanceManager.getDefault(TurnoutManager.class).getNamedBean(name); 127 return t != null; 128 } 129 }); 130 } 131 132 private void addGetTurnoutStateFunction(Set<Function> functionClasses) { 133 functionClasses.add(new AbstractFunction(this, "getTurnoutState", Bundle.getMessage("LayoutFunctions.getTurnoutState_Descr")) { 134 @Override 135 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 136 throws CalculateException, JmriException { 137 if (parameterList.isEmpty()) { 138 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 139 } 140 141 String name = TypeConversionUtil.convertToString( 142 parameterList.get(0).calculate(symbolTable), false); 143 144 Turnout t = InstanceManager.getDefault(TurnoutManager.class).getNamedBean(name); 145 if (t == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_GetTurnoutState_TurnoutNotFound", name)); 146 return t.getKnownState(); 147 } 148 }); 149 } 150 151 private void addSetTurnoutStateFunction(Set<Function> functionClasses) { 152 functionClasses.add(new AbstractFunction(this, "setTurnoutState", Bundle.getMessage("LayoutFunctions.setTurnoutState_Descr")) { 153 @Override 154 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 155 throws CalculateException, JmriException { 156 if (parameterList.isEmpty()) { 157 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 2)); 158 } 159 160 String name = TypeConversionUtil.convertToString( 161 parameterList.get(0).calculate(symbolTable), false); 162 int value = (int) TypeConversionUtil.convertToLong( 163 parameterList.get(1).calculate(symbolTable)); 164 165 Turnout t = InstanceManager.getDefault(TurnoutManager.class).getNamedBean(name); 166 if (t == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_SetTurnoutState_TurnoutNotFound", name)); 167 t.setState(value); 168 return t.getKnownState(); 169 } 170 }); 171 } 172 173 private void addSensorExistsFunction(Set<Function> functionClasses) { 174 functionClasses.add(new AbstractFunction(this, "sensorExists", Bundle.getMessage("LayoutFunctions.sensorExists_Descr")) { 175 @Override 176 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 177 throws CalculateException, JmriException { 178 if (parameterList.isEmpty()) { 179 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 180 } 181 182 String name = TypeConversionUtil.convertToString( 183 parameterList.get(0).calculate(symbolTable), false); 184 185 Sensor s = InstanceManager.getDefault(SensorManager.class).getNamedBean(name); 186 return s != null; 187 } 188 }); 189 } 190 191 private void addGetSensorStateFunction(Set<Function> functionClasses) { 192 functionClasses.add(new AbstractFunction(this, "getSensorState", Bundle.getMessage("LayoutFunctions.getSensorState_Descr")) { 193 @Override 194 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 195 throws CalculateException, JmriException { 196 if (parameterList.isEmpty()) { 197 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 198 } 199 200 String name = TypeConversionUtil.convertToString( 201 parameterList.get(0).calculate(symbolTable), false); 202 203 Sensor s = InstanceManager.getDefault(SensorManager.class).getNamedBean(name); 204 if (s == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_GetSensorState_SensorNotFound", name)); 205 return s.getKnownState(); 206 } 207 }); 208 } 209 210 private void addSetSensorStateFunction(Set<Function> functionClasses) { 211 functionClasses.add(new AbstractFunction(this, "setSensorState", Bundle.getMessage("LayoutFunctions.setSensorState_Descr")) { 212 @Override 213 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 214 throws CalculateException, JmriException { 215 if (parameterList.isEmpty()) { 216 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 2)); 217 } 218 219 String name = TypeConversionUtil.convertToString( 220 parameterList.get(0).calculate(symbolTable), false); 221 int value = (int) TypeConversionUtil.convertToLong( 222 parameterList.get(1).calculate(symbolTable)); 223 224 Sensor s = InstanceManager.getDefault(SensorManager.class).getNamedBean(name); 225 if (s == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_SetSensorState_SensorNotFound", name)); 226 s.setState(value); 227 return s.getKnownState(); 228 } 229 }); 230 } 231 232 private void addLightExistsFunction(Set<Function> functionClasses) { 233 functionClasses.add(new AbstractFunction(this, "lightExists", Bundle.getMessage("LayoutFunctions.lightExists_Descr")) { 234 @Override 235 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 236 throws CalculateException, JmriException { 237 if (parameterList.isEmpty()) { 238 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 239 } 240 241 String name = TypeConversionUtil.convertToString( 242 parameterList.get(0).calculate(symbolTable), false); 243 244 Light l = InstanceManager.getDefault(LightManager.class).getNamedBean(name); 245 return l != null; 246 } 247 }); 248 } 249 250 private void addGetLightStateFunction(Set<Function> functionClasses) { 251 functionClasses.add(new AbstractFunction(this, "getLightState", Bundle.getMessage("LayoutFunctions.getLightState_Descr")) { 252 @Override 253 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 254 throws CalculateException, JmriException { 255 if (parameterList.isEmpty()) { 256 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 257 } 258 259 String name = TypeConversionUtil.convertToString( 260 parameterList.get(0).calculate(symbolTable), false); 261 262 Light l = InstanceManager.getDefault(LightManager.class).getNamedBean(name); 263 if (l == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_GetLightState_LightNotFound", name)); 264 return l.getKnownState(); 265 } 266 }); 267 } 268 269 private void addSetLightStateFunction(Set<Function> functionClasses) { 270 functionClasses.add(new AbstractFunction(this, "setLightState", Bundle.getMessage("LayoutFunctions.setLightState_Descr")) { 271 @Override 272 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 273 throws CalculateException, JmriException { 274 if (parameterList.isEmpty()) { 275 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 2)); 276 } 277 278 String name = TypeConversionUtil.convertToString( 279 parameterList.get(0).calculate(symbolTable), false); 280 int value = (int) TypeConversionUtil.convertToLong( 281 parameterList.get(1).calculate(symbolTable)); 282 283 Light l = InstanceManager.getDefault(LightManager.class).getNamedBean(name); 284 if (l == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_SetLightState_LightNotFound", name)); 285 l.setState(value); 286 return l.getKnownState(); 287 } 288 }); 289 } 290 291 private void addSignalHeadExistsFunction(Set<Function> functionClasses) { 292 functionClasses.add(new AbstractFunction(this, "signalHeadExists", Bundle.getMessage("LayoutFunctions.signalHeadExists_Descr")) { 293 @Override 294 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 295 throws CalculateException, JmriException { 296 if (parameterList.isEmpty()) { 297 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 298 } 299 300 String name = TypeConversionUtil.convertToString( 301 parameterList.get(0).calculate(symbolTable), false); 302 303 SignalHead sh = InstanceManager.getDefault(SignalHeadManager.class).getNamedBean(name); 304 return sh != null; 305 } 306 }); 307 } 308 309 private void addGetSignalHeadAppearanceFunction(Set<Function> functionClasses) { 310 functionClasses.add(new AbstractFunction(this, "getSignalHeadAppearance", Bundle.getMessage("LayoutFunctions.getSignalHeadAppearance_Descr")) { 311 @Override 312 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 313 throws CalculateException, JmriException { 314 if (parameterList.isEmpty()) { 315 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 316 } 317 318 String name = TypeConversionUtil.convertToString( 319 parameterList.get(0).calculate(symbolTable), false); 320 321 SignalHead sh = InstanceManager.getDefault(SignalHeadManager.class).getNamedBean(name); 322 if (sh == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_GetSignalHeadAppearance_SignalHeadNotFound", name)); 323 return sh.getAppearance(); 324 } 325 }); 326 } 327 328 private void addSetSignalHeadAppearanceFunction(Set<Function> functionClasses) { 329 functionClasses.add(new AbstractFunction(this, "setSignalHeadAppearance", Bundle.getMessage("LayoutFunctions.setSignalHeadAppearance_Descr")) { 330 @Override 331 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 332 throws CalculateException, JmriException { 333 if (parameterList.isEmpty()) { 334 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 2)); 335 } 336 337 String name = TypeConversionUtil.convertToString( 338 parameterList.get(0).calculate(symbolTable), false); 339 int aspect = (int) TypeConversionUtil.convertToLong( 340 parameterList.get(1).calculate(symbolTable)); 341 342 SignalHead sh = InstanceManager.getDefault(SignalHeadManager.class).getNamedBean(name); 343 if (sh == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_SetSignalHeadAppearance_SignalHeadNotFound", name)); 344 sh.setAppearance(aspect); 345 return sh.getAppearance(); 346 } 347 }); 348 } 349 350 private void addSignalMastExistsFunction(Set<Function> functionClasses) { 351 functionClasses.add(new AbstractFunction(this, "signalMastExists", Bundle.getMessage("LayoutFunctions.signalMastExists_Descr")) { 352 @Override 353 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 354 throws CalculateException, JmriException { 355 if (parameterList.isEmpty()) { 356 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 357 } 358 359 String name = TypeConversionUtil.convertToString( 360 parameterList.get(0).calculate(symbolTable), false); 361 362 SignalMast sh = InstanceManager.getDefault(SignalMastManager.class).getNamedBean(name); 363 return sh != null; 364 } 365 }); 366 } 367 368 private void addGetSignalMastAspectFunction(Set<Function> functionClasses) { 369 functionClasses.add(new AbstractFunction(this, "getSignalMastAspect", Bundle.getMessage("LayoutFunctions.getSignalMastAspect_Descr")) { 370 @Override 371 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 372 throws CalculateException, JmriException { 373 if (parameterList.isEmpty()) { 374 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 375 } 376 377 String name = TypeConversionUtil.convertToString( 378 parameterList.get(0).calculate(symbolTable), false); 379 380 SignalMast sm = InstanceManager.getDefault(SignalMastManager.class).getNamedBean(name); 381 if (sm == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_GetSignalMastAspect_SignalMastNotFound", name)); 382 return sm.getAspect(); 383 } 384 }); 385 } 386 387 private void addSetSignalMastAspectFunction(Set<Function> functionClasses) { 388 functionClasses.add(new AbstractFunction(this, "setSignalMastAspect", Bundle.getMessage("LayoutFunctions.setSignalMastAspect_Descr")) { 389 @Override 390 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 391 throws CalculateException, JmriException { 392 if (parameterList.isEmpty()) { 393 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 2)); 394 } 395 396 String name = TypeConversionUtil.convertToString( 397 parameterList.get(0).calculate(symbolTable), false); 398 String aspect = TypeConversionUtil.convertToString( 399 parameterList.get(1).calculate(symbolTable), false); 400 401 SignalMast sm = InstanceManager.getDefault(SignalMastManager.class).getNamedBean(name); 402 if (sm == null) throw new CalculateException(Bundle.getMessage("LayoutFunctions_SetSignalMastAspect_SignalMastNotFound", name)); 403 sm.setAspect(aspect); 404 return sm.getAspect(); 405 } 406 }); 407 } 408 409}