/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JAME is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.core.util; import java.util.concurrent.ThreadFactory; /** * @author andrea */ public abstract class Refresher { public static final int DEFAULT_PAUSE_TIME = 50; private final Object lock = new Object(); private final ThreadFactory factory; private volatile Thread thread; private volatile boolean running; private volatile boolean refresh; private long idleTime = 0; private long startTime = 0; private long totalTime = 0; private long sleepTime = 0; private long pauseTime = DEFAULT_PAUSE_TIME; /** * @param factory */ public Refresher(ThreadFactory factory) { this.factory = factory; } /** * @return */ public long getPauseTime() { return pauseTime; } /** * @param pauseTime */ public void setPauseTime(long pauseTime) { this.pauseTime = pauseTime; } /** * */ public void refresh() { synchronized (lock) { refresh = true; lock.notify(); } } /** * */ public void start() { if (thread == null) { thread = factory.newThread(new RefresherTask()); running = true; thread.start(); } } /** * */ public void stop() { running = false; if (thread != null) { thread.interrupt(); try { thread.join(); } catch (final InterruptedException e) { } thread = null; } } /** * */ protected abstract void prepare(); /** * */ protected abstract void process(); /** * @throws InterruptedException */ protected abstract void acquire() throws InterruptedException; /** * */ protected abstract void release(); /** * @return */ protected abstract boolean needsRefresh(); private class RefresherTask implements Runnable { /** * @see java.lang.Runnable#run() */ public void run() { try { while (running) { startTime = System.currentTimeMillis(); acquire(); refresh |= needsRefresh(); prepare(); process(); release(); synchronized (lock) { if (refresh) { idleTime = System.currentTimeMillis(); } if (System.currentTimeMillis() - idleTime > 1000) { if (!refresh) { lock.wait(); } idleTime = System.currentTimeMillis(); } refresh = false; } totalTime = System.currentTimeMillis() - startTime; sleepTime = pauseTime - totalTime; if (!running) { break; } if (sleepTime > 10) { Thread.sleep(sleepTime); } else { Thread.sleep(10); } } } catch (final InterruptedException e) { Thread.currentThread().interrupt(); } catch (final Exception e) { e.printStackTrace(); } } } }