Skip to main content

Feature Requests

25 replies [Last post]
chet
Offline
Joined: 2003-08-07
Points: 0

If you have requests for the Timing Framework, either simple method tweaks or major new functionality you'd like to see, post your ideas. The intention is to keep evolving the library, and other related libraries, and to develop utilities in core Java that help enable much easier GUI animations. I have a lot of thoughts on this already, and some work is ongoing, but I'd like to get more input from what you need for your applications.

Thanks,
Chet.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
chet
Offline
Joined: 2003-08-07
Points: 0

Okay, so I took a hack at it and made something work with (I think) minimal API. This is, after all, a feature that few developers would probably need (although the ones that want it [i]really[/i] want it). Anyway, here's a proposed approach that seems to work:

[pre]
public interface TimingEventListener {
public void timingSourceEvent(TimingSource timingSource);
}

public abstract class TimingSource {
public abstract void start();
public abstract void stop();
public abstract void setResolution(int resolution);
public abstract void setStartDelay(int delay);
public final void addEventListener(TimingEventListener listener) {...}
public final void removeEventListener(TimingEventListener listener) {...}
protected final void timingEvent() {...}
}
[/pre]

And in Animator, we have the single new public method:

[pre]
public void setTimer(TimingSource timer) {...}
[/pre]

The way it works is that you implement your own TimingSource, send it into Animator.setTimer(), then your TimingSource object later calls the protected timingEvent() method, which forwards that event to the Animators listening in. Note that a call to Animator.setTimer() will, behind the scenes, call TimingSource.addEventListener(), which is how TimingSource knows to call Animator later.

Thoughts?

chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

I definitely think the flexibility offered by the timing framework (property changes over time, with envelopes, repeat behavior and the like) could be useful in some server scenarios, when performing time-sensitive measurements, network broadcasting that adapts to environmental properties, sound editing, to name but a few.

Doesn't need to be in 1.0 though.

- Chris

mikaelgrev
Offline
Joined: 2006-09-27
Points: 0

You're making a common mistake. 10ms makes it possible to have 100, 50, 33, 25Hz and so on. What if I want 60Hz or 75Hz, which is a common refresh rate? Sure, you can have 75Hz over time with a 10ms timer, but if you look at the exact points where the events are fired they will be very unevenly distributed, making animation jerky.

Cheers,
Mikael

steevcoco
Offline
Joined: 2004-05-23
Points: 0

See this FAQ on "jsresources.org": check out points 1.5, 1.6, and 1.3:

http://jsresources.org/faq_performance.html#currenttimemillis

chet
Offline
Joined: 2003-08-07
Points: 0

Actually, it's not that simple. On my XP system, I got a resolution of about 16 ms with currentTimeMillis(). On my Vista system, the resolution seems closer to the nanoTime() resolution (1-2 ms). These results can also vary depending on what else is running on the system...

jwenting
Offline
Joined: 2003-12-02
Points: 0

that's the problem with ALL software timers and the reason the Timer APIs don't give any guarantees except that the time between ticks is AT LEAST the time you set (rather than exactly).
They're run as threads and therefore depend on the OS actually giving them a timeslice to run in at something approaching the interval they want.

If you want more precision you'll have to move to a hardware timer.

steevcoco
Offline
Joined: 2004-05-23
Points: 0

Hello.

The native timer resolution will vary with platform. You will likely find better resolution on Linux or Solaris than on Windows typically: though I don't have the actual numbers myself. Some windows system timers bottom out at 10-12 ms resolution.

I don't know the finer details, but this is well known for the Java Sound implementation and other media implementations concerned with reliable timing.

Nano time should yield better resolution on all platforms I believe.

Run this simple program to see: You'll notice that when you sleep "1" ms, the timer will return much later than that: 8ms on this Ubuntu Linux box. And if you up the value, you'll discover that the additional 7ms is not due to the println call: I can up it to sleep 5ms and it still returns every 8.

public class Timing {
public static void main(final String[] args) throws Exception {
while (true) {
Thread.sleep(1);
System.out.println(System.currentTimeMillis());
}
}
}

skelvin
Offline
Joined: 2003-06-11
Points: 0

> I think the question is valid
I don't really think so, but maybe I am missing the point.
10ms allows one hundred callbacks per second, right?
Nobody I know runs a display with a higher refresh rate (and that's because it already exceeds our own eyes' 'refresh rate').
So anything higher would give you the ability to render multiple images per frame, which sounds pretty much useless to me.

jwenting
Offline
Joined: 2003-12-02
Points: 0

there might be a very limited use in highspeed data acquisition software, but that's not stuff you'd probably want to write in Java as it is too hardware specific (and if you need that accurate timing you want to time on individual clockcycles of your DAC rather than any software timer, something Java isn't suited to).

rah003
Offline
Joined: 2004-05-26
Points: 0

> I think the question is valid. One of the worst coding experiences is when you start out using a framework or tool and somewhere along the way discovers that it just doesn't support that last important thing and you have to change framework.

I never meant to imply that such question is not valid. Sorry if it looked that way. It is more that when you choose the framework you should look at what its limitations are upfront and whether they are acceptable for intended purpose of use. If writing high performance game, I would most likely use something else. For UI elements animations, to improve user experience, current resolution seem to be enough (at least in my case so far).

TimingFramework uses under the hood swing.Timer so it has whatever resolution swing.Timer has. AFAIK both util.Timer and swing.Timer use underneath wait(long) and are therefore curentTimeMillis() based in JDK 6.

Also with the nanoTime() there are limitations. I think that on most systems you would not get below 2ms resolution anyway. (Not making a claim to be right whatsoever here, its just a speculation)

chet
Offline
Joined: 2003-08-07
Points: 0

Okay, I just posted v.55, which has support for external timers (high res, non-GUI, whatever). See the ExternalTimer demo for an example of how to use it. Let me know how it works for you...

chet
Offline
Joined: 2003-08-07
Points: 0

gkw: There are no specific plans, but this is one of the reasons that I hid the actual Timer being used inside the framework and didn't percolate it through the API. Currently, the framework uses the Swing Timer, which makes sense for GUI animations since you really want those timing events on the Event Dispatch Thread. But I could see a future framework either using a different timer by default, or allowing callers to supply the timer and sending timing events into the system. Neither of these is precluded by the current API, although neither are implemented either....

i30817
Offline
Joined: 2006-05-02
Points: 0

It would be great, if (somehow :) ) the framework could be integrated with matisse in some simple situations (move component from here to there, create custom code that affects component whenever timer is fired, the possibilities are endless.

chet
Offline
Joined: 2003-08-07
Points: 0

That is one of the possibilities here that I was hoping to enable. Building such a tool on top of the current timing facilities would have been incredibly tedious. Hopefully, the stuff in the timing framework would make this task much more feasible...

raubezia
Offline
Joined: 2007-03-10
Points: 0

Hi,

I've tried your framework and it works fine. But I've got problems to integrate it in my application. In it, you can add serveral timer with diffrend speeds. Think a gameengine with serveral timer for gui and objects. If you enter a special gamestate (like an option menu) I can stop a/some timer, so the objects won't move.
If I want to use your framework, I need your timer to sync with my timer. The simplest way is, that I update your timer with the current elapsed time (of course the timer is based on nanos not on millis, so it won't be a problem). Sure I can modify your code to provide this, but I will lose update compabilities.

what do you think?

Dan

chet
Offline
Joined: 2003-08-07
Points: 0

I would like to add the functionality of either specifying a different Timer to use or sending in your own timing events, but it's not there yet (and probably won't make 1.0). I guess if you need it now, I'd suggested adding the capability, knowing that you might need to modify things later when you merge with a future version of the framework.

raubezia
Offline
Joined: 2007-03-10
Points: 0

ok... changed your code so far. hope you're not changing much in the future ;)

Dan

chet
Offline
Joined: 2003-08-07
Points: 0

So I got a couple of requests for this last week at the Desktop Matters conference. In one case, someone wanted to use a higher-resolution timer than the default one that the framework uses. In another case, someone wanted to use a timer that didn't have anything to do with Swing.

I would like to fix this eventually (not clear if it'll make the v 1.0 release, since I need to nail down that API for the book right about ... last month).

I would be curious for your input, or anyone else's, on an appropriate approach here.

Note that there are three mechanisms which any Timer has to support, to integrate well into the current framework:
- it must be started from Animator
- it must be stopped from Animator
- it probably needs to have a settable resolution (at least a hint on a minimum resolution)
- it must send timing events into Animator

For the first three, the framework could provide a new interface that defines start/stop/setResolution, and allow Animator clients to pass in a new Timer that implemented this interface.

For the last one, Animator probably needs to expose an external method that could be called from another Timer. Currently, Animator has an actionPerformed() method that is called by the Swing timer. This method is not public, because the timer is just an implementation detail under the hood. We could expose actionPerformed and require external timers to call this method. On the other hand, Animator ignores the ActionEvent parameter completely, so it's pretty much overkill for the situation where we basically just need to be called with tick events. So we could expose a simpler no-arg method instead, and require clients to call that method with timing events.

Thoughts?

mikaelgrev
Offline
Joined: 2006-09-27
Points: 0

Chet,

IMHO.

I have little interest in setting my own Timer. Not even sure how one could do that without busy-wait when sleep() and wait() doesn't provide higher than 10ms resolution. Maybe through JNI?

I think the most important part is that you can switch timer behind the scenes if a better one becomes available.

What is even more important is that the [b]default[/b] timer gets better resolution.

If one should be able to set a new Timer how about this:

[code]
public interface AnimationTimer {
void start();
void stop();
void setResolution(long res); // I don't think this is needed actually... It should be in the concrete class.
void addTickListener(ChangeListener l);
void removeTickListener(ChangeListener l);
}
[/code]

Cheers,
Mikael Grev

jmh_
Offline
Joined: 2007-03-14
Points: 0

Hi All!

I predicate this post with the fact that i havent actually used chets timing framework and maybe everyone on this forum already knows what im about to state.....

Anyho, my experience is using hi-res timers extensively on Windows, maybe the following code may be of use. It has bits missing and coded off the top of my head, but feel free to embrace and complete ;-) Of course it will require a JNI binding.

*begin mind barf*

On Windows 2000)+ there are two providers of hi-res timers capable of sustaining 1-2ms precision on most machines, the windows multimedia timers (winmm.dll) and the queue timers (kernel32.dll). The windows multimedia framework has a limitation of only having a max of 16 timers available (more on later windows platforms), after which timers will be silently overwritten (blech!). I suspect that the queue timers actually use a method where the firing period is calculated to be the lowest required by the set of timers and then a count of the firings is used to work out the individual firing rates of each individual timer. At any rate (sic) the queue timers do not suffer from a number of timers limitation.

*end mind barf*

/* A Windows Hi Res basic structure (Not compilable or complete. Sorry!).

JNI bindings left as an exercise to the final implementor
*/
public class WindowsPeriodicTimer implements AnimationTimer {
public int timerId = 0;
public long period = 10;

public WindowsPeriodicTimer() {
//Setup the resolution of the system wide timing to be as precise as possible.

//Important side effects:
// 1) This is system wide! (Some applications will do this already ie Windows Media Player
//and you may already experience high resolution!)
// 2) Thread.sleep , for small sleep increments, becomes (more) accurate (at least for pure windows threads, no idea what Java does on top of this)
// 3) I believe that any calls to retrieving time is now millisecond precise, rather than the 10-15 millisecond default precision. Cant remember if this is strictly true, we ensure millisecond precision by calling WinMM_Dll.timeGetTime() which is always millisecond precise (at least when coupled with the following call)

WinMM_Dll.timeBeginPeriod(1);
}

protected void finalize()
throws Throwable {
//Each call to WinMM_Dll.timeBeginPeriod should be terminated with the following call (making sure that the resolution passed in matches)
WinMM_Dll.timeEndPeriod(1);
}

public void start() {
if (timerId != 0)
stop();
//JMH: JNI Binding will need to return a struct of both the timer Id and return status.
// Plus being a JNI n00b i have no idea how callback functions (timerCallback) are handled
K32_Return retn = Kernel32_Dll.CreateTimerQueueTimer(/*timerId returned in struct*/,
0,
timerCallback,
0,
0,
period,
Kernel32_Dll.WT_EXECUTE_FLAG /*=0x20*/);
if (!rtn.success) {
//Throw an exception ??
}
timerId = rtn.timerId;
}

private void timerCallback() {
//Note: timerCallback is being called on the timer thread
//synchronisation to the EDT needs to be handled somewhere
fireTickListeners();
}

protected void fireTickListeners() {
//Exercise for Reader
}

public void stop() {
if (timerId != 0) {
Kerner32_Dll.DeleteTimerQuereTimer(0, timerId, 0);
timer Id = 0;
}

public void setResolution(long res) {
//Personally i dont think that this is required. My experience is that most modern
//machines are capable of having a 1ms resolution with many timers without
//issue.
}

public void setPeriod(long period) {
//But this method is required, and is probably missing from the interface.
this.period = period;
stop();
start();
}

public void addTickListener(ChangeListener l) {
//Exercise for reader
}

public void removeTickListener(ChangeListener l) {
//Exercise for reader
}

}

}

Added note indicating timerCallback on timer thread

Message was edited by: jmh_

gkw
Offline
Joined: 2003-06-10
Points: 0

I would like to hear what you have planned for the future. Is there any chance that you will move to a higher resolution timer?

rah003
Offline
Joined: 2004-05-26
Points: 0

> I would like to hear what you have planned for the future. Is there any chance that you will move to a higher resolution timer?

Can't speak for future plans, but did you already hit the limits with current implementation?
Considering this library is meant for relatively simple animations of UI elements and the fact that highest achievable resolution varies widely between different systems I can't come up with a use case which would require that.
I used it in few places already and seems to be working just fine for me.

mikaelgrev
Offline
Joined: 2006-09-27
Points: 0

Hello,

I think the question is valid. One of the worst coding experiences is when you start out using a framework or tool and somewhere along the way discovers that it just doesn't support that last important thing and you have to change framework.

If it's not too hard (I don't know the implementation details) I'd suggest that this gets look ed into.

The main thing to fix here though it of course the resolution of the main timer implementation (swing.Timer and util.Timer) . It is now about 10 ms but since there is a nanoTimer it should be possible to in an easy way make the default timer have about 1 ms accuracy.

Cheers,
Mikael Grev

chet
Offline
Joined: 2003-08-07
Points: 0

mikaelgrev: I'd love for the resolution of all of the timers to get better, but they are dependent upon native facilities (at least now) that make this tricky. I was surprised to find, for example, that changing the Swing timer to use System.nanoTime() as its timer had no effect on its resolution. It is gated, instead, by the resolution of the wait() method, which still uses the low resolution timer of the platform.

Anyway, we should look into making the current timers higher-res, but as I said above, it should also be possible (in a future feature) to somehow make the timing framework use a different timer instead.

mikaelgrev
Offline
Joined: 2006-09-27
Points: 0

Good that you've hidden the Timer implementation. That way you can make it better later. :)

Cheers,
Mikael