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

javrsim.util.ClockThread Maven / Gradle / Ivy

// Copyright 2018 The JavaAVR Project Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package javrsim.util;

import javrsim.windows.SimulationWindow;

/**
 * The Clock Thread is responsible for producing a consistent "pulse" which is
 * used to update the game state, and refresh the display. Setting the pulse
 * rate too high may cause problems, when the point is reached at which the work
 * done to service a given pulse exceeds the time between pulses.
 *
 * @author David J. Pearce
 *
 */
public class ClockThread extends Thread {
	private final SimulationWindow display;
	private volatile int delayMillis; // delay between ticks in ms
	private volatile int delayNanos; // delay between ticks in ms
	private volatile boolean enabled;

	public ClockThread(int delay, SimulationWindow display) {
		this.delayMillis = delay / 1000000;
		this.delayNanos = delay % 1000000;
		this.display = display;
	}

	/**
	 * Set the delay between clock pulses. This effectively sets the frequency of
	 * the clock.
	 *
	 * @param delay (in nanos)
	 */
	public void setDelay(int delay) {
		this.delayMillis = delay / 1000000;
		this.delayNanos = delay % 1000000;
	}

	public void enable() {
		this.enabled = true;
	}

	public void pause() {
		this.enabled = false;
	}

	@Override
	public void run() {
		while (1 == 1) {
			// Loop forever
			sleep(delayMillis,delayNanos);
			if (enabled) {
				display.clock();
			}
		}
	}

	/**
	 * Sleep for a given number of milliseconds and nanoseconds. Due to the inherent
	 * limitation of schedulers, we have to busy wait for the nanos.
	 *
	 * @param millis
	 * @param nanos
	 */
	private static void sleep(int millis, int nanos) {
		try {
			// Sleep for a give number of milliseconds (where appropriate)
			if(millis > 0) {
				Thread.sleep(millis);
			}
			// Busy wait for a given number of nano seconds.
			long start = System.nanoTime();
			while(System.nanoTime() - start < nanos) {
				;
			}
		} catch (InterruptedException e) {
			// should never happen
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy