NPE during map scrolling due to off-EDT Swing calls

We’ve had a bunch of reports of this bug in the past two weeks:

sourceforge.net/tracker/?func=d … tid=594231

At first, it appears to be a Direct3D problem, but on closer inspection
that’s a red herring—the NPE is happening in an internal Java D3D class,
but there are Swing calls in the stack trace and a non-EDT thread at the
top. The problem is that the autoscoller for Map windows is being run from
a non-EDT thread. I have no idea why this suddenly started generating bug
reports now, as it’s been broken this way for years.

I’ve uploaded a build which fixes the problem—autoscrolling calls are
made by a javax.swing.Timer now, which runs on the EDT. What I’d like you
guys to test is whether you find the autoscrolling behavior under the fix
similar enough to the old autoscrolling behavior (or possibly better?) so
that we can include the fix in 3.1.5 as-is.

The build to test is svn5553:

nomic.net/~uckelman/tmp/vassal/

Drag some tokens to the edges and see how it behaves for you.

I don’t find a difference in the autoscrolling behaviour. It seems to be the same.

However, the autoscrolling behaviour was never great. I’d never rely on it. It’s generally unresponsive without some serious prodding.

That being said, SVN5553 is the same – no worse, no better.

  • M.

2009/5/5 uckelman <messages@forums.vassalengine.org (messages@forums.vassalengine.org)>

Post generated using Mail2Forum (mail2forum.com)

Thus spake Michael Kiefte:

Thanks for trying it. They’re slightly different for me (which is why I
posted about this), but each way is approximately as crappy as the other.

Do you know what we’d need to do improve this? The totality of the code
which matters for this is lines 1318-1394 in Map.java. I haven’t committed
my threading fix to the 3.1 branch yet—I’ll do that this evening—but
it doesn’t fundamentally change anything there. Instead of starting a
Thread, my modification has the contents of run() called from a Timer.

It seems to me that there are at least two problems with it:

  1. It takes too long to start.
  2. It’s jerky, and seems to stop for no apparent reason.


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Not really. Threads are not one of my strengths – I like things to be deterministic. Other than that, the code is totally reasonable.

I’m guessing that the JVM is just not waking it up as much as you’d think…

I seem to recall that there are different types of threads in Java and this might not be the right one. I wanted to do some RT processing in Java (gave up on that idea real quick), and looked into this once. However, on googling it, I think I must be mistaken – threads in Java appear to be ridiculously simple.

I can’t help but think that if you wanted to do an animation in Java that this is not the way you’d do it. It clearly isn’t reliable.

  • M.

Post generated using Mail2Forum (mail2forum.com)

I just looked at this again and there’s nothing actually wrong with it per se, it just doesn’t behave as you’d expect it to.

You have to be within 15 pixels of the edge, but you can’t be outside the viewport area. I expected that if you attempted to drag a piece outside the window, it would still scroll, but it doesn’t for reasons that are somewhat obvious.

That’s not really intuitive behaviour. However, the map doesn’t receive a drag action if you move outside the viewport. What is more, if you tried to do it via drag ‘n’ drop, it might interfere with other actions – like actually dragging and dropping.

So there isn’t really anything wrong with the autoscrolling.

That’s easy to change.

The reason appears to be that your dragging to far (or not enough – 15 pixels is not huge).

  • M.

Post generated using Mail2Forum (mail2forum.com)

Thus spake Michael Kiefte:

That’s exactly what’s wrong with it. :slight_smile:

In particular, if autoscrolling didn’t stop when you left the viewport, then
your map would keep scrolling while you’re dragging a piece to another window.

It might be good if we made the hot area for autoscrolling a bit wider than
it is is now.

However, I messed with this a bit, and I think the reason autoscrolling was
jerky has to do with the timer starting and stopping, not the width of the
hot area.

Try svn5576, or merge from the 3.1 branch:

nomic.net/~uckelman/tmp/vassal/

I switched from using a Timer to using an Animator with a start delay. I
also decided to make the motion parabolic instead of linear, since it’s
always bugged me that the scrolling doesn’t accelerate. (I believe this is
the first time I’ve ever used the analysis I learned, since I had to recall
that 2t is the derivative of t^2 in order to calculate the amount to scroll
at each step. All the math I do normally is discrete.)

Does this behave reasonably for you? Is the acceleration enough, or do you
think it should be superlinear?


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

It’s only doing what you ask it to :slight_smile:

That’s obvious when you say it, but for some reason, it’s not really what you expect. I agree that there’s not a lot you could do about it (or would want to do about it).

You left it at 15. It could probably go to 20 as far as I’m concerned.

I’m not that keen on the acceleration. I also find it a bit fast. I think I’d prefer to have the rate inversely proportional to the distance from the edge. That way you could control the rate yourself. If you expand the hot zone out to 20 pixels, it might work out better.

