001package jmri.jmris;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.io.IOException;
006
007import jmri.InstanceManager;
008import jmri.JmriException;
009import jmri.Timebase;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Abstract interface between the JMRI (fast) clock and a network connection
015 *
016 * @author Paul Bender Copyright (C) 2013
017 * @author Randall Wood Copyright (C) 2014
018 */
019abstract public class AbstractTimeServer {
020
021    private static final Logger log = LoggerFactory.getLogger(AbstractTimeServer.class);
022    protected PropertyChangeListener timeListener = null;
023    protected Timebase timebase = null;
024
025    public AbstractTimeServer(){
026        this(InstanceManager.getDefault(Timebase.class));
027    }
028
029    public AbstractTimeServer(Timebase timebase){
030        this.timebase = timebase;
031    }
032
033    /*
034     * Protocol Specific Abstract Functions
035     */
036    abstract public void sendTime() throws IOException;
037
038    abstract public void sendRate() throws IOException;
039
040    abstract public void sendStatus() throws IOException;
041
042    abstract public void sendErrorStatus() throws IOException;
043
044    abstract public void parseTime(String statusString) throws JmriException, IOException;
045
046    abstract public void parseRate(String statusString) throws JmriException, IOException;
047
048    // wrapper around the clock control start and stop functions.
049    public void startTime() {
050        this.timebase.setRun(true);
051    }
052
053    public void stopTime() {
054        this.timebase.setRun(false);
055    }
056
057    public void dispose() {
058        if (this.timeListener != null) {
059            this.timebase.removeMinuteChangeListener(timeListener);
060            this.timeListener = null;
061        }
062        this.timebase = null;
063    }
064
065    public void listenToTimebase(boolean listen) {
066        if (!listen && timeListener == null) {
067            return; // nothing to do.
068        }
069        if (timeListener == null) {
070            timeListener = evt -> {
071                try {
072                    if (evt.getPropertyName().equals("minutes")) {
073                        sendTime();
074                    } else if (evt.getPropertyName().equals("run")) {
075                        sendStatus();
076                    } else {
077                        sendRate();
078                    }
079                } catch (IOException ex) {
080                    log.warn("Unable to send message to client: {}", ex.getMessage());
081                    timebase.removeMinuteChangeListener(timeListener);
082                }
083            };
084        }
085        if (listen) {
086            timebase.addMinuteChangeListener(timeListener);
087        } else {
088            timebase.removeMinuteChangeListener(timeListener);
089        }
090    }
091}