All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.thehilikus.jrobocom.timing.MasterClock Maven / Gradle / Ivy

There is a newer version: 1.0.0-beta-02
Show newest version
package com.github.thehilikus.jrobocom.timing;

import java.util.Timer;
import java.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.thehilikus.events.event_manager.api.EventDispatcher;
import com.github.thehilikus.events.event_manager.api.EventPublisher;
import com.github.thehilikus.jrobocom.events.TickEvent;
import com.github.thehilikus.jrobocom.timing.api.Clock;

/**
 * Time keeper
 * 
 * @author hilikus
 * 
 */
public class MasterClock implements Clock, EventPublisher {

    private long cycles;

    private Logger log = LoggerFactory.getLogger(MasterClock.class);

    private int period = 400;

    private Timer timer;

    private Ticker currentTicker;

    private Delayer delayer;

    private EventDispatcher eventDispatcher;

    /**
     * Minimum clock period allowed
     */
    public static final int MIN_PERIOD = 10;

    /**
     * Main constructor
     * 
     * @param pDelayer thread blocker object
     */
    public MasterClock(Delayer pDelayer) {
	delayer = pDelayer;
    }

    @Override
    public void start(boolean reset) {
	log.debug("Starting Master Clock. Period = {}, Reset = {}", period, reset);
	if (reset) {
	    cycles = 0;
	}
	currentTicker = new Ticker();
	timer = new Timer("Master Clock Timer");
	timer.scheduleAtFixedRate(currentTicker, period, period);
    }

    /* (non-Javadoc)
     * @see com.github.thehilikus.jrobocom.timing.Clock#step()
     */
    @Override
    public void step() {
	delayer.tick();
    }

    /* (non-Javadoc)
     * @see com.github.thehilikus.jrobocom.timing.Clock#stop()
     */
    @Override
    public void stop() {
	log.debug("Stopping Master Clock");
	if (currentTicker != null) {
	    currentTicker.cancel();
	    currentTicker = null;
	}
	if (timer != null) {
	    timer.cancel();
	    timer = null;
	}

    }

    private class Ticker extends TimerTask {

	@Override
	public void run() {
	    cycles++;
	    log.trace("Tick {}", cycles);

	    delayer.tick();

	    eventDispatcher.fireEvent(new TickEvent(MasterClock.this, cycles));
	}

    }

    @Override
    public long getCycles() {
	return cycles;
    }

    /*
     * If the value is too small, it will be overwritten by {@link #MIN_PERIOD}
     * (non-Javadoc)
     * @see com.github.thehilikus.jrobocom.timing.Clock#setPeriod(int)
     */
    @Override
    public void setPeriod(int pPeriod) {
	if (pPeriod < 0) {
	    throw new IllegalArgumentException("Period cannot be negative");
	}
	int actual = Math.max(pPeriod, MIN_PERIOD);
	log.debug("Changing clock period to {}", actual);
	period = actual;

	if (isRunning()) {
	    stop();
	    start(false);
	}
    }

    @Override
    public int getPeriod() {
	return period;
    }

    @Override
    public boolean isRunning() {
	return currentTicker != null;
    }

    /* (non-Javadoc)
     * @see com.github.thehilikus.jrobocom.timing.Clock#start()
     */
    @Override
    public void start() {
	start(true);

    }

    /* (non-Javadoc)
     * @see com.github.thehilikus.jrobocom.timing.Clock#clean()
     */
    @Override
    public void clean() {
	if (isRunning()) {
	    stop();
	}

    }

    @Override
    public void setEventDispatcher(EventDispatcher dispatcher) {
	eventDispatcher = dispatcher;

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy