/* * Copyright 2009 Hao Nguyen * * 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 gwt.g2d.client.util; import java.util.LinkedList; import com.google.gwt.user.client.Timer; /** * A fixed FPS Timer. The desired FPS may or may not be reached depending on * the complexity of each loop. * * The implementation of this class is based on part of utils3d.js in WebGL's * Hello World demo. * * @author hao1300@gmail.com */ public abstract class FpsTimer { private static final int FRAMERATE_UPDATE_INTERVAL = 500; private FpsTimerImpl timer = new FpsTimerImpl(); private Timer fpsUpdateTimer = new Timer() { @Override public void run() { float tot = 0; for (Float fps : timer.framerates) { tot += fps; } fps = tot / timer.framerates.size(); } }; private float fps; private int desiredFps; public FpsTimer() { this(30); } public FpsTimer(int desiredFps) { this.desiredFps = desiredFps; } /** * Starts the FPS timer. */ public void start() { timer.renderTime = System.currentTimeMillis(); timer.scheduleRepeating(1000 / desiredFps); fpsUpdateTimer.scheduleRepeating(FRAMERATE_UPDATE_INTERVAL); } /** * Cancels the FPS timer. */ public void cancel() { timer.cancel(); fpsUpdateTimer.cancel(); } /** * Sets the desired frame rate per seconds. * * @param desiredFps */ public void setDesiredFps(int desiredFps) { this.desiredFps = desiredFps; } /** * Gets the desired frame rate per seconds. */ public int getDesiredFps() { return desiredFps; } /** * Gets the current FPS, which may be different from the desired fps. */ public float getFps() { return fps; } /** * Overrides this method to perform update per frame. */ public abstract void update(); /** * Helper class for checking the FPS. */ public class FpsTimerImpl extends Timer { private LinkedList<Float> framerates = new LinkedList<Float>(); private long renderTime; @Override public void run() { long newTime = System.currentTimeMillis(); int t = (int) (newTime - this.renderTime); float framerate = 1000f / t; framerates.addLast(framerate); while (framerates.size() > desiredFps) { framerates.removeFirst(); } renderTime = newTime; update(); } } }