OS X上的Haskell SDL

Pea*_*ker 7 macos haskell sdl

OS X上的SDL使用预处理器技巧使main()用自己的入口点重载,用Objective C编写,调用用户的main.

这些技巧使非C SDL用户(例如:Haskell绑定)的生命变得非常困难.

有这么好的理由吗?

为什么SDL不能在SDL_init中执行Objective-C Cocoa初始化?

Owe*_* S. 5

Mac OS X的方法与其他非Linux平台(Windows,旧Mac,BeOS)的方法没有太大区别.您可以向SDL开发人员询问他们为什么这样做,但我可以看到他们选择这样做的几个原因:

  • 这保留了SDL代码的依赖性,SDL代码专注于初始化特定于SDL的子系统(视频,音频,时序等),这些子系统仅限于SDL特别设计用于的特定子系统.就是这样,SDL保持精益和平均.
  • 它避免了为应用程序初始化引入新的特定于平台的子系统.不是每个人都想要SDL为Mac应用程序设置的简单应用程序对象和菜单,而不是长篇大论 - 所以如果你打算将它放入SDL_init,你需要将它作为一个可选的子系统,以便不要给不需要它的开发人员带来不便.
  • 它正确处理控制反转,这是Mac OS X和其他应用程序框架通常运行的方式,同时保持SDL例程的操作语义.SDL_init假定它将在初始化完成后返回调用者,但是如果你天真地尝试创建一个应用程序对象SDL_init[app run]在其上调用以完成初始化应用程序并启动,那么你永远不会返回.如果你没有run在那里调用,则必须创建一个单独的SDL函数来设置应用程序运行循环.这可能会使SDL库变得相当复杂.选择的方法通过让框架首先处理所有应用程序设置并SDL_main()从中调用例程来避免所有这些applicationDidFinishLaunching.
  • 它可以很容易转移到Mac OS X中,以编码在Linux SDL演示转换你甚至不必重命名主-的预处理器重新命名main(),以SDL_main()负责的是你!

我猜这些原因中的最后一个是重新定义main in的主要驱动因素SDL_main.h,我同意这是一个丑陋的黑客.

如果您准备为您的库和应用程序放弃该级别的跨平台可移植性,我建议您只需修改您的SDL_main.h以删除以下行:

#define main SDL_main
Run Code Online (Sandbox Code Playgroud)

并从SDLMain.m项目中删除以下内容:

#ifdef main
#  undef main
#endif
Run Code Online (Sandbox Code Playgroud)

如果这样做,您甚至不需要重新编译SDL.注意,SDLMain.m已经设置为在SDL_main()没有预处理器黑客的情况下调用,而SDL中没有任何其他内容可以使用它,因此通过这种方式,您可以简单地提供SDL_main()作为游戏的入口点.

如果你想走另一条路,接管main()自己,你仍然想要摆脱#define main SDL_main黑客攻击SDL_main.h,但除此之外,你不会对main()SDL为你提供的东西感到满意.首先,请注意,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
*/
Run Code Online (Sandbox Code Playgroud)

这听起来像是一个邀请你自己滚动,如果这些不适合你,从SDLMain.{h,m}模型开始.如果你自己动手,你可以做你想做的事!就此而言,你可以SDLMain.m使用HOC 编写Haskell中的等价物,如果这是你想要的.但是,除非你是HOC的高手,否则我会保持简单.