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