I’d go with 0 acceleration. If the rate was inversely proportional to distance from edge, it might feel like acceleration anyway.

  • m.

Post generated using Mail2Forum (mail2forum.com)

I find 5576 not particularly usable. The scrolling still starts too slowly, and the then speeds up way too fast - there is no time to react before you are way past the spot you want to be. However, I think the principle of a parabolic speed up is good, it just has to start earlier, further from the edge and have a lower maximum speed.

However, the scrolling seems to be smoother than in 3.1.4.

The big problem is that when moving a unit a ‘normal’ pace, you can pass right over the hot zone and leave the viewport before the map even starts scrolling.

The scrolling gesture requires that you move a unit towards the edge of the map, and then stop moving it within a very narrow zone, but there is no instant feedback that have reached this zone. When you are dragging a unit to an edge, you don’t stop moving the unit until you actually see the map start to scroll. Currently, by the time it start scrolling and you get the feedback, and you react, you have already dragged the unit off the edge of the map and the scroll either stops or never starts.

I think the answer is to

a) Have the Hot zone MUCH wider so that scrolling starts further from the edge. I would go at least 30 pixels, perhaps even 50 or 70 (i.e. a normal counter width).

b) Have the scrolling start asap when the counter hits the hot zone to give an ealry visual response that the scroll is starting

c) Have the initial scroll speed much slower, we just want a feedback, plus give the user time to stop if they don’t really want to scroll.

d) Have the parabolic speed up, but with a slower top speed than 5576 so that you have time to react and drop the unit, or move it away from the edge when you get to the place you want to be

e) Perhaps have the cursor change when in the scrolling hotzone

B.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Thus spake “Brent Easton”:

I think you and Michael either have poor reflexes or the scrolling is
happening much faster for you than it is for me. I am having a hard
time imagining how anyone could want it to be slower than how I set it.

I wonder if the size of the hot zone should scale with the map?

Do you think it won’t be irritating to have the map start scrolling when
you drag a piece to another window? That’s going to be much more common
once I have the docking framework completed.

If we had a setting for this, I wonder if anyone would understand what it
is?

Have you tried setting the delay higher? There already is a preference for
that.

That’s a good idea. To what?


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Thus spake “Brent Easton”:

BTW, this is easy to experiment with if you want to. There are two calls
to scrollAtEdge in Map.java. Just change the argument “15” to the border
width you’d like to try.


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Thus spake “Brent Easton”:

Try the following experiment (which I just did) and see how you find the
result:

Set the hot zone width to 50. Open some scenario in the Afrika II module
and zoom to 50%. Then try to place a unit into a hex on the edge of the
viewport. I’ll bet you can’t do it without having the map scroll away from
you.

I think with a wider hot zone we need a longer delay before scrolling
starts. If the map starts scrolling away from people too often, it will
drive them nuts.


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

ehhh depends

For me its alright, could be slower, but its definitely too fast for large
maps once it gets going. The map re-tiling does not keep up so you travel
across ‘whitespace’ not knowing where you are on the map.

This seems to be very user dependent (unknown variable)

What if the scroll edge zone pixel value is stored in preferences and speed
is controlled there also by slider bar for user adjustment?
Give the user the control to suit their own tastes

Post generated using Mail2Forum (mail2forum.com)

At the current speed, the map whizzes past in a blur that is impossible to follow (Fast Quad core, Vista) or stop before you hit the edge. I have halved the speed (delta = t++) and it is far more usable.

30 pixels seems to work well.

I find that if you are moving a unit to another window, you move it a such a speed and with no intent to stop near the edge, that the map barely scrolls if at all.

This is controlled by the scroll edge delay in the preferences. The default is 200ms which I find way to long. I’ve set it to 50ms now and this seems to work nicely with a 30 pixel hot zone and the slower scroll ramp up.

Perhaps have a sort wishy-washy scroll setting - select from ‘Responsive’, ‘Average’, ‘Slow’ and set the other parameters based on this.

  • Delay before scrolling starts
  • Speed at which scrolling increases
  • Top scrolling speed

No, that’s worse. I have the delay set lower to 50ms to make it more responsive

There are the those scroll cursors you get in Acrobat or IE when you initiate manual page scrolling - A circle containing 2 triangles on either side of a dot. The two triangles indicate scroll direction which means you end up with 4 different cursors depending on scroll direction. Really, we would only want one triangle, which means 8 cursors. Sort of like the image attached.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Thus spake “Brent Easton”:

Would you set “Responsive” to have low delay and high acceleration, and
“Slow” to have high delay and low acceleration? If so, then none of those
are what I want, and based on Michael’s description, none of those are what
he wants, either. I want high delay and high acceleration; Michael wants
high initial velocity and deceleration.

I guess we have four parameters here, which should probably be set
independently:

  1. Hot zone width
  2. Scroll delay
  3. Initial velocity
  4. Acceleration

