001package jmri.jmrit.logixng.util.parser.functions; 002 003import java.time.Instant; 004import java.util.*; 005 006import jmri.*; 007import jmri.jmrit.logixng.SymbolTable; 008import jmri.jmrit.logixng.util.parser.*; 009 010import org.openide.util.lookup.ServiceProvider; 011 012/** 013 * Implementation of clock functions. 014 * 015 * @author Daniel Bergqvist 2020 016 */ 017@ServiceProvider(service = FunctionFactory.class) 018public class ClockFunctions implements FunctionFactory { 019 020 private final Timebase _fastClock = InstanceManager.getDefault(jmri.Timebase.class); 021 022 @Override 023 public String getModule() { 024 return "Clock"; 025 } 026 027 @Override 028 public Set<Function> getFunctions() { 029 Set<Function> functionClasses = new HashSet<>(); 030 031 addSystemClockFunction(functionClasses); 032 addFastClockFunction(functionClasses); 033 addFastClockRateFunction(functionClasses); 034 addFastClockRunningFunction(functionClasses); 035 036 return functionClasses; 037 } 038 039 @Override 040 public Set<Constant> getConstants() { 041 return new HashSet<>(); 042 } 043 044 @Override 045 public String getConstantDescription() { 046 // This module doesn't define any constants 047 return null; 048 } 049 050 private void addSystemClockFunction(Set<Function> functionClasses) { 051 functionClasses.add(new AbstractFunction(this, "systemClock", Bundle.getMessage("Clock.systemClock_Descr")) { 052 @Override 053 @SuppressWarnings("deprecation") // Date.getMinutes, Date.getHours 054 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 055 throws CalculateException, JmriException { 056 057 Date currentTime = Date.from(Instant.now()); 058 059 if (parameterList.isEmpty()) { // Num minutes since midnight 060 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 061 } else if (parameterList.size() == 1) { 062 Object param = parameterList.get(0).calculate(symbolTable); 063 if (param instanceof String) { 064 switch ((String)param) { 065 case "hour": 066 return currentTime.getHours(); 067 case "min": 068 return currentTime.getMinutes(); 069 case "sec": 070 return currentTime.getSeconds(); 071 case "minOfDay": 072 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 073 case "secOfDay": 074 return ((currentTime.getHours() * 60) + currentTime.getMinutes()) * 60 + currentTime.getSeconds(); 075 default: 076 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 077 } 078 } else { 079 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 080 } 081 } 082 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 083 } 084 }); 085 } 086 087 private void addFastClockFunction(Set<Function> functionClasses) { 088 functionClasses.add(new AbstractFunction(this, "fastClock", Bundle.getMessage("Clock.fastClock_Descr")) { 089 @Override 090 @SuppressWarnings("deprecation") // Date.getMinutes, Date.getHours 091 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 092 throws JmriException { 093 094 Date currentTime = _fastClock.getTime(); 095 096 if (parameterList.isEmpty()) { // Num minutes since midnight 097 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 098 } else if (parameterList.size() == 1) { 099 Object param = parameterList.get(0).calculate(symbolTable); 100 if (param instanceof String) { 101 switch ((String)param) { 102 case "hour": 103 return currentTime.getHours(); 104 case "min": 105 return currentTime.getMinutes(); 106 case "minOfDay": 107 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 108 default: 109 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 110 } 111 } else { 112 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 113 } 114 } 115 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 116 } 117 }); 118 } 119 120 private void addFastClockRateFunction(Set<Function> functionClasses) { 121 functionClasses.add(new AbstractFunction(this, "fastClockRate", Bundle.getMessage("Clock.fastClockRate_Descr")) { 122 @Override 123 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 124 throws JmriException { 125 126 double rate = _fastClock.userGetRate(); 127 128 if (parameterList.isEmpty()) return rate; 129 130 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 131 } 132 }); 133 } 134 135 private void addFastClockRunningFunction(Set<Function> functionClasses) { 136 functionClasses.add(new AbstractFunction(this, "isFastClockRunning", Bundle.getMessage("Clock.isFastClockRunning_Descr")) { 137 @Override 138 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 139 throws JmriException { 140 141 boolean rate = _fastClock.getRun(); 142 143 if (parameterList.isEmpty()) return rate; 144 145 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 146 } 147 }); 148 } 149 150}