在OS X上使用Haskell SDL

7

在OS X上,SDL使用预处理技巧来重载main()函数,并使用Objective C编写自己的入口点,以调用用户的main()函数。

这些技巧使得非C语言的SDL用户(例如:Haskell绑定)非常困难。

这样做有什么好处吗?

为什么SDL不能在SDL_init()函数中完成Objective-C Cocoa初始化呢?

1个回答

5
Mac OS X的方法与其他非Linux平台(Windows,旧Mac,BeOS)的方法并没有太大区别。你可以问SDL开发人员为什么要这样做,但我可以看到他们选择这样做的几个原因:
- 这使得SDL代码的依赖性得以保持,该代码专注于初始化SDL特定子系统(视频、音频、定时等),并将其限制在SDL专门设计用于处理的特定子系统上。也就是说,这样SDL会保持精简和高效。 - 它避免了引入新的平台特定子系统来进行应用程序初始化。并不是每个人都想要SDL为Mac应用程序设置的基本应用程序对象和菜单,如果你要将它放入SDL_init中,你需要将其作为可选子系统,以避免给不需要它的开发人员带来不便。 - 它正确地处理了控制反转,这是Mac OS X和其他应用程序框架通常操作的方式,同时保持了SDL例程的操作语义。SDL_init假设初始化完成后将返回调用者,但是如果你试图在SDL_init中创建一个应用程序对象并在其中调用[app run]以完成应用程序初始化和启动,你将永远无法返回。如果你没有在那里调用run,你就必须创建一个单独的SDL函数来设置应用程序运行循环。这可能会使SDL库变得更加复杂。所选择的方法通过让框架首先处理所有应用程序设置,并从applicationDidFinishLaunching调用SDL_main()例程,避免了所有这些问题。 - 它使得将在Linux上编写的SDL演示转换到Mac OS X变得容易。你甚至不需要重命名main - 预处理器将main()重命名为SDL_main()就已经为你处理了!
我猜最后一个原因是重新定义SDL_main.h中的main的主要驱动力,我同意这是一种丑陋的hack。
如果你准备放弃库和应用程序的跨平台可移植性,我建议你简单地修改你的SDL_main.h以删除以下行:
#define main SDL_main

从您的项目中的SDLMain.m中删除以下内容:
#ifdef main
#  undef main
#endif

如果您这样做,甚至不需要重新编译SDL。请注意,SDLMain.m已经设置好了调用SDL_main()而无需使用预处理器hack,SDL中没有其他内容会使用它,因此您可以将SDL_main()简单地提供为游戏的入口点。
如果您想采用另一种方法,自己接管main(),您仍然需要摆脱SDL_main.h中的#define main SDL_main hack,但除此之外,您并不受SDL为您提供的main()的约束。首先,请注意,SDLMain.{h,m}不是库本身的一部分;您必须在项目中单独包含它们。其次,请注意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
*/

这对我来说就像是邀请你自己动手解决问题,如果这些无法满足你的需求,可以使用SDLMain.{h,m}作为模板进行定制。如果你自己动手实现,你可以按照自己的意愿进行。事实上,你甚至可以使用HOC编写类似于SDLMain.m的东西。但是,除非你很擅长HOC,否则我建议保持简单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接