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 addCurrentTimeMillisFunction(functionClasses); 032 addSystemClockFunction(functionClasses); 033 addFastClockFunction(functionClasses); 034 addFastClockRateFunction(functionClasses); 035 addFastClockRunningFunction(functionClasses); 036 037 return functionClasses; 038 } 039 040 @Override 041 public Set<Constant> getConstants() { 042 return new HashSet<>(); 043 } 044 045 @Override 046 public String getConstantDescription() { 047 // This module doesn't define any constants 048 return null; 049 } 050 051 private void addCurrentTimeMillisFunction(Set<Function> functionClasses) { 052 functionClasses.add(new AbstractFunction(this, "currentTimeMillis", Bundle.getMessage("Clock.currentTimeMillis_Descr")) { 053 @Override 054 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 055 throws CalculateException, JmriException { 056 057 if (parameterList.isEmpty()) { 058 return System.currentTimeMillis(); 059 } else { 060 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 061 } 062 } 063 }); 064 } 065 066 private void addSystemClockFunction(Set<Function> functionClasses) { 067 functionClasses.add(new AbstractFunction(this, "systemClock", Bundle.getMessage("Clock.systemClock_Descr")) { 068 @Override 069 @SuppressWarnings("deprecation") // Date.getMinutes, Date.getHours 070 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 071 throws CalculateException, JmriException { 072 073 Date currentTime = Date.from(Instant.now()); 074 075 if (parameterList.isEmpty()) { // Num minutes since midnight 076 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 077 } else if (parameterList.size() == 1) { 078 Object param = parameterList.get(0).calculate(symbolTable); 079 if (param instanceof String) { 080 switch ((String)param) { 081 case "hour": 082 return currentTime.getHours(); 083 case "min": 084 return currentTime.getMinutes(); 085 case "sec": 086 return currentTime.getSeconds(); 087 case "minOfDay": 088 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 089 case "secOfDay": 090 return ((currentTime.getHours() * 60) + currentTime.getMinutes()) * 60 + currentTime.getSeconds(); 091 default: 092 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 093 } 094 } else { 095 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 096 } 097 } 098 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 099 } 100 }); 101 } 102 103 private void addFastClockFunction(Set<Function> functionClasses) { 104 functionClasses.add(new AbstractFunction(this, "fastClock", Bundle.getMessage("Clock.fastClock_Descr")) { 105 @Override 106 @SuppressWarnings("deprecation") // Date.getMinutes, Date.getHours 107 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 108 throws JmriException { 109 110 Date currentTime = _fastClock.getTime(); 111 112 if (parameterList.isEmpty()) { // Num minutes since midnight 113 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 114 } else if (parameterList.size() == 1) { 115 Object param = parameterList.get(0).calculate(symbolTable); 116 if (param instanceof String) { 117 switch ((String)param) { 118 case "hour": 119 return currentTime.getHours(); 120 case "min": 121 return currentTime.getMinutes(); 122 case "minOfDay": 123 return (currentTime.getHours() * 60) + currentTime.getMinutes(); 124 default: 125 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 126 } 127 } else { 128 throw new CalculateException(Bundle.getMessage("IllegalParameter", 1, param, getName())); 129 } 130 } 131 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 132 } 133 }); 134 } 135 136 private void addFastClockRateFunction(Set<Function> functionClasses) { 137 functionClasses.add(new AbstractFunction(this, "fastClockRate", Bundle.getMessage("Clock.fastClockRate_Descr")) { 138 @Override 139 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 140 throws JmriException { 141 142 double rate = _fastClock.userGetRate(); 143 144 if (parameterList.isEmpty()) return rate; 145 146 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 147 } 148 }); 149 } 150 151 private void addFastClockRunningFunction(Set<Function> functionClasses) { 152 functionClasses.add(new AbstractFunction(this, "isFastClockRunning", Bundle.getMessage("Clock.isFastClockRunning_Descr")) { 153 @Override 154 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 155 throws JmriException { 156 157 boolean rate = _fastClock.getRun(); 158 159 if (parameterList.isEmpty()) return rate; 160 161 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName())); 162 } 163 }); 164 } 165 166}