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