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

Required iOS Callbacks #592

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Closed

Required iOS Callbacks #592

SDLBugzilla opened this issue Feb 10, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

Reported in version: HG 2.0
Reported for operating system, platform: iOS (All), iPhone/iPod touch

Comments on the original bug report:

On 2012-05-25 11:06:43 +0000, Brian Barnes wrote:

iOS requires that certain events are dealt with in callbacks. Failure to do this will cause mysterious crashes and not follow the guidelines for proper app behavior. Also, iOS removes time from your app so they must be handled in the callbacks.

These messages are:

willterminate
didreceivememorywarning
resignactive
becomeactive
enterbackground
enterforeground

The patch: http://www.klinksoftware.com/download/SDL_iOS_event_patch.diff

This patch creates a new callback system. Once registered, all events happen in a callback (and can be rerouted in the queue.) This callback mechanism does the same as the filter mechanism, and could be combined.

This patch can also be used for Android with the proper messages added, and the basis for the game center patch.

Note this patch also removes a pump events from the screen flip, this causes these events to come at unexpected times (outside when you call pump.)

On 2012-05-25 12:04:06 +0000, Gabriel Jacobo wrote:

A few notes:

As Brian mentioned on the mailing list, his patch does not use the already existing event filter mechanism.

For alternatives to his solution, see here:
http://forums.libsdl.org/viewtopic.php?t=8133 (includes Game Center functionality as well)
http://forums.libsdl.org/viewtopic.php?t=7733

The original discussion:
http://forums.libsdl.org/viewtopic.php?t=8053

I think we need to do some consolidation of the alternatives, probably based on the solution given here: http://forums.libsdl.org/viewtopic.php?t=8133 which uses SetEventFilter as Sam suggested, though I'm confused by his complete disabling of the UIKit_PumpEvents function.

On 2012-05-25 12:24:53 +0000, Brian Barnes wrote:

(In reply to comment # 1)

I'm not the biggest fan of http://forums.libsdl.org/viewtopic.php?t=8133 for a couple of reasons:

  1. It makes the iOS and every other OS operate differently; it kinds of defeats the purpose of SDL to have one OS be push only and the others be polling. As discussed earlier, going to all pushing is probably the best bet, especially if you can push back to the queue.

  2. It still puts the entire background to foreground cycle in ONE pair of messages. This is bad. This will not work under certain circumstances and does NOT follow the guidelines. There needs to be at least 4 separate messages, and this doesn't count memory low and will terminate.

  3. I don't like the main function not being under my control. This can be a performance bottleneck for games, and it's a pretty big difference in how SDL is integrated as is, right now (see # 1.)

Mine should go through the filters -- this is easy enough to fix and I can update and put up a new diff later on.

On 2012-05-25 21:10:51 +0000, Brian Barnes wrote:

I've updated the patch:

http://www.klinksoftware.com/download/SDL_iOS_event_patch.diff

It now removes the call back and instead uses SDL_SetEventFilter. I retested this and it all works correctly.

[>] Brian

On 2012-05-26 07:02:18 +0000, Sam Lantinga wrote:

Thanks for the patch!

I have a few questions about this.

  1. How is the application expected to handle these events? Can we add documentation for these to README.iOS?
  2. Why did you remove the call to SDL_PumpEvents()?
  3. How does this affect (or not) GameCenter integration?

That last question is for my own personal use. :)

On 2012-05-26 09:03:13 +0000, Brian Barnes wrote:

Sam, this has actually brought up a place where I think the patch might have a problem. I'm not sure what the solution is, we'll have to think about it.

  1. How is the application expected to handle these events? Can we add
    documentation for these to README.iOS?

Sure!

Per iOS docs (and this is what dim3 does):

SDL_IOS_WILLTERMINATE

Terminate the app. Shut everything down before returning from this routine.

** The problem is quitting SQL, this is something you don't do as you are in SDL. I do make this call, and it seems to work, and it might be because the long jump still exist. **

SDL_IOS_DIDRECEIVEMEMORYWARNING

You will get this when you app is paused and iOS wants more memory. Release as much memory as possible.

SDL_IOS_WILLRESIGNACTIVE

Prepare you app to go into the background. Stop loops, etc. This gets called first when the user hits the home button, or gets a call.

SDL_IOS_DIDENTERBACKGROUND

This will get called if the user accepted whatever send your app to the background. If the user got a phone call and canceled it, you'll instead get a SDL_IOS_DIDBECOMEACTIVE and restart your loops. When you get this, you have 5 seconds to save all your state. You app is NOT active at this point.

SDL_IOS_WILLENTERFOREGROUND

This call happens when you app is coming back tot the foreground. Restore all your state here.

SDL_IOS_DIDBECOMEACTIVE

Restart your loops here, your app is ready to start receiving time.

  1. Why did you remove the call to SDL_PumpEvents()?

It's a call to pump events which makes one of these events get back to your application. Therefore, you need to have these events happen at predictable times (i.e., it's hard to shut down a loop when you could get called in any place in it.) The solution is to make sure that you only get a callback when you expect it, i.e., YOU pump events. This is something that will have to go into the docs.

