leezer3 / OpenBVE

OpenBVE- A free train simulator
http://www.openbve-project.net
281 stars 51 forks source link

Touch Control resets RefreshRate in unrelated animated objects #926

Open Kenny-Hui opened 1 year ago

Kenny-Hui commented 1 year ago

Description

When clicking a touch control in a 3D cab via mouse, it seems all animated object with RefreshRate will have their timer reset. This may create oddities on a, for example, fixed interval blinking light using RefreshRate, while the user interacts with other element.

Reproduction

If the issue occurs in multiple routes/ trains, please provide one or two samples. In order to reproduce the issue and debug it, it's helpful to have the following:

Train

repo.zip (Gray cube on the bottom left of the panel is the touch area, in the middle there's a blinking red light using RefreshRate).

Related information

leezer3 commented 1 year ago

Hmm.

So this is being caused by the fact that the touch event forces an animated object update. Looking at the code, anything that forces an update will have this effect (IIRC this is primarily otherwise going to be changes between cab / exterior and jumps): https://github.com/leezer3/OpenBVE/blob/0490186f0082ed6df41f707bcb4cfe165b97259c/source/OpenBveApi/Objects/ObjectTypes/AnimatedWorldObject.cs#L28-L35

The RefreshRate isn't really the best thing to use for a static blinking light, and all it appears to guarantee is the minimum time before the functions are updated. If the time exceeds the maximum, the interval would also be extended, although in practice this isn't likely to happen, as obviously your average frame time is going to be in the milliseconds range at 60+ FPS.

In two minds over whether to change this a bit, probably special-casing low values / some events (may have some side effects I've not immediately thought of with jumping etc.), or to update the documentation to make the existing behaviour clearer.

Kenny-Hui commented 1 year ago

I have noticed some reliability issue with the blinking light in the past but it's minor enough that I never bothered with it, wondering how can I make it blink without RefreshRate?

leezer3 commented 1 year ago

Let me think about it for a day or two, Probably something messy with value + delta, hence why Michelle reccomended RefreshRate for use in this case, but noted that it wasnt guaranteed.

TBQH, unless you're really concerned about it leave it as-is, users will probably never notice.

Kenny-Hui commented 1 year ago

Ended up with StateFunction = if[value > 1, 0, value+(delta/2)/RefreshRate], seems to work reasonably ok for my use case so I'll stick with that for now.