As I wrote in a previous post Timing Framework have been acting kind of strange lately. The problem is that when animating, say a movement (a simple moving line is enough), for two seconds the application takes much longer time and the result isn’t even close to good looking. A 2 second animation ends up taking 6 seconds and still doesn’t look good. Yes Houston we have a problem!!!
So I’ve been working on this problem for a couple of month and I’ve tried a lot of different things and tried to blame everything from Timing Framework and Java to Windows and the hardware and just when I was about to give up and accept the fact I stumbled apon the solution. And this time it’s really working.
So what’s the problem? It turns out that the problem is related to both Java and the native platform. Timing Framework uses a swing timer and the swing timer uses wait(time) and notify() internally. Unfortenately wait and notify lacks the kind of resolution that we need and to be more precise, on Windows, the resolution is approximately 16 ms. This means that the maximum frame rate that we can get is 1000(ms)/16(ms) = 62 FPS. This is not enough for our application since we use an animation time of 2 seconds and in that time the component that we scroll moves 500-1500 pixels. That means, worst case, that each animation loop will make the component move 1500/(62*2) = 12 pixels. And i’m pretty sure that not even a drunk and half blind person won’t notice the choppy behaviour.
And the solution is….. simple. Write your own TimingSource.
A TimingSource is a class in TimingFramework that handles the timing and all you have to do is write 4 simple methods and add the new TimingSource to your Animation class and your done. I guess I don’t have to remind you NOT to use wait() and notify() in your solution? What should you use? Well I guess there are several ways to do it but we have done it as simple as possible and used Thread.sleep(time) which actually works as expected with an accurate precision. If you’re using Linux or some other operating system then you don’t have this issue and I have no idé why you’ve read this far.
Below is our implementation of TimingSource. Note that this is a first version and no brain power has been consumed creating it. This will of cource change in the future.
public class NanoSource extends TimingSource {
private long resolution;
private boolean stop = false;
@Override
public void start() {
new Thread() {
@Override
public void run() {
while (!stop) {
try {
sleep(resolution);
} catch (Exception e) {
e.printStackTrace();
}
timingEvent();
}
}
}.start();
}
@Override
public void stop() {
stop = true;
}
@Override
public void setResolution(int res) {
resolution = res;
}
@Override
public void setStartDelay(int arg0) {
// add delay
}
}
And then all you have to do to make your Animator use your new TimingSource is:
Animator animator = new Animator(2000, timingTarget);
animator.setTimer(new NanoSource());
animator.start();
and your done.
That’s it for this time
Ps. Yes I know that we’ve promised to opensource/publish our feed reader and yes we are going to do exactly that but we need just a little bit more time. Ds.
Recent comments