iOS MultiTasking and CallBacks

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian

Some of what I wrote earlier might not be right, there’s blocking going
on that I don’t understand yet. It looks like I’ll have to fully
implement this to figure out exactly what’s going on.

Stay tuned.

Using SDL “properly” with iOS might be a bit trickier if you have bigger
requirements then just pausing your game.

[>] Brian

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
PiotrOn Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

What kind of game or application would not have state worth saving? The point is to dump the current state to disk in case the application is purged from memory (entirely) and when the user starts it
again they expect to see it exactly where they left off - usually paused but with no other changes.

This functionality exists because apps can be entirely deleted from memory at any time when in the background, a typical example is a very memory hungry highend game which literally can’t survive in a
background state because running anything else is going to cause the low memory warning and then purge it.On 03/20/2012 07:27 PM, sdl at union.pl wrote:

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
Piotr

On Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

Yup, that’s not going to fly. We will also need the background events.
Right now I’m on the cocoa list trying to get some additional
information, but haven’t gotten much about the events.

There’s going to be another needed fix (I think) in SDL itself, which is
SDL calling pump events for you. This has the problem of causing these
callbacks to come at times you can’t predict, which throw everything
into a problem.

If your game is simple, you can just throw up a flag in ResignActive.
If your program is a big 3D game, that is BAD NEWS. Because you’re
going to be the first in a sweep to get more memory, and you are going
to be killed.

What dim3 will do (well, whatever game is written using dim3) is act
like somebody hit quick save + quit in the regular desktop version of
the game, and then act like launch + quick load. In this way, I’ll be a
good citizen, release EVERYTHING possible, and save all my state.

My state is NOT simple. This is a generic 3D engine. I need to save
reams of data :slight_smile:

Also, note one other interesting thing: You can get ResignActive
WITHOUT EnterBackground if you get a phone call (for example) and don’t
pick it up. These case you NEED to separate “pause” from “save state.”

Right now SDL2 works great for iOS except this one instance, but we’ll
figure out exactly what’s needed to get it into shape!

[>] Brian

Forest Hale wrote:> What kind of game or application would not have state worth saving? The point is to dump the current state to disk in case the application is purged from memory (entirely) and when the user starts it

again they expect to see it exactly where they left off - usually paused but with no other changes.

This functionality exists because apps can be entirely deleted from memory at any time when in the background, a typical example is a very memory hungry highend game which literally can’t survive in a
background state because running anything else is going to cause the low memory warning and then purge it.

On 03/20/2012 07:27 PM, sdl at union.pl wrote:

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
Piotr

On Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

A good example would be a game with checkpoints while progressing
through it. In this case there is no need to save the state of the game
between checkpoints, because it was already saved at a checkpoint. When
such game is terminated and ran again the progress starts from the last
saved checkpoint.

regards,
PiotrOn Wed, 21 Mar 2012, Forest Hale wrote:

What kind of game or application would not have state worth saving? The point is to dump the current state to disk in case the application is purged from memory (entirely) and when the user starts it
again they expect to see it exactly where they left off - usually paused but with no other changes.

This functionality exists because apps can be entirely deleted from memory at any time when in the background, a typical example is a very memory hungry highend game which literally can’t survive in a
background state because running anything else is going to cause the low memory warning and then purge it.

On 03/20/2012 07:27 PM, @Piotr_Drapich wrote:

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
Piotr

On Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

FYI, recent version of my callback implementation also handles other
events like didenterbackground. You just need to provide your
callback function to handle these events.
regards,
PiotrOn Wed, 21 Mar 2012, Brian Barnes wrote:

Yup, that’s not going to fly. We will also need the background events.
Right now I’m on the cocoa list trying to get some additional
information, but haven’t gotten much about the events.

There’s going to be another needed fix (I think) in SDL itself, which is
SDL calling pump events for you. This has the problem of causing these
callbacks to come at times you can’t predict, which throw everything
into a problem.

