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