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

Add high-frequency touch events to iOS GameView #8092

Merged
merged 41 commits into from Dec 18, 2023

Conversation

Mindfulplays
Copy link
Contributor

@Mindfulplays Mindfulplays commented Nov 15, 2023

Fine-grained/high-frequency touch events are available in certain platforms upon request. On iOS, coalesced touch events can be obtained from the GetCoalescedTouch via the passed-in event.

This PR proposes a side-channel OnCoalescedTouchEvent that can be used in lieu or in addition to OnTouchEvent without any performance penalty. I have tested with and without the coalesced touch event including Apple Pencil which produces events > 60 events per second.

Also fixed minor typos here and there (going forward, I will create smaller commit PRs to avoid polluting).

tomspilman and others added 26 commits August 10, 2020 07:39
In other `Platform` classes (such as `SDLGamePlatform` and `AndroidGamePlatform`, `Threading.Run()` is called during `Tick()` or `RunLoop()` (inconsistently, it may be called before or after `Game.Tick()` unfortunately).

Fixing this for `iOSGamePlatform`. `WinForms` and perhaps other platforms (Switch?) may suffer from the same issue.

Note that texture loading from background thread is discouraged however a lot of computationally intensive operations (reading/decoding the image file streams, allocating CPU buffers) could be done in the background thread and hence is a good practice to move such work alone into the bgthread until we request the actual texture from the main thread.
@Mindfulplays
Copy link
Contributor Author

@harry-cpp @mrhelmut Could you please help review? thank you!

@stromkos
Copy link
Contributor

On the PR itself, there are several regression issues that need to be addressed.

Please collapse the commits.

There are thread timing issues that need to be formally addressed since the entire TouchCollection becomes asynchronous.

Rather than passing an event through the framework for this case, set a listener, hook with callback delagate, for the event and call the handler(a static function elsewhere) in Program.cs or Activity.cs.

That was how I handled the delay issue on Android and Windows.

What are the associated costs:

https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_touches_in_your_view/getting_high-fidelity_input_with_coalesced_touches

Important

Coalesced touches are intended for apps that need the extra precision and can handle the associated costs. Processing coalesced touches means gathering additional data and applying it to your content. If you don’t need the extra precision, continue using the set of touch objects that UIKit passes to the methods of your views or gesture recognizers.

@Mindfulplays
Copy link
Contributor Author

On the PR itself, there are several regression issues that need to be addressed.

Please collapse the commits.

There are thread timing issues that need to be formally addressed since the entire TouchCollection becomes asynchronous.

Rather than passing an event through the framework for this case, set a listener, hook with callback delagate, for the event and call the handler(a static function elsewhere) in Program.cs or Activity.cs.

That was how I handled the delay issue on Android and Windows.

What are the associated costs:

https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_touches_in_your_view/getting_high-fidelity_input_with_coalesced_touches

Important
Coalesced touches are intended for apps that need the extra precision and can handle the associated costs. Processing coalesced touches means gathering additional data and applying it to your content. If you don’t need the extra precision, continue using the set of touch objects that UIKit passes to the methods of your views or gesture recognizers.

Could you add what the regressions are to the PR comments? Not seeing it...

The coalesced events (+processing) is optional (existing apps can choose to subscribe by adding OnCoalescedTouchEvent handler). No extra work is done unless the caller asks for it.

I am not aware of any thread timing issues as the evt holds on to the TouchCollection in memory. There is no round-trip back to the OS or any other blocking main-thread activity. I verified by both stepping through the framework code and the provided iOS documentation.

In case I am missing something, please clarify / provide specific examples.

@Mindfulplays
Copy link
Contributor Author

@harry-cpp @mrhelmut could you please take a look? Thanks!

@Mindfulplays Mindfulplays changed the title Add coalesced touch events to iOS GameView Add high-frequency touch events to iOS GameView Dec 12, 2023
@@ -1,7 +1,7 @@
#region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright � 2009-2010 The MonoGame Team
// MonoGame - Copyright � 2009-2010 The MonoGame Team
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happened here @Mindfulplays ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codepage issues (apparently, VS Code says UTF-8!), just made it (C) :) note that GH diff shows/has codepage issues in the 'before' too for this file and the other ones, so fixed both.

@tomspilman
Copy link
Member

Hey @Mindfulplays

There are some changes to readme.md files in this PR. Is that in other PR somewhere? Are we waiting for that to be merged?

@Mindfulplays
Copy link
Contributor Author

Hey @Mindfulplays

There are some changes to readme.md files in this PR. Is that in other PR somewhere? Are we waiting for that to be merged?

Apologies, non-familiarity with gh workflows, accidental, removed.

@Mindfulplays
Copy link
Contributor Author

Please take a look, I resolved your comments.

@tomspilman
Copy link
Member

Thanks @Mindfulplays

@tomspilman tomspilman merged commit 5fc1d04 into MonoGame:develop Dec 18, 2023
4 checks passed
@SimonDarksideJ
Copy link
Contributor

I take it @Mindfulplays there is not an Android equivalent path for Android? (as this PR only focuses on iOS)

@Mindfulplays
Copy link
Contributor Author

There is: we can get History of touch events in Android. I will send a separate patch for that.

Similarly we have DirectManipulation in Windows but that might be a moot point as I am not sure if it's useful in the context of Windows tablets as a market compared to mobile. (Thoughts?)

@Mindfulplays
Copy link
Contributor Author

Also am not sure if there is such a thing on Consoles (may be Switch or Steam Deck?), but I don't have access to Consoles SDKs so currently wouldn't be able to dabble in it.

@SimonDarksideJ
Copy link
Contributor

If it is available on Android, then it would make sense @Mindfulplays to have parity there.
As for Windows touch, tbh, I'm not sure we need to bother unless it is easy to implement as it is not a touch-first platform like iOS / Android.

As for consoles, only Switch really would be compatible (possibly steam deck) but again, they are not touch-first devices, so I do not think we need to worry about those.

@tomspilman
Copy link
Member

This is one of those features where it may only be available on a couple of platforms.

We should come up with a way to document what platforms these features work on.

Is there some sort of reference document tag we can use for this?

If not maybe some sort of common language in reference docs like:

This feature is available on iOS, Android.

We would just need to be sure to keep this up to date.

@Mindfulplays
Copy link
Contributor Author

Added Android support + doc in #8109

Mindfulplays added a commit to Mindfulplays/MonoGame that referenced this pull request Dec 28, 2023
* Fix iOS GamePlatform to run pending background tasks MonoGame#7520

In other `Platform` classes (such as `SDLGamePlatform` and `AndroidGamePlatform`, `Threading.Run()` is called during `Tick()` or `RunLoop()` (inconsistently, it may be called before or after `Game.Tick()` unfortunately).

Fixing this for `iOSGamePlatform`. `WinForms` and perhaps other platforms (Switch?) may suffer from the same issue.

Note that texture loading from background thread is discouraged however a lot of computationally intensive operations (reading/decoding the image file streams, allocating CPU buffers) could be done in the background thread and hence is a good practice to move such work alone into the bgthread until we request the actual texture from the main thread.

* Update docs for sync/test code

* Fix typo in comment

* Add coalesced touch events to iOS GameView

* Add coalesced touch API to TouchPanel*

* Fix UTF-8 copyright mistake

* Ensure we process coalesced touches only if the client asked for it

* Avoid using C#5.0+ features (expression-bodied properties)

* Suggested changes

* Remove Coalesced API (new) and update existing touch event with a flag for `isHighFrequency`.
 - Also consistently use `high-frequency` instead of `coalesced` when referring to this new behavior.

* Remove `out int` C# 7.0 / use C# 5.0 feature instead

* Update based on @harry-cpp comments

* Rename to `origin` instead of `upstream`

* Remove git stuff

* Address PR comments

* Change (c) UTF-8 due to codepage issues, my bad.

---------

Co-authored-by: Tom Spilman <tom@sickheadgames.com>
Co-authored-by: Thao D <thao.mindfulplay@gmail.com>
Co-authored-by: Simon (Darkside) Jackson <darkside@zenithmoon.com>
Co-authored-by: mindfulplay.build <mindfulplay@appu.app>
itsBuggingMe pushed a commit to itsBuggingMe/MonoGame that referenced this pull request May 12, 2024
* Fix iOS GamePlatform to run pending background tasks MonoGame#7520

In other `Platform` classes (such as `SDLGamePlatform` and `AndroidGamePlatform`, `Threading.Run()` is called during `Tick()` or `RunLoop()` (inconsistently, it may be called before or after `Game.Tick()` unfortunately).

Fixing this for `iOSGamePlatform`. `WinForms` and perhaps other platforms (Switch?) may suffer from the same issue.

Note that texture loading from background thread is discouraged however a lot of computationally intensive operations (reading/decoding the image file streams, allocating CPU buffers) could be done in the background thread and hence is a good practice to move such work alone into the bgthread until we request the actual texture from the main thread.

* Update docs for sync/test code

* Fix typo in comment

* Add coalesced touch events to iOS GameView

* Add coalesced touch API to TouchPanel*

* Fix UTF-8 copyright mistake

* Ensure we process coalesced touches only if the client asked for it

* Avoid using C#5.0+ features (expression-bodied properties)

* Suggested changes

* Remove Coalesced API (new) and update existing touch event with a flag for `isHighFrequency`.
 - Also consistently use `high-frequency` instead of `coalesced` when referring to this new behavior.

* Remove `out int` C# 7.0 / use C# 5.0 feature instead

* Update based on @harry-cpp comments

* Rename to `origin` instead of `upstream`

* Remove git stuff

* Address PR comments

* Change (c) UTF-8 due to codepage issues, my bad.

---------

Co-authored-by: Tom Spilman <tom@sickheadgames.com>
Co-authored-by: Thao D <thao.mindfulplay@gmail.com>
Co-authored-by: Simon (Darkside) Jackson <darkside@zenithmoon.com>
Co-authored-by: mindfulplay.build <mindfulplay@appu.app>
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.

None yet

4 participants