I had no idea when I proposed this that we’d have such divergeant opinions
about how this should work.

Are there any other programs which can scroll during drags? I’d like to
look at them to see what they do.


J.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

This must work differently on different systems, because the parameters you find terrific are completely unusable for me.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

I prefer low delay, low initial speed, medium acceleration!


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Joel,

This seems to behave very differently with different sized maps.

*********** REPLY SEPARATOR ***********

On 7/05/2009 at 12:12 AM Joel Uckelman wrote:

I am trying Afrika II, but with your base code and default 200ms delay and it is pretty much unusable. If I drag a counter to an edge hex, nothing happens for the 200ms, then the map whizzes completely accross to the other side within about 1 second.

Even worse, the scrolling does not stop when you drop the unit - the map keeps on scrolling, leaving your unit way behind. This looks like a bug.

Because there is no visual feedback that you are in scroll hot zone, it makes Vassal seem unresponsive. Then it suddenly explodes into whizzing action.

I would prefer a much short response time so that scrolling starts sooner, but that the initial scroll speed be VERY much slower and ramp up to full speed slower so that you get a chance to stop if you need to.

I have changed now to a 50ms delay time, 30 pixel hot zone and half the ramp up speed (delta = t++) and I find it is fairly usable now.

I think changing the cursor to the ‘scroll’ cursor (perhaps the hand cursor) as soon as you are in the scroll hot zone is essential. This will give you the visual feedback to know you have reached the correct place and something is going to happen.

Perhaps scrolling should start with no delay, but very, very slowly and the speed of the scroll be determined by how close the cursor is to the edge of the viewport?

Reboot

I think we need to start defining the problems we are tring to solve.

What exactly is it about the current scroll system that is a problem?

I think the lack of visual feedback that you are in the hot zone and it’s small size is the main problem, followed closely by the inability to dynamically control the speed and acceleration of the scroll to cope with different needs (e.g scroll a little, scroll medium and slow, scroll a lot).

What are the different scenarios that need to be catered for? These are the ones I can think of:

  1. User wants to scroll to other side of map and knows it, just wants to get there quick,
  2. User wants to scroll somewhere but is not sure where, so they want to scroll slower to see where he is going.
  3. User wants to scroll just a little bit over a few hexes, or say, 10 hexes
  4. User wants to place a piece near an edge and not scroll much, if at all.
  5. User is dragging a piece off map and does not want to scroll at all.

Joel, your current settings make 2 and 3 completely impossible for me. Depending on what you want to do and how well you know the map, you will need different scrolling dynamics.

I have to go eat breakfast…solve it while I’m away will you :slight_smile:


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

Adobe and IE have a scroll mode thatstarts when you click the middle mouse button. The speed of scrolling is then proportional to the distance you move the mouse away from the place where you first clicked.

Gimp allows scrolling when dragging a selection rectangle, but scrolling doesn’t start until you LEAVE the viewport and then the speed of the scroll is proportional to the distance you move the cursor past the edge of the viewport.

In both cases, users have direct control over the speed of the scrolling by moving the cursor while scrolling is progress.

The current VASSAL scroll mechanisms do not have this. You cannot control the speed of the scroll once it starts.

I think the correct dynamic that allows the user to control the speed of the scroll will do away with the need to specify these parameters altogether.

I think this will become irrelevent and we will just be able to choose a suitable size to suit all. My feel is 30 pixels is about right.

I think this should be very short for everyone, about 50-100ms, just to prevent scrolling if you move a piece quickly off the edge of the map. However, the Cursor should change immediately that it enters the Hot zone to give the user feedback that they have enter the Hot zone, and the initial scroll velocity should be VERY slow.

These should be completely under user control by how far they move the cursor into the hot zone towards the map edge.

Initial velocity should be very slow and increase logarithmically as the cursor approaches the viewport edge. The user controls the speed of the scroll by moving the cursor closer to or further away from the viewport edge.

There should also be a maximum rate of acceleration that ramps up over time so that if you very quickly move the cursor right to the edge of the viewport, the scroll speed does not instantaneously go to maximum, but still ramps up to maximum.

B.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)

My original suggestion was that there be no acceleration but that the rate of scrolling be inversely proportional to the distance from the edge. I think that is what you are referring to as well. The closer you are to the edge, the faster the rate is.

  • M.

Post generated using Mail2Forum (mail2forum.com)

Yes, I believe we are in agreement. The ‘velocity’ is then controlled by how close you move the cursor to the edge and the ‘acceleration’ is controlled indirectly by how fast you move the cursor.

The last bit is about an acceleration dampener so that the scrolling does not speed up too quickly of you move the cursor quickly near to the edge.


Messages mailing list
Messages@forums.vassalengine.org
forums.vassalengine.org/mailman/ … engine.org

Post generated using Mail2Forum (mail2forum.com)