我目前正在使用 SDL2 库和 C 语言编写 iPhone 应用程序,大部分情况下进展顺利。不幸的是,文档在某些方面似乎相当单薄,尤其是 iOS 特定的功能。我刚开始使用 SDL2,这让事情变得非常困难。到目前为止,一切正常,但我遇到了一个问题。 SDL2 定义了六种专门用于移动应用程序的事件类型。 README-ios.txt 文件描述了它们并这样使用它们:
int HandleAppEvents(void *userdata, SDL_Event *event)
{
switch (event->type)
{
case SDL_APP_TERMINATING:
/* Terminate the app.
Shut everything down before returning from this function.
*/
return 0;
case SDL_APP_LOWMEMORY:
/* You will get this when your app is paused and iOS wants more memory.
Release as much memory as possible.
*/
return 0;
case SDL_APP_WILLENTERBACKGROUND:
/* Prepare your app to go into the background. Stop loops, etc.
This gets called when the user hits the home button, or gets a call.
*/
return 0;
case SDL_APP_DIDENTERBACKGROUND:
/* This will get called if the user accepted whatever sent your app to the background.
If the user got a phone call and canceled it, you'll instead get an SDL_APP_DIDENTERFOREGROUND event and restart your loops.
When you get this, you have 5 seconds to save all your state or the app will be terminated.
Your app is NOT active at this point.
*/
return 0;
case SDL_APP_WILLENTERFOREGROUND:
/* This call happens when your app is coming back to the foreground.
Restore all your state here.
*/
return 0;
case SDL_APP_DIDENTERFOREGROUND:
/* Restart your loops here.
Your app is interactive and getting CPU again.
*/
return 0;
default:
/* No special processing, add it to the event queue */
return 1;
}
}
int main(int argc, char *argv[])
{
SDL_SetEventFilter(HandleAppEvents, NULL);
//... run your main loop
return 0;
}
我有几个关于这段代码的问题。
SDL_SetEventFilter() 有什么作用?我看了 SDL Wiki 页面,它似乎特别模糊。
在实践中,HandleAppEvents() 函数是如何工作的?例如,如果我有这样的代码:
int main(int argc, char* argv[])
{
//Initialize SDL, etc...
SDL_SetEventFilter(HandleAppEvents, NULL);
//I've got some SDL_Textures and windows and things...
SDL_Window* my_window;
SDL_Renderer* windowrend;
SDL_Texture* tex1, tex2, tex3;
//Primitive game loop
while(game_is_running){
handle_input();
do_logic();
update_screen();
}
destroy_all_my_data();
SDL_Quit();
return 0;
}
例如,当我收到 SDL_APP_WILLENTERBACKGROUND 时,应该在 HandleAppEvents() 或 main() 中放置什么样的代码来破坏内存或停止我的游戏循环?
假设 tex2 是可消耗的,如果应用收到 SDL_APP_LOWMEMORY 则可以将其删除。我如何从 HandleAppEvents() 中删除 tex2 而不会弄乱其他数据?
用户数据指针中有什么?
当我的应用程序进入后台时,我应该将我的纹理转换为表面,并将它们作为 bmps 保存在 ../tmp/目录中,还是当应用程序返回前台时它们仍然在内存中?
我希望我的令人困惑的问题能说明一些道理。如果有什么地方可以找到 SDL2 的详尽文档,我会很高兴知道。
感谢您的关注!
最佳答案
SDL_SetEventFilter 是一种“领先”SDL 事件队列的方法。在事件被放入队列之前,您基本上会在收到事件时得到事件,在 iOS 的情况下,您必须立即对它们使用react。
这背后的技术原因是,对于这类消息,iOS 使用了一系列回调,SDL 接收并为您包装这些回调,以使跨平台体验尽可能无缝,但事实仍然是 iOS 仍然希望您在从回调返回之前对它们采取行动。
因此,例如,如果我们只是将系统内存不足的消息放在队列中,而不是通过此机制将其直接传递给应用程序,那么在该事件通过队列之前您什么都不做、您对其进行轮询等,iOS 可以强制关闭您的应用程序,因为它没有按预期运行。
当应用进入后台时,您无需保存纹理。 iOS 会为你做这件事,如果它没有足够的内存来这样做,它只会杀死你的应用程序(你永远不会丢失 GL ES/ES2 上下文,这在某些 Android 设备上可能会发生)。
userdata 指针将包含您作为第二个参数传递给 SDL_SetEventFilter 的数据,因此如果您使用 SDL_SetEventFilter(HandleAppEvents, NULL),userdata 将为 NULL。
在 SDL_APP_WILLENTERBACKGROUND 上,如果我没记错的话,你不需要做任何事情。我有一段时间没有启动我的 iOS 应用程序,但我认为 SDL 会自行处理其所有内部状态(包括阻止事件循环然后重新启动它)。你必须自己处理的事件是 SDL_APP_LOWMEMORY 和 SDL_APP_TERMINATING,你如何处理它是特定于应用程序的(删除纹理、空闲内存等,它超出了 SDL 的具体范围)
关于ios - 我应该如何使用 SDL2 iOS 应用程序事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18563710/