If your game is simple, you can just throw up a flag in ResignActive.
If your program is a big 3D game, that is BAD NEWS. Because you’re
going to be the first in a sweep to get more memory, and you are going
to be killed.

What dim3 will do (well, whatever game is written using dim3) is act
like somebody hit quick save + quit in the regular desktop version of
the game, and then act like launch + quick load. In this way, I’ll be a
good citizen, release EVERYTHING possible, and save all my state.

My state is NOT simple. This is a generic 3D engine. I need to save
reams of data :slight_smile:

Also, note one other interesting thing: You can get ResignActive
WITHOUT EnterBackground if you get a phone call (for example) and don’t
pick it up. These case you NEED to separate “pause” from “save state.”

Right now SDL2 works great for iOS except this one instance, but we’ll
figure out exactly what’s needed to get it into shape!

[>] Brian

Forest Hale wrote:

What kind of game or application would not have state worth saving? The point is to dump the current state to disk in case the application is purged from memory (entirely) and when the user starts it
again they expect to see it exactly where they left off - usually paused but with no other changes.

This functionality exists because apps can be entirely deleted from memory at any time when in the background, a typical example is a very memory hungry highend game which literally can’t survive in a
background state because running anything else is going to cause the low memory warning and then purge it.

On 03/20/2012 07:27 PM, @Piotr_Drapich wrote:

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
Piotr

On Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I don’t think that behavior would be considered appropriate on iOS or Android, users would complain that they just switched away to check their email and go back and it’s back to a checkpoint much
earlier.

The saving of exact current state is an expected feature.On 03/21/2012 11:16 AM, sdl at union.pl wrote:

A good example would be a game with checkpoints while progressing
through it. In this case there is no need to save the state of the game
between checkpoints, because it was already saved at a checkpoint. When
such game is terminated and ran again the progress starts from the last
saved checkpoint.

regards,
Piotr

On Wed, 21 Mar 2012, Forest Hale wrote:

What kind of game or application would not have state worth saving? The point is to dump the current state to disk in case the application is purged from memory (entirely) and when the user starts it
again they expect to see it exactly where they left off - usually paused but with no other changes.

This functionality exists because apps can be entirely deleted from memory at any time when in the background, a typical example is a very memory hungry highend game which literally can’t survive in a
background state because running anything else is going to cause the low memory warning and then purge it.

On 03/20/2012 07:27 PM, sdl at union.pl wrote:

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
Piotr

On Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

When you switch away, you’re not quitting the application (at least on
iOS >3) - it is put in background and in this case you will not loose the
current state of it when you activate it back. It happens only when the
application is killed by the system when it did not free its resources
after receiving memory warning or when memory is really low and more is
needed for a newly started appliciation or requested by currently active
application.
POn Wed, 21 Mar 2012, Forest Hale wrote:

I don’t think that behavior would be considered appropriate on iOS or Android, users would complain that they just switched away to check their email and go back and it’s back to a checkpoint much
earlier.

The saving of exact current state is an expected feature.

On 03/21/2012 11:16 AM, @Piotr_Drapich wrote:

A good example would be a game with checkpoints while progressing
through it. In this case there is no need to save the state of the game
between checkpoints, because it was already saved at a checkpoint. When
such game is terminated and ran again the progress starts from the last
saved checkpoint.

regards,
Piotr

On Wed, 21 Mar 2012, Forest Hale wrote:

What kind of game or application would not have state worth saving? The point is to dump the current state to disk in case the application is purged from memory (entirely) and when the user starts it
again they expect to see it exactly where they left off - usually paused but with no other changes.

This functionality exists because apps can be entirely deleted from memory at any time when in the background, a typical example is a very memory hungry highend game which literally can’t survive in a
background state because running anything else is going to cause the low memory warning and then purge it.

On 03/20/2012 07:27 PM, @Piotr_Drapich wrote:

HI Brian,
For games or applications where no data neeeds to be saved you dont need
to handle didenterbackground and use mutex to arbitrate: the simpler way
would be to make a global variable, containing the state of
your app and change it in callback depending on type of event received.
The main loop can check this variable and execute game state updates,
rendering and audio depending on this variable.
regards,
Piotr

