001package jmri.jmrit.logixng.implementation;
002
003import java.util.*;
004
005import javax.annotation.Nonnull;
006
007import jmri.*;
008import jmri.jmrit.logixng.*;
009
010/**
011 * Every AnalogExpressionBean has an DefaultMaleAnalogExpressionSocket as its parent.
012 * 
013 * @author Daniel Bergqvist Copyright 2018
014 */
015public class DefaultMaleAnalogExpressionSocket extends AbstractMaleSocket implements MaleAnalogExpressionSocket {
016
017//    private final AnalogExpressionBean ((AnalogExpressionBean)getObject());
018    private DebugConfig _debugConfig = null;
019    private boolean _enabled = true;
020
021
022    public DefaultMaleAnalogExpressionSocket(@Nonnull BaseManager<? extends NamedBean> manager, @Nonnull AnalogExpressionBean expression) {
023        super(manager, expression);
024    }
025
026    /** {@inheritDoc} */
027    @Override
028    public boolean getTriggerOnChange() {
029        return ((AnalogExpressionBean)getObject()).getTriggerOnChange();
030    }
031    
032    /** {@inheritDoc} */
033    @Override
034    public void setTriggerOnChange(boolean triggerOnChange) {
035        ((AnalogExpressionBean)getObject()).setTriggerOnChange(triggerOnChange);
036    }
037    
038    /**
039     * Get the value of the AnalogExpressionBean.
040     */
041    private double internalEvaluate() throws JmriException {
042        double result = ((AnalogExpressionBean)getObject()).evaluate();
043        
044        if (Double.isNaN(result)) {
045            throw new IllegalArgumentException("The result is NaN");
046        }
047        if (result == Double.NEGATIVE_INFINITY) {
048            throw new IllegalArgumentException("The result is negative infinity");
049        }
050        if (result == Double.POSITIVE_INFINITY) {
051            throw new IllegalArgumentException("The result is positive infinity");
052        }
053        return result;
054    }
055
056    /** {@inheritDoc} */
057    @Override
058    public double evaluate() throws JmriException {
059        if (! _enabled) {
060            return 0.0;
061        }
062        
063        if ((_debugConfig != null)
064                && ((AnalogExpressionDebugConfig)_debugConfig)._forceResult) {
065            return ((AnalogExpressionDebugConfig)_debugConfig)._result;
066        }
067        
068        ConditionalNG conditionalNG = getConditionalNG();
069        
070        int currentStackPos = conditionalNG.getStack().getCount();
071        
072        double result = 0.0;
073        try {
074            conditionalNG.getSymbolTable().createSymbols(_localVariables);
075            result = internalEvaluate();
076        } catch (JmriException e) {
077            if (e.getErrors() != null) {
078                handleError(this, Bundle.getMessage("ExceptionEvaluateMulti"), e.getErrors(), e, log);
079            } else {
080                handleError(this, Bundle.getMessage("ExceptionEvaluate", e.getLocalizedMessage()), e, log);
081            }
082        } catch (RuntimeException e) {
083            handleError(this, Bundle.getMessage("ExceptionEvaluate", e.getLocalizedMessage()), e, log);
084        }
085        
086        conditionalNG.getStack().setCount(currentStackPos);
087        conditionalNG.getSymbolTable().removeSymbols(_localVariables);
088        
089        return result;
090    }
091    
092    @Override
093    public int getState() {
094        return ((AnalogExpressionBean)getObject()).getState();
095    }
096
097    @Override
098    public String getDisplayName() {
099        return ((AnalogExpressionBean)getObject()).getDisplayName();
100    }
101
102    @Override
103    public void disposeMe() {
104        ((AnalogExpressionBean)getObject()).dispose();
105    }
106
107    /**
108     * Register listeners if this object needs that.
109     */
110    @Override
111    public void registerListenersForThisClass() {
112        ((AnalogExpressionBean)getObject()).registerListeners();
113    }
114    
115    /**
116     * Register listeners if this object needs that.
117     */
118    @Override
119    public void unregisterListenersForThisClass() {
120        ((AnalogExpressionBean)getObject()).unregisterListeners();
121    }
122    
123    @Override
124    public void setState(int s) throws JmriException {
125        ((AnalogExpressionBean)getObject()).setState(s);
126    }
127
128    @Override
129    public String describeState(int state) {
130        return Bundle.getMessage("BeanStateUnknown");
131    }
132
133    @Override
134    public String getComment() {
135        return ((AnalogExpressionBean)getObject()).getComment();
136    }
137
138    @Override
139    public void setComment(String comment) {
140        ((AnalogExpressionBean)getObject()).setComment(comment);
141    }
142
143    @Override
144    public void setProperty(String key, Object value) {
145        ((AnalogExpressionBean)getObject()).setProperty(key, value);
146    }
147
148    @Override
149    public Object getProperty(String key) {
150        return ((AnalogExpressionBean)getObject()).getProperty(key);
151    }
152
153    @Override
154    public void removeProperty(String key) {
155        ((AnalogExpressionBean)getObject()).removeProperty(key);
156    }
157
158    @Override
159    public Set<String> getPropertyKeys() {
160        return ((AnalogExpressionBean)getObject()).getPropertyKeys();
161    }
162
163    @Override
164    public String getBeanType() {
165        return ((AnalogExpressionBean)getObject()).getBeanType();
166    }
167
168    @Override
169    public int compareSystemNameSuffix(String suffix1, String suffix2, NamedBean n2) {
170        return ((AnalogExpressionBean)getObject()).compareSystemNameSuffix(suffix1, suffix2, n2);
171    }
172
173    /** {@inheritDoc} */
174    @Override
175    public void setDebugConfig(DebugConfig config) {
176        _debugConfig = config;
177    }
178
179    /** {@inheritDoc} */
180    @Override
181    public DebugConfig getDebugConfig() {
182        return _debugConfig;
183    }
184
185    /** {@inheritDoc} */
186    @Override
187    public DebugConfig createDebugConfig() {
188        return new AnalogExpressionDebugConfig();
189    }
190
191    /** {@inheritDoc} */
192    @Override
193    public void setEnabled(boolean enable) {
194        _enabled = enable;
195        if (isActive()) {
196            registerListeners();
197        } else {
198            unregisterListeners();
199        }
200    }
201    
202    /** {@inheritDoc} */
203    @Override
204    public void setEnabledFlag(boolean enable) {
205        _enabled = enable;
206    }
207    
208    /** {@inheritDoc} */
209    @Override
210    public boolean isEnabled() {
211        return _enabled;
212    }
213
214
215
216    public static class AnalogExpressionDebugConfig implements MaleSocket.DebugConfig {
217        
218        // If true, the socket is returning the value of "result" instead of
219        // executing the expression.
220        public boolean _forceResult = false;
221        
222        // The result if the result is forced.
223        public double _result = 0.0f;
224        
225        @Override
226        public DebugConfig getCopy() {
227            AnalogExpressionDebugConfig config = new AnalogExpressionDebugConfig();
228            config._forceResult = _forceResult;
229            config._result = _result;
230            return config;
231        }
232        
233    }
234    
235    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultMaleAnalogExpressionSocket.class);
236
237}