The real reason you need to be able to expect this is some of these calls happen when you are no longer in control of your app (i.e., it has no time.) So you can't let a loop run out, you need to have it frozen at that point.

  1. How does this affect (or not) GameCenter integration?

That's the big question, and I suspect it will still be broken. If you look at the other patch, the big thing about it is it takes away control of the loop from the SDL application and hands it back to the OS. I'm betting this is what makes game center work. This is a bad solution for games that need to be in fine control of their timing, especially things like mine which are pretty complex 3D engines.

What might need to happen is a "game center" mode where you can call into SDL and it goes into it's own loop of this so you can run the game center dialogs, and returns when done. Sadly, that will mean an iOS specific call.

[>] Brian

On 2012-05-26 09:19:40 +0000, Gabriel Jacobo wrote:

(In reply to comment # 5)

  1. Why did you remove the call to SDL_PumpEvents()?

It's a call to pump events which makes one of these events get back to your
application. Therefore, you need to have these events happen at predictable
times (i.e., it's hard to shut down a loop when you could get called in any
place in it.) The solution is to make sure that you only get a callback when
you expect it, i.e., YOU pump events. This is something that will have to go
into the docs.

The real reason you need to be able to expect this is some of these calls
happen when you are no longer in control of your app (i.e., it has no time.)
So you can't let a loop run out, you need to have it frozen at that point.

It seems to me this should be an app specific solution...as the end user, you should be aware that when you call SDL_RenderPresent, that will eventually pump events, which implies potentially getting an iOS callback, and you should structure your loop around that (which basically is being aware of it and interrupting or restarting your loop after calling SDL_RenderPresent), or am I missing a different important factor?

On 2012-05-26 09:36:47 +0000, Brian Barnes wrote:

(In reply to comment # 6)

(In reply to comment # 5)

  1. Why did you remove the call to SDL_PumpEvents()?

It's a call to pump events which makes one of these events get back to your
application. Therefore, you need to have these events happen at predictable
times (i.e., it's hard to shut down a loop when you could get called in any
place in it.) The solution is to make sure that you only get a callback when
you expect it, i.e., YOU pump events. This is something that will have to go
into the docs.

The real reason you need to be able to expect this is some of these calls
happen when you are no longer in control of your app (i.e., it has no time.)
So you can't let a loop run out, you need to have it frozen at that point.

It seems to me this should be an app specific solution...as the end user, you
should be aware that when you call SDL_RenderPresent, that will eventually pump
events, which implies potentially getting an iOS callback, and you should
structure your loop around that (which basically is being aware of it and
interrupting or restarting your loop after calling SDL_RenderPresent), or am I
missing a different important factor?

Sure, but it's errata. It's easier to say "during a call to event code (specifically pump) is when you could get these callbacks" then a list of possible places. The problem with this iOS stuff is getting these events means your code, after the event, will NO LONGER BE RUNNING. When it comes back to the foreground, it'll start out right where it ended, and this can cause all sorts of havoc. I'd rather have it up at the top of a loop (when you'll be pumping and running the math) then at the bottom, where you are in the middle of rendering stuff that might no longer exist by the time you return.

For instance, you should free as much memory as you can. I save all my state and back out to the title page, which is as low memory as possible. I'd have a hard time with that if it restarted right where it was rendering.

I also might not be necessary to call pump events there, I'd have to talk to the person that originally wrote the code. I don't mind there being a flag.

[>] Brian

On 2012-05-26 09:39:56 +0000, Brian Barnes wrote:

(In reply to comment # 6)

(In reply to comment # 5)

  1. Why did you remove the call to SDL_PumpEvents()?

It's a call to pump events which makes one of these events get back to your
application. Therefore, you need to have these events happen at predictable
times (i.e., it's hard to shut down a loop when you could get called in any
place in it.) The solution is to make sure that you only get a callback when
you expect it, i.e., YOU pump events. This is something that will have to go
into the docs.

The real reason you need to be able to expect this is some of these calls
happen when you are no longer in control of your app (i.e., it has no time.)
So you can't let a loop run out, you need to have it frozen at that point.

It seems to me this should be an app specific solution...as the end user, you
should be aware that when you call SDL_RenderPresent, that will eventually pump
events, which implies potentially getting an iOS callback, and you should
structure your loop around that (which basically is being aware of it and
interrupting or restarting your loop after calling SDL_RenderPresent), or am I
missing a different important factor?

One other quick note (sorry about all the email): The other solution that completely takes over the game loop? This is why that one works the way it does, you are never going to be inside your game loop when the message comes. For a solution where the app controls the loop, you need to be sure you'll know where the message will come in.

On 2012-05-26 18:17:53 +0000, Sam Lantinga wrote:

That makes sense

On 2012-07-15 00:48:50 +0000, Vittorio Giovara wrote:

Hi Brian, I apreciate you work on the SDL for iOS events.

I have just a few concerns on this, I hope to express them clearly so that you'll be able to address them.

  • Are iOS-specific events a good thing? What about Android and future mobile ports? I fear that system-specific events become a documentation burden and it also fragments the operating system support. What I would long for is a "mobile" events system, where independently of the platform, the application code can react in the same way to the same events.
  • I'm not sure the callback mechanism is actually required, why isn't it possible to reply in the event loop? After all, iOS events give you some time to respond and an "immediate" action at every system event is not really required.
  • This is more a doubt, implementing a callback mechanis wouldn't break the SDL paradigm? As far as i know, there are no public callbacks besides SetEventFilter.

I hope we will be able to find a way to accomodate everyone proposal as each of them provided some very nice functionality.

On 2012-07-16 21:45:17 +0000, Brian Barnes wrote:

(In reply to comment # 10)

Hi Brian, I apreciate you work on the SDL for iOS events.

I have just a few concerns on this, I hope to express them clearly so that
you'll be able to address them.

  • Are iOS-specific events a good thing? What about Android and future mobile
    ports? I fear that system-specific events become a documentation burden and it
    also fragments the operating system support. What I would long for is a
    "mobile" events system, where independently of the platform, the application
    code can react in the same way to the same events.
  • I'm not sure the callback mechanism is actually required, why isn't it
    possible to reply in the event loop? After all, iOS events give you some time
    to respond and an "immediate" action at every system event is not really
    required.
  • This is more a doubt, implementing a callback mechanis wouldn't break the SDL
    paradigm? As far as i know, there are no public callbacks besides
    SetEventFilter.

I hope we will be able to find a way to accomodate everyone proposal as each of
them provided some very nice functionality.

Vittorio,

We've gone over most of this on the list, but I'll try and hit a couple points. There is another proposal out there that has events mapped to generic events, and we should use that setup.

The callback is definitely required. Apple demands that you do the required tasks within the callback. Once the callback exits, you can lose all time to your application, so a callback is the only way (and the documented way) to handle this. Apple gives you time, but that's within the callback and that's the only guaranteed time you have.

Worse yet, since there's no processor time, you WILL NOT get the callback for memory low, which happens when you application is already frozen. This will cause you application to be killed.

The latest implementation will just use SetEventFilter. You setup the callback, and ignore everything that isn't a specific mobile event. These events will go back on the stack to be picked up n the regular event mechanism.

On 2013-05-18 15:50:29 +0000, Sam Lantinga wrote:

Okay, I generalized the events for Android and checked them in:
http://hg.libsdl.org/SDL/rev/11612d544fcd

Please let me know if there are any issues!

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

No branches or pull requests

1 participant