Haskell SDL on OS X

OSL SDL uses preprocessing tricks to overload main () with its own entry point, written in Objective-C, which calls the main user.

These tricks make life difficult for non-C SDL users (like Haskell bindings).

Is there a good reason for this?

Why didn't the SDL initialize Cocoa's objective-C in SDL_init?

+7
haskell sdl macos
source share
1 answer

The approach for Mac OS X is not much different from the approach to other platforms other than Linux (Windows, old Mac, BeOS). You could ask the SDL developers themselves why they did this, but I see several reasons why they could do this:

  • Here, the dependencies of the SDL code are saved, which is focused on initializing the SDL subsystems (video, audio, time, etc.), limited to specific subsystems specially designed for working with SDL. That is, in this way, SDL remains scarce and average.
  • This avoids the need to introduce a new subsystem for a specific platform to initialize the application. Not everyone wants the application object and menu for barebone applications that SDL configures for Mac applications, and not a long snapshot - so if you are going to put it in SDL_init , you need to make it an optional subsystem so as not to inconvenience developers who don't need her.
  • It correctly manages the inversion of control; as a rule, Mac OS X and other application environments work, while preserving the operational semantics of the SDL routines. SDL_init assumes that it will return to the caller after initialization is complete, but if you tried to naively create an application object in SDL_init and call [app run] on it to complete the initialization of the application and start, you will never return. If you did not call run , you would need to create a separate SDL function to configure the application launch cycle. This can complicate the SDL library. The approach that was chosen avoids all this, allowing the infrastructure to take care of the entire application installed first and call the SDL_main() procedure from applicationDidFinishLaunching .
  • This makes it easy to convert Linux SDL demos to Mac OS X. You donโ€™t even need to rename the main one - reprogramming the preprocessor from main() to SDL_main() will take care of this for you!

I assume that the last of these reasons is the main driver for overriding main in SDL_main.h , which I agree with an ugly hack.

If you are willing to give up this level of cross-platform portability for your library and applications, I would suggest simply changing your SDL_main.h to remove the following line:

 #define main SDL_main 

and removal from the SDLMain.m project in your project:

 #ifdef main # undef main #endif 

You do not even need to recompile the SDL if you do. Note that SDLMain.m already configured to call SDL_main() without hacking the preprocessor, and nothing else in the SDL is going to use this, so you can simply provide SDL_main() as the entry point to the game.

If you want to go the other way by taking main() yourself, you still want to get rid of the hacking #define main SDL_main in SDL_main.h , but other than that, you are not obliged to main() , which the SDL provides for you. First, note that SDLMain.{h,m} are not part of the library itself; You must include them separately in your project. Secondly, pay attention to the following comments in SDLMain.h :

 /* SDLMain.m - main entry point for our Cocoa-ized SDL app Initial Version: Darrell Walisser <dwaliss1@purdue.edu> Non-NIB-Code & other changes: Max Horn <max@quendi.de> Feel free to customize this file to suit your needs */ 

It sounds like an invitation to me to switch to your own if they donโ€™t work for you, starting with SDLMain.{h,m} as a model. And if you ride on your own, you can do what you want! In this case, you can write the equivalent of SDLMain.m in Haskell using HOC if that is what you want. If you hadn't been whistling with the HOC, I would have kept it simple.

+5
source share

All Articles