On Mon, 19 Mar 2012, Brian Barnes wrote:

I’ve been doing a lot of research on this and while I haven’t attempted an implementation (I just hacked the SDL code to call back into my code), I want to explain where I’m coming from. It does not look like, especially for me, anything but callbacks will work.

There are really 4 message we are looking at (the patch floating around only handles 2 of them, plus memory low.)

applicationWillResignActive
applicationDidEnterBackground

applicationWillEnterForeground
applicationDidBecomeActive

How Apple wants you to handle this is:

applicationWillResignActive - slow down or stop your loops
applicationDidEnterBackground - save your state

NOTE, and this is very important. If you have a tight loop, it will CONTINUE TO RUN during these messages. ResignActive is called first (where you should shut down your loops) and EnterBackground is next, where you have 5 seconds to save your state. After 5 seconds, your code is frozen.

The big problem is you need to deal with your loop. In ResignActive, I’ll need to use a mutex to make sure my loop has completed one trip before I release back to the OS, and before I get EnterBackground. Otherwise, my game will still be generating state and there will be all sorts of havok. Yes, I’m running a tight loop instead of responding to timers, I understand the ins-and-outs of this :slight_smile:

The opposite number, EnterForeground and BecomeActive, basically have the same problem in reverse, but should be solved by making sure the loop pauses in the right place.

Even worse, your code is frozen so you can’t poll for events; therefore you will never get the “memory low warnings.” Without a doubt, games are going to be the number one targets of this and iOS will just send a KILL to your app after you do nothing on a memory warning.

As I was looking through this, I also noticed that there is a bizarre bit of code to deal with the terminate message. This is also something that should be in the callback, we’ll just have to know if we write an iOS application to handle quiting in a callback. The same thing applies – need to mutex the loop and then quit.

Now, you CAN get away with this (in a manner) in the queued polling, you’re just asking for a large number or hard to debug crashes in the future.

The original patch is still good. It just needs to add:

applicationDidEnterBackground
applicationWillEnterForeground
applicationWillTerminate

And probably that wacky long jump stuff can go.

[>] Brian


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Piotr wrote:

Don’t do that! If I’m playing your game, and I’m halfway to the next
checkpoint, and I get a phone call, I don’t want to get back to the game
and find out I’ve lost a couple minutes of progress! That’s the easiest
way to get a lot of 2 star reviews :slight_smile:

BTW, thanks for the work on the patch. Hopefully we can convince the
powers that be to put it in the repo.

[>] Brian> A good example would be a game with checkpoints while progressing

through it. In this case there is no need to save the state of the game
between checkpoints, because it was already saved at a checkpoint. When
such game is terminated and ran again the progress starts from the last
saved checkpoint.

Piotr wrote:

When you switch away, you’re not quitting the application (at least on
iOS >3) - it is put in background and in this case you will not loose
the current state of it when you activate it back. It happens only
when the application is killed by the system when it did not free its
resources after receiving memory warning or when memory is really low
and more is needed for a newly started appliciation or requested by
currently active application.

Docs are very specific here (for > 3). On Enter background, you remove
AS much memory as you can. You’re going to be an immediate target for
killing if you don’t. You should NOT use the low memory warning for
this. When you get that, the OS is already doing funky work in the
background that you probably don’t want to have to deal with.

In Resign, stop loops. This is because if they cancel and alert/phone
call, you could go immediately back into being live.

In EnterBackground, save state and kill everything you can. I’m going
to be deconstructing the entire game. You go into background ONLY if
you don’t cancel what was interrupting you, or it’s the home button.

Think about it like this:

Get phone call
WillResign
Accept phone call
EnterBackground

or

Get phone call
WillResign
Cancel phone call
DidBecomeActive

or

Hit Button
WillResign
EnterBackground (right after return from willresign)

That’s why there are two messages sets.

[>] Brian