| iOS System Callback |
|
Jared Maddox
Guest
|
<snip>
At the same time, there may be apps where it makes sense to separate time-critical code & non-time-critical code. Can't say that I know of any, though (my backburner project likely won't deal with the time-critical bits correctly EVER, so.. ). Can anyone think of any cases where it would be useful to have both callbacks & events? _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||
|
|
||||||||||||||||||||
| iOS System Callback |
|
eclectocrat
|
Your use of the words 'time-critical' hit the nail on the head. Theoretically...
Perhaps some system might implement such events as signal handlers, which would add a new synchronization element to handling them. In such cases clients might not want to enter the murky waters of correct signal handling and opt to wait for the nice message to be handled in a normal context on the main thread. You asked for an example, so I made one up :) I feel as though we should avoid over-tailoring this patch to iOS, but I still strongly suggest the callback mechanism, as it's the only way to keep the library out of the way of clients that want to get down to the metal. I understand the confusion that might arise from having two delivery mechanisms, but remember that the library already provides alternate ways of doing the same thing (such as LoadWAV vs using rwops). My 2 pennies. On Tue, Mar 27, 2012 at 10:49 PM, Jared Maddox wrote:
|
|||||||||||||||||||||
|
|
||||||||||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Let's take these one at a time:
Jared wrote:
Jeremy wrote:
The bottom line is there's no other way to do this. Apple *requires* that this stuff be handled IN the callback. And more important than that, after the callback exits, your code *no longer receives any time!* You can't handle it by polling later. You code is halted. So it *has* to be in the callback. These type of callbacks are, by their very nature, very system independent. Ones of android, or any future system (windows phone, etc) aren't going to be necessarily the same. Instead of creating a confusing call that says "on X it does Y on Z it does W" kind of thing, make the calls specific to the OS that is catching them. Vittorio wrote:
But the point of SDL is to hide the implementation details and make things as cross platform as possible. Actually overriding internal structures and objects in a library is not the best way to go about this. The callback is simple, clean, and best of all, future proof. [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||
|
|
||||||||||||||||||
| Re: iOS System Callback |
|
RodrigoCard
|
Handling it ALSO as an event could be useful. For example, I could pause the game or prevent drawing the next frame (until the assest are reloaded, in case you dump all the textures in the willenterbackgorund ) when iOS returns control to the mainloop. The main loop must be aware that the callback was called, posting these events as sdl events looks correct. |
|||||||||||||||||||||
|
|
||||||||||||||||||||||
| iOS System Callback |
|
Jared Maddox
Guest
|
As far as my comment goes, it was about duplicating the callback into the event queue. I have no problem with callbacks.
Remember how I mentioned time-critical vs non-time-critical? My 'backburner' project is adding SDL support to a pre-existing virtual machine. This virtual machine allows the programmer to act as if the virtual machine never shuts down (time just magically passes faster than normal, all connections fail, etc.). If I spend the effort to adapt this to iOS (which is unlikely, since I don't have one of the devices) then I'll obviously need to put code into one of the callbacks to implement this... However, the code running on the virtual machine should ALSO be informed of this (example: so that it can figure out if it needs to reload textures), and that realistically can (AND SHOULD) be relegated to events. Thus, two types of reaction to callbacks: 1) time-critical code that needs to run INSIDE the callback, and 2) non-time-critical code that can run anywhere as long as it eventually runs. As for me asking whether anyone can come up with a use-case? I don't think I'll be using this, so I don't feel that I can JUSTIFY the developer effort with my example. It may be informative, but I could just as easily implement the events myself, and I probably won't be using the callbacks for this project regardless.
I think you mean system-dependant. At any rate, I don't know where you're going with this?
I heartily agree, callbacks are the correct way to do this.
So this makes sense to someone else, too? That's good. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| iOS System Callback |
|
Vittorio Giovara
Guest
|
In my opinion, you are missing the "Simple" in "Simple Directmedia Library"...
If you need to do something so complex that forces you to - set up callbacks; - respond in quasi real time; - handle a variable number of events you might as well just subclass the main delegate instead of completely revolutionising the SDL chain. Beware that I hardly believe the proposed implementation is future proof, in fact as you know the events that need a fast action might change with every ios release (like it happened from 3.x to 4.x). I'm sure that subclassing+ovverriding can be adopted for android as well. I'm not discreting the patch or the patch's author, I'm just worried about the possible implications and feature duplication. Best, Vittorio On Thu, Mar 29, 2012 at 5:32 AM, Jared Maddox wrote:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||
|
|
||||||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Jared wrote:
Yes, I understand that, what I'm trying to tell you is that it just won't work. You will NOT get some of these messages in the event queue; your program will be halted at that point. What you will get is the worse possible solution: player hits button, you get one event, code is halted, then you get (in a row) the "enter background" and "exit background" AFTER you have exited the background. This is bad and will only serve to make the events useless.
There's nothing stopping you dropping a "minizimed" or "maximized" event on the queue. Again, you're avoiding the giant elephant in the room, which is that your code is halted! You can't timely send these messages. This is just how iOS works. No usage case is going to change how the OS works. Vittorio wrote:
You can never create anything if you are worried about APIs changing. They will, and there's nothing you can do about it. Overriding is not a good ideal in a library! The concept of libraries is that they are black boxes. I should note that the big change in iOS (when background processing was added) was the ADDITION of new events. An override would have the exact same problem. And "Simple" is find, but "works" is better. If this is the way it's required to do by the OS, there's no way around it. You *have* to respond to these in real time. OK, the last thing I want this to do is become some dumb fight on the level of things that end up being minutia. There are things that are very easy to compromise on, but we're going to be running around in circles until somebody with the authority decides to let something get in the trunk [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||
|
|
||||||||||||||||||||
| iOS System Callback |
|
gabomdq
|
I think overriding the delegate, if possible, is the best solution as you keep the changes limited to the platform that's got the problem, and you leave up to the developer what solution to implement. There's plenty of examples of black box libraries where you have to override things to make it work, the iOS framework being the first that comes to mind! We can also consider adding an example implementation of these overrides to help new users get quickly up to speed, or modify the current delegate to error out if you haven't overriden the required methods, etc. I do agree that it would be nice to hear what Sam or Ryan think about this! -- Gabriel. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Gabriel wrote:
If your code is all cross platform C code, then no, it's a bad idea, and especially a bad idea for a library that's front end is C. The iOS Frameworks are tied directly into your code; the SDL system sits in between and is supposed to hide those details. It's expected in an object oriented system. It's not expected in a C library. In my mind, the real beauty of SDL is that it allows you to write cross platform code. Here, there's no "layer". I think one of the big stumbling blocks for some is this: "changes limited to the platform that's got the problem". It's not a problem, it's a very different platform then SDL is normally used to. And what's worse, it's going to be the future. OS X and Windows both seem to be going that way, and you know eventually the any other OS will go that way. Always on, never quit, send to background, etc. All that is going to have to be dealt with on time. The fact is, eventually, and not far down the road, SDL is *going* to require this kind of system. If we have to override for every different implementation type, then we aren't really preserving anything cross platform. [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Jared Maddox
Guest
|
The only way that I can think of that this might future-proof your application is if you provide implementations for ALL events in this manner. If you do THAT, then there is NO reason to use SDL, because you're already doing almost everything that it does.
<snip>
Ah, I understand now. I had thought that you didn't understand my post, but it was the other way around. Thus, I apologize for the delay in telling you this: I HAVE considered this before, in reference to the very project that I mentioned (technically it was related to PWM messages, but the timing issue was the same). When I say 'non-time-critical' I mean it. It doesn't matter if it runs after execution resumes, because you're just informing the code of something that happened, nothing more. My conclusion was the same as now: the event makes sense, because the user of the event gets to read the documentation and decide if they care about it. Remember, SDL is calling your handler from within it's handler, it can do whatever temporary archiving that it needs to (though I assume that it currently favors "don't need to"), so these events have no reason to just vanish (in fact, you suggest otherwise yourself). Further, it doesn't matter if the messages are timely, because that's what the callback itself is for in the first place! As I said twice now, time-critical vs. non-time-critical. Time-critical needs the callback, non-time-critical just needs to know that it happened at all. When non-time-critical code finds out doesn't matter. Now, is it perhaps a little silly to have two events for this? Sure, but that's an implementation detail.
Agreed.
Also, if (just as an example) someone decided to port SDL as a micro-kernel interface to graphics hardware, this callback system could be used to make hardware-interrupts easier to deal with. Same thing would go with any other callback system that used unusual function styles (e.g. lots of MS Windows functions, so probably WindowsRT); by handling those things itself & providing a callback interface where relevant, SDL makes it much easier to deal with those systems.
That sounds REALLY badly designed. Interfaces to other systems should fully adapt what they're interfacing to into their own idioms. SDL interfaces to OS systems, and should thus fully adapt those parts of iOS that it actually touches (in some cases this might not actually be realistic, but this is not one of those cases).
The first just increases the boilerplate that developers have to write, the second is obnoxious (especially if they just don't care, e.g. a clock application). _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| iOS System Callback |
|
gabomdq
|
It may very well be bad design, but as everything in real life it is (at least in my opinion) a compromise, a good balance between solving what currently is an iOS only issue (despite what the future may bring, currently it is a single platform issue) and keeping it restricted to the platform with the problem.
I don't see how a particular application simplicity is of relevance here. Currently for the Android platform you have to jump through several minor hoops to set the project up just to show one pixel or build the next Minecraft, a complex project like SDL will never be click and play in all the cases, specially considering the broad range of supported platforms which don't share a design philosophy. -- Gabriel. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||
|
|
||||||||||||||||||||
| iOS System Callback |
|
gabomdq
|
2012/3/29 Brian Barnes:
I'm sure Sam will send a message on about this eventually, I hope I'm not going out of line here posting this, but I chatted with him about this issue yesterday: Sam: I'm actually okay with it.There actually is a system specific message callback system. SDL_SYSWM And you can set a callback hook that gets called inline. But it's kind of clunky for the kind of stuff you're dealing with here. Sam: I'm also okay with the delegate idea. It's cleaner for sure, but not extensible to other operating systems. Honestly, I'd like to see how it works out and get feedback from people on which they like best. So there you have it! I think that if you clean the patch up, upload it on the tracker or an unofficial repository ready to use for people to try it there's a good chance the patch will get accepted. -- Gabriel. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Forest Hale
Guest
|
For my part I vote for required callback functions provided by the app on the specific platforms that need them - I.E. fail to compile on iOS if the app does not provide a function named
SDL_iOSEvent_WillTerminate and similar functions. This is the only way I see to avoid this being a minefield for new developers on iOS who may not be aware of all the standard requirements and the current state of things (if the API changes later, we'll see new required functions, this is a nice reminder of changes that are necessary). The iOS SDK is a moving target, and the best way to get programmers in line is to have compile errors on outdated code. On 03/30/2012 05:49 AM, Gabriel Jacobo wrote:
-- 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 http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
|
||||||||||||||||
| iOS System Callback |
|
Tim Angus
Guest
|
I agree with this. I certainly think it's confusing to have events that will almost never be useful or correct.
On Fri, 30 Mar 2012, 22:36:06 BST, Forest Hale wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||
|
|
||||||||||||||||||
| iOS System Callback |
|
Jonas Thiem
Guest
|
Can someone clear up for me whether this issue affects Android aswell? I don't know enough of Android to know myself, and your discussion seems to have skipped this particular point (or I missed it digging in the old messages).
Regards, Jonas Thiem Tim Angus wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| iOS System Callback |
|
Rainer Deyke
Guest
|
On 2012-03-29 21:33, Brian Barnes wrote:
I completely agree with this. I see two ways to reconcile the cross-platform nature of SDL with the requirements of iOS: 1. The complicated way. Use setlongjmp trickery to temporarily pass control back to the app's event loop from the callback until the event is handled. It's messy and difficult on the SDL side, but it allows the user to completely ignore the special requirements of the iOS platform. 2. The simple way. Add a single API for synchronous callback events, and require it for all platforms. User code is made a bit more complicated, but remains platform independent. -- Rainer Deyke _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
|
||||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Forest Hale wrote:
I'm not opposed to this, either. I just want something to get into the trunk ASAP so I can begin testing with it, as I'm hoping to put out my first dim3 iOS game in a couple months. :) The only things that, too me, are necessary, is 1) they have to be callbacks 2) Unneeded event pumps are removed from the code (without this, #1 is nearly impossible to handle) The way above is actually how I tested it now by hacking these into the static library, but that's in a very quick and dirty way and certainly not something patch worthy. It wouldn't actually have to be anything but calling these functions without a stub; iOS requires the libraries (at this point, as far as I remember) to be static libraries anyway. Should I work up a patch? [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
I created a patch.
http://www.klinksoftware.com/download/iOSCallback.zip This contains 3 files. The patch itself, and the two changed .m files if anybody wants to just apply it that way (both in video/uikit). This was done off the trunk from about a day ago (I doubt these files have changed.) This ASSUMES you are compiling a static library, which right now is your only option, and it requires that these functions exist. The functions are: void SDL_iOSEvent_WillTerminate(void); void SDL_iOSEvent_DidReceiveMemoryWarning(void); void SDL_iOSEvent_WillResignActive(void); void SDL_iOSEvent_DidBecomeActive(void); void SDL_iOSEvent_DidEnterBackground(void); void SDL_iOSEvent_WillEnterForeground(void); Currently, I get a crash every 3rd or so time. I will be tracking this; it's obviously some threaded or race condition, and I have some ideals. For now, I'm assuming it's my code. I left in there the call that adds a minimize/maximize event onto the event stack. I ignore these on iOS, so somebody else will have to fight over include/not-include. :) NOTE: I REMOVED a pump events from swap buffer. ANY pump events outside of event polling code is going to be asking for trouble. So using this REQUIRES that you pump events yourself (or poll events, whatever.) This is something you should probably be doing anyway. There could be more, and it could be the source of my crash, but I won't know until I can investigate further. The patch itself (don't use this, use the one in the zip): diff -r 6bb657898f55 src/video/uikit/SDL_uikitappdelegate.m --- a/src/video/uikit/SDL_uikitappdelegate.m Tue Feb 28 21:58:36 2012 -0500 +++ b/src/video/uikit/SDL_uikitappdelegate.m Sat Mar 31 12:54:02 2012 -0400 @@ -36,6 +36,15 @@ #undef main #endif +// these events must be defined in the client code +// this assumes a static library +extern void SDL_iOSEvent_WillTerminate(void); +extern void SDL_iOSEvent_DidReceiveMemoryWarning(void); +extern void SDL_iOSEvent_WillResignActive(void); +extern void SDL_iOSEvent_DidBecomeActive(void); +extern void SDL_iOSEvent_DidEnterBackground(void); +extern void SDL_iOSEvent_WillEnterForeground(void); + extern int SDL_main(int argc, char *argv[]); static int forward_argc; static char **forward_argv; @@ -123,16 +132,16 @@ - (void)applicationWillTerminate:(UIApplication *)application { - SDL_SendQuit(); - /* hack to prevent automatic termination. See SDL_uikitevents.m for details */ - longjmp(*(jump_env()), 1); + SDL_iOSEvent_WillTerminate(); +} + +- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application +{ + SDL_iOSEvent_DidReceiveMemoryWarning(); } - (void) applicationWillResignActive:(UIApplication*)application { - //NSLog(@"%@", NSStringFromSelector(_cmd)); - - // Send every window on every screen a MINIMIZED event. SDL_VideoDevice *_this = SDL_GetVideoDevice(); if (!_this) { return; @@ -143,13 +152,14 @@ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } + + SDL_iOSEvent_WillResignActive(); } - (void) applicationDidBecomeActive:(UIApplication*)application { - //NSLog(@"%@", NSStringFromSelector(_cmd)); - - // Send every window on every screen a RESTORED event. + SDL_iOSEvent_DidBecomeActive(); + SDL_VideoDevice *_this = SDL_GetVideoDevice(); if (!_this) { return; @@ -162,6 +172,16 @@ } } +- (void) applicationDidEnterBackground:(UIApplication*)application +{ + SDL_iOSEvent_DidEnterBackground(); +} + +- (void) applicationWillEnterForeground:(UIApplication*)application +{ + SDL_iOSEvent_WillEnterForeground(); +} + @end #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff -r 6bb657898f55 src/video/uikit/SDL_uikitopengles.m --- a/src/video/uikit/SDL_uikitopengles.m Tue Feb 28 21:58:36 2012 -0500 +++ b/src/video/uikit/SDL_uikitopengles.m Sat Mar 31 12:54:02 2012 -0400 @@ -95,7 +95,7 @@ [data->uiwindow makeKeyAndVisible]; /* we need to let the event cycle run, or the OS won't update the OpenGL view! */ - SDL_PumpEvents(); +// SDL_PumpEvents(); } [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||
|
|
||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Rainer Deyke email just alerted me that I forgot a bit of this patch (which is not important at this point) -- all the long jump stuff can be removed if we go this way.
I should note that I'm not married to either way; I could care less if it's a callback mechanism or the patch I just put up (which I only put up to hopefully get something moving.) As long as it fits the requirements, i.e., it's a callback, then everything is fine with me. The patch code I put up is a bit simpler than registering callbacks, but restrictive in static libs only (which is already a requirement.) [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||
|
|
||||||||||||
| iOS System Callback |
|
eclectocrat
|
Please no long jumps! This doesn't play well with C++ stack unwinding and will lead to memory leaks and/or state mess-ups.
On Sat, Mar 31, 2012 at 3:22 PM, Brian Barnes wrote:
|
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Forest Hale
Guest
|
I'm liking this patch so far but haven't had a chance to test it, it's hard for it to be a regression as currently in my project I'm not even handling these events yet, so I'm wide open on the how,
but I am firmly in the "must be callbacks" crowd for simplicity sake :) And longjmp is vile stuff, everything in SDL2 that relies on it terrifies me :) On 03/31/2012 12:22 PM, Brian Barnes wrote:
-- 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 http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Eric Wing
Guest
|
On 3/31/12, Brian Barnes wrote:
I am in general agreement that there should be a real callback for this. As you said, there has been a movement to event driven systems for awhile now. As issues like battery life become more important to end users, I believe the pressure for event systems will continue to increase. As for your patch, I'm thinking we might be able to improve upon this so it is more optional, more extensible, and less platform specific. I think we should introduce a new/general SDL function that lets you set a function pointer to handle callback events. (This is akin to SDL_mixer's callback system.) On platforms that support callbacks, if the function pointer is set, it will invoke the user's function, otherwise it is a no-op. (All typed in mail, so code is unverified.) void SDL_SetEventCallback( void (*sdl_event_callback_function)(SDL_Event* event, void* userdata), void* userdata); I haven't looked at the old iOS/SDL patch for handling events, but I assume there is already special information packed into SDL_event so you could get this through PollEvent. So I propose to reuse those SDL_events for the callback. The callback will pass through an SDL_event so you can identify which specific event is happening (e.g. background, resume, low memory). I hope we might be able to also pass any special OS specific data in this structure just in case, otherwise we might want an additional void* parameter for this. The userdata parameter is for users to pass through any special information they need to get back from the callback so they don't need global variables. (This is a pet-peev of mine about SDL_mixer's callbacks.) void MyEventCallbackHandler(SDL_Event* event, void* userdata) { // Look at the SDL_Event to figure out what kind of event this is and handle it if(MyIsSuspendEvent(event)) { // Do what I need to do to save my info and prepare for suspend } else if(MyIsResumeEvent(event)) { } else if(MyIsLowMemoryEvent(event)) { } } int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); // … yada yada yada SDL_SetEventCallback(MyEventCallbackHandler, NULL); return 0; } Then for example, in the iOS implementation of SDL: - (void)applicationWillTerminate:(UIApplication *)application { // Note: SDL will need some global/static variable to save the function pointer that user registered and another for the user data. // This will be in the SDL core and not the platform specific implementation. if(NULL != s_userSDLEventCallbackPtr) { // We need to create the SDL_event with the proper stuff to passthrough. // Can we do this on the stack, or do we need to do this on the heap? // If on the heap, we need to free the memory after the callback SDL_Event event; // Fill the event for this event type (terminate) // … // Invoke the callback s_userSDLEventCallbackPtr(&event, s_userSDLEventCallbackUserData); // free the event if it was done on the heap } } The nice thing about this is that it can be useful on more platforms (e.g. Android, Mac, etc.) while at the same time allows users to opt-into it instead of throwing a compile error. (I will argue that though handling these is a good idea, not everybody actually needs to handle it directly at this level so forcing it may not be correct.) Thinking way, way ahead into the future, one possibility is that this could be used to optionally use SDL as an event driven system instead of the current polling architecture. So for example in Cocoa, we start adding the callback check to all the event handlers such as mouse, keyboard, touch, etc. and invoke the callback if defined and not be restricted to just 'special' system events like iOS style backgrounding. We might need one more API function to let users specify which mode they want to run SDL in for these. -Eric -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
| iOS System Callback |
|
Eric Wing
Guest
|
On 3/31/12, Brian Barnes wrote:
I don't think this proposal to address your original problem is much larger than the patch you proposed. Most of the code needed was in the previous message. The missing details are packing the specific SDL_events (which I assume already exist in the longjmp implementations so they just need to be moved) and where to store the global variables for the new API function. This change will not affect any current behavior and users or platforms that do not implement this will be none the wiser as this will just be a no-op as before.
Definitely not me, but maybe my opinion has a little weight.
As I said, this is 'way, way in the future' and something that may be opted into. What I'm proposing now solves your current problem in a more general way, while also laying possible ground work for future work on a general (but optional) event driven system. The solution for today that I'm proposing should be fairly constrained. -Eric -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||
|
|
||||||||||||||||||||
| iOS System Callback |
|
sdl
Guest
|
Hi Eric,
I already did an implementation of generic callback mechanism very similar to what you described. The initial version with usage instruction was posted here: http://forums.libsdl.org/viewtopic.php?t=7733&sid=21dffacbd29855581fe66d8a1126a1df and the latest version with Android support here: http://forums.libsdl.org/viewtopic.php?t=8021&sid=1fc02d7d3399878c1a2f11c0a2d94895 I'll try to put it as a file somewhere tomorrow, because it looks like spaces got messed a bit. regards, Piotr On Sat, 31 Mar 2012, Eric Wing wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
|
||||||||||||||||
| iOS System Callback |
|
Eric Wing
Guest
|
On 3/31/12, wrote:
Oh cool Piotr! I skimmed it over (though I am not good at reading diffs) and I think we're very much on agreement. Several very quick feedback items: 1) Add a userdata callback parameter. (I have very strong opinions on this 2) I think we are all in agreement that the longjmp stuff needs to go away 3) I am a little concerned about the order of when the callback should be invoked. For example, in: - (void) applicationDidBecomeActive:(UIApplication*)application, I think you invoke the callback first, and then do the video/window reactivation stuff. I can't give you a concrete example, but I have a nagging feeling the order should be reversed. The risk is that some SDL subsystem is suspended and in the callback, the user tries to make API calls that affect or depend on the suspended subsystem not actually being suspended. Here is an attempt at an example. OS Suspend event comes in Pass user a callback. User pauses the audio in their game (remembers the seek position). We return from callback and suspend SDL (including audio) OS Resume event comes in. We resume SDL subsystems (including audio) Pass the user a callback. User unpauses their audio (reseeks to position if necessary) If we do this in the wrong order, for example in OS Resume, we do the callback first and then resume SDL, the user might be calling audio APIs that are no-ops or cause crashes since the underlying audio subsystem isn't fully active. -Eric -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Eric wrote:
They don't. You might need to check back on the longer, early thread about this. There are basically 6 messages, and 2 were exposed as minimize/maximum events, but that won't work for a variety of reasons already discussed at length. As I said before, I'm not married to any solution, and this one is also fine, and there's nothing to stop us from adding the new events, but one important note: Some will be SPECIFIC to iOS. iOS has a lot of messages dealing with sending applications to the back and forward that have to be dealt with at the correct place, so we will be filling up the regular event system with very iOS specific events (and in the future, Android specific ones, etc.) I just want to see something getting done ASAP :) While you solution is good, I do see it as a lot more work; the reason being is that if you only implement the 6 messages needed here, then it's easier, but then it's also a confusing API because it won't function as a replacement for ALL the events when the API is named that way and targetted that way. The other thing -- and this is the one that could be a very big deal -- is turning this on can be a either/or thing. If I start receiving events by callbacks, it would interfere how I receive them by polling, which would kind of force it to be either/or. If I just handle the iOS specific calls by callback, then I can leave my polling code in. Going to this means I need to begin to receive all events through this mechanism, and that would mean MASSIVE changes in a lot of code. (That is if I am getting your proposal right.) [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Piotr wrote:
Piotr's version is where we started all this. My version was actually from another guy's request, which I just implemented so others could play with it. Again, I have no horse in this race, anything that fits the requirements for a callback is fine with me, I'm just pushing and pushing to have something happen, so I'll implement any idea if it pushes it forward. If I had to pick, I'd probably go with Piotr's solution as it's more open-ended. NOTE: Eric, this solution is *not* the same solution you proposed (unless I am completely mis-reading it.) Piotr's solution is SPECIFICALLY for callback-required OS events, NOT for generic OS events. It can be tailored that way, but I think this is really where you might be getting confused. If you only implement it for OS stuff, then later implement it for everything else, it WILL break almost everybody's code. There are 3 solutions, right now: 1) Was it Forest Hale? I think solution, the one I implemented, the required callbacks 2) Piotr's register callback by constant 3) Eric's move all events to callbacks I'd pick 2. I know others picked 1. Not the biggest fan of 3. 1) Pros: Forces users to fill in required functions, easy to implement Cons: Not open ended, very specific 2) Pros: Open ended, more cross platform Cons: Allows programs the ability to ignore these message (they could stub in 1, above) 3) Pros: More forward thinking about events all together Cons: Will take a lot more to implement and can't really be done is steps DISCUSS! :) [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
|
||||||||||||||||
| iOS System Callback |
|
Eric Wing
Guest
|
On 4/1/12, Brian Barnes wrote:
You are mis-reading it. Piotr's solution is what I'm getting at. This solves your problem in a way that is still compatible and reusable for other platforms that have the same problem without being a pain for people on iOS that don't want to use it. What I am also saying for the third time, that 'very very far into the future', this could be extended (with a lot of work) to make SDL optionally event-driven. When I say, very far, I'm likely talking years from now. But by planting a compatible seed now, minimize future breakage if/when that time comes. -Eric -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||
|
|
||||||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Eric wrote:
I understand, and I'm telling you for the third time that'll break SDL on iOS if you ever make that change, when you do it in the future. Regardless, if you vote for Piotr's solution as is, I'm on board. The future stuff we will leave to the future. Also, this WILL not work unless you remove any unknown event pumps. The one I removed in my patch should continue on to this patch (in SDL_uikitopengles.m). If you do not remove this, you will get all sorts of crashes as these callbacks can come at inopportune times. [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Eric Wing
Guest
|
On 4/1/12, Brian Barnes wrote:
I'm aware that this won't be an easy change. That's why I reiterate that is a far in the future thing. As you said, the event pump stuff will have to be disabled if running in a full event driven mode. This suggests there will need to be another API mechanism to allow users to select which mode they want to run in. By default, the mode would retain current SDL behavior to preserve compatibility. To pull this off will require non-trivial effort which I am well-aware of. But this new API is not incompatible with this idea and in fact facilitates it. And the nasty stuff is mostly behind the scenes implementation details that don't affect the public API (sans the mode toggling API). But I do believe this needs to happen for SDL to remain useful/relevant in the future. There are already places in Cocoa that make assumptions about Apple driving the main event-loop, not the other way around. There was a post recently about a user not being able to use Game Center successfully with SDL (all the buttons remained unresponsive when activated). While I don't know for sure, this sounds very much like typical run-loop ownership problem that comes up every now and again in general Cocoa. Even though you didn't hit this specific one, these are real problems and very related to the heart of the immediate problem you are trying to solve. -Eric -- Beginning iPhone Games Development http://playcontrol.net/iphonegamebook/ _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
|
||||||||||||||||
| iOS System Callback |
|
Jared Maddox
Guest
|
Good points. I suggest a slight modification: enum SDL_callbackstage { SDL_initialcallback, SDL_queuecallback, SDL_finishcallback }; void SDL_SetEventCallback( int (*sdl_event_callback_function)( SDL_Event* event, void* userdata, SDL_callbackstage stage ), void* userdata ); The basic concept is based on Aspect-oriented programming. With Aspect-orientation, you basically replace calls to specific functions with a set of 3 functions: one that happens before the call; one that happens after the call; and one in between that decides whether the original function is called at all, gets to modify the arguments before they get passed to the original function, and gets to modify the return before it gets returned to the original caller. I propose that the final implementation be based on that, with the 'aspect' specifically applying to the places in the library where OS events are placed onto the SDL event queue (so that this doesn't affect user events). SDL_callbackstage is used to signal which position the callback was called from: SDL_initialcallback and SDL_finishcallback are both self-explanatory, they happen at the beginning and end of set of callback invocations, and their return value is ignored. SDL_queuecallback is used to control whether the event is added to the event queue (-1 for default (presumably "yes", but see the final paragraph of this post), 0 for no, 1 for yes). The behavior would be something like this: OS event comes in Pass user initial callback Pass user queue callback & react to return value Suspend/resume SDL (*) Pass user final callback *The exact order of the queue call & SDL being suspended/resumed should be event-dependent. I think that the basic outline above is correct. A callback to control whether SDL gets suspended/resumed might be useful on some platforms, but I doubt it. Conveniently, this variant of the patch wouldn't be too different than the current one, it just involves a switch statement (for the queue), two more callback invocations, an enum, and an extra argument. Applying this to events in general might involve more effort (I haven't checked), but that's effort that a callback system would require anyways. Note: I haven't received the digest for the following post yet.
Fortunately, my proposed variant doesn't have this problem. No mode switching, no magically knowing which generic events are hooked by callback & which aren't, just a simple add-in system where the callback can effectively say "pretend I don't exist". It provides an implementation route for Eric's future-proofing, without requiring SDL's maintainers to keep track of when a particular event was moved to the callback system. In all cases of my proposed variant, returning -1 if the callback doesn't recognize either the SDL_callbackstage value or the event type is correct, because it basically means "do the default". Thus, if the callback either doesn't know about or care about some particular SDL_callbackstage or event (or combination of the two) then it simply does nothing other than return -1, and (one way or another) SDL will do the default action. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||
|
|
||||||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Jared wrote:
That's a good idea but it can add a lot of overhead, especially in the problem were trying to solve which is time critical (the OS will actually attempt to halt you if you take to long to do what you are doing.) Would a simpler solution be use Eric's version, add a boolean return, if you return TRUE, you've handled the event, if you return FALSE, drop the event on the queue to later be picked up by an event poll? That solves the problem in the same way without a lot of overhead, and future proofs an iOS code (just return TRUE for all the iOS events, but FALSE for everything else.) This is basically the same solution you've proposed, but without the various before/after stages. I'm not sure this would ever be useful, but I like the direction. Regardless, this would solve (so far) all the major problems. [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Jared wrote:
Going back to the original problem, iOS actually handles all these events separately; i.e., there's a before/after event (roughly) and before/after event (again, roughly) for going in and out of suspending. And each has very specific tasks you are supposed to handle. Are you saying you want to wrap these into one event, with a before and after? Or each one has a before and after? For something that's so OS specific, I think anything except exporting the exact events will cause trouble. There really isn't any docs on the SDL side about what to do, but tons of docs on the iOS side telling you what to do for each event. If it's a before/after for each one, I don't really see the need. I've done a bit of perusing of the code, and I could actually add a event callback system pretty easily (I think), with a boolean return to handle "put back in the polling stack" kind of thing that would actually work (again, I think, without doing it.) Anybody care to try it out if I push out a patch? It'd basically be Eric's bit with a slight change, plus the addition of some specific iOS events. [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
gabomdq
|
Sorry for bashing, but this looks to me as an over engineered solution, there's been simpler (though perhaps less flexible) solutions mentioned. -- Gabriel. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
|
||||||||||||||
| iOS System Callback |
|
Brian Barnes
Guest
|
Here's a proposal. NOTE: There IS already a system in place for this,
"event watches". It doesn't seem complete yet as there's some comments here and there. Is this a SDL2 thing? Should it be one or the other? Both would serve the exact same purpose. Anyway, quick code, haven't attempted to compile as I just typed it out for this message. This is step one, to add a overall event callback mechanism. Step 2 is to create and expose the new iOS callback event types. =========================================================================== Add to SDL_events.h typedef int (SDLCALL * SDL_EventCallback) (SDL_Event * event,void *userdata); extern DECLSPEC void SDLCALL SDL_SetEventCallback(SDL_EventCallback callback,void *userdata); ===Add to SDL_events.c ===to top: static struct { SDL_EventCallback callback; void *userdata; } SDL_EventCallback_Data; ===in SDL_StartEventLoop(void) add: SDL_EventCallback_Data.callback=NULL; SDL_EventCallback_Data.userdata=0; ===anywhere add: void SDL_SetEventCallback(SDL_EventCallback callback,void *userdata) { SDL_EventCallback_Data.callback=callback; SDL_EventCallback_Data.userdata=userdata; } ===in SDL_PushEvent(SDL_Event * event) make: int SDL_PushEvent(SDL_Event * event) { int skip_add; SDL_EventWatcher *curr; event->window.timestamp = SDL_GetTicks(); if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) { return 0; } // after filtering, before watches skip_add=0; if (SDL_EventCallback_Data.callback!=NULL) { skip_add=SDL_EventCallback_Data.callback(event,SDL_EventCallback_Data.userdata); } if (skip_add!=0) { for (curr = SDL_event_watchers; curr; curr = curr->next) { curr->callback(curr->userdata, event); } if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) { return -1; } } SDL_GestureProcessEvent(event); return 1; } ====================================== [>] Brian _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||
|
|
||||||||||||
| iOS System Callback |
|
Jared Maddox
Guest
|
I was saying, each one with a before/after. However, if it isn't needed, then there isn't any reason to use two (besides which, the possibility of more callback points being added at later dates/for other platforms is part of why I worded things the way I did).
The basic assumption that I'm making is two-fold: 1) There is a specific event where you suspend everything, and another where you resume; 2) The SDL function that calls your callback suspends the SDL library itself. With those two assumptions, if you have a mix of things that need to be suspended before SDL, and others that need to be suspended after, then you need two callback invocations in the relevant SDL function. However, I'm not an iOS developer, so maybe this isn't a real problem.
Ease of implementation was one of the reasons I made that specific suggestion _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||||||
|
|
||||||||||||||||||||

