Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create event functions for precise input handling. #1802

Open
wants to merge 2 commits into
base: 8.2.0-Dev
Choose a base branch
from

Conversation

EliteMasterEric
Copy link
Contributor

This feature adds several functions which allow for precise tracking of inputs using timestamps provided by SDL.

SDL provides a timestamp field on each Keyboard key press, and each Gamepad button press and axis change. By recording these timestamps and including them in the event objects, developers can receive a precise record of when the input was pressed.

Using this information requires knowing the current SDL timestamp, thus a lime_sdl_get_ticks() function is provided.

Notes:

  • This feature was developed for, and is actively used by, Friday Night Funkin' in order to precisely track and rate user inputs.
    • This code has been tested and proven, however that was in our develop branch and porting the changes over to 8.2.0-Dev may cause some issues.
  • This creates 5 new events, rather than modifying the existing ones, because adding a new argument is a hard breaking change that prevents applications which use the existing events from building.
  • Timestamps currently use millisecond timings. SDL version 3, which is currently nearing a stable release, provides support for nanosecond timestamps, which should be used as soon as convenient.

@jgranick
Copy link
Member

jgranick commented Jul 9, 2024

I think it would be most flexible to add public var timestamp:Int to lime.app.Event.

We can set it to 0 at first, then it is possible to use it like this:

var event = new Event<String->Void>();
event.timestamp = 1000;
event.dispatch("Hello World");

This would allow the use of timecodes on any/all events coming from SDL.

However I love this idea, and I love how this is serving Friday Night Funkin' 😊

@jgranick
Copy link
Member

jgranick commented Jul 9, 2024

Here's a somewhat more complex idea we could consider:

1.) We add a private var __timestamp:Int = -1 property to lime.app.Event
2.) We add public var timestamp(default, null):Int to lime.app.Event (read-only when dispatched)
3.) We update the dispatch method in lime._internal.macros.EventMacro (https://github.com/openfl/lime/blob/develop/src/lime/_internal/macros/EventMacro.hx#L82)
4.) We use something like the following:

if (this.__timestamp != -1)
{
    this.timestamp = this.__timestamp;
}
else
{
    this.timestamp = lime.system.System.getTimer();
}

5.) Internal methods with Lime would use __timestamp with @:privateAccess before dispatching

EDIT:

Here's a less accurate version which would not have a performance impact:

public var timestamp(get, never):Int;
private var __timestamp:Int = -1;

private function get_timestamp():Int
{
    if (__timestamp != -1) return __timestamp;
    return System.getTimer();
}

@player-03
Copy link
Contributor

Looks like you can get event->common.timestamp for every SDL event. Maybe we should do that?

@EliteMasterEric
Copy link
Contributor Author

Looks like you can get event->common.timestamp for every SDL event. Maybe we should do that?

Yep! That should work great.

I'd also like to standardize these timestamps to use nanoseconds for the unit (at least internally), since as mentioned, upcoming versions of SDL support highly precise timestamps provided by the operating system.

Also I never bothered to check if there was already a hook for GetTicks, the lime_sdl_get_ticks function this PR adds is completely redundant compared with lime.system.System.getTimer().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants