我目前正在使用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页面,它似乎特别模糊。
实际上,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;
}例如,当我接收到一个HandleAppEvents()或main()时,应该在SDL_APP_WILLENTERBACKGROUND ()或main()中放置什么样的代码来破坏内存或停止游戏循环?
假设tex2是可以使用的,如果应用程序收到SDL_APP_LOWMEMORY,它可以被删除。如何在不干扰其他数据的情况下从tex2 ()中删除HandleAppEvents?
用户数据指针中有什么?
当我的应用程序进入背景时,我应该将我的纹理转换成表面,并将它们保存在./tmp/目录中作为bmps,还是当应用程序返回到前台时它们还在内存中?
我希望我那些令人困惑的问题有点道理。如果有一个地方,我可以找到一个完整的SDL2文档,这将是很好的了解。
谢谢你看一看!
发布于 2013-09-04 23:08:52
SDL_SetEventFilter是一种“领先”SDL事件队列的方法。在将事件放入队列之前,您基本上可以在接收到事件时得到它们,而在iOS情况下,您必须立即对它们做出反应。
这背后的技术原因是,对于这类消息,iOS使用一系列回调,SDL为您接收和包装这些回调,以使跨平台体验尽可能无缝,但事实仍然是,iOS仍然希望您在从回调返回之前对它们执行操作。
因此,例如,如果我们只是将系统内存不足的信息放在队列中,而不是通过这种机制直接将其传递给应用程序,那么在该事件通过队列、轮询它之前,您什么也不做,等等,iOS可以强制关闭您的应用程序,因为它的行为不像预期的那样。
当应用程序转到后台,你不需要保存你的纹理。iOS会为你做这件事,如果它没有足够的内存,它只会杀死你的应用程序(你永远不会失去GL /ES2上下文,这在某些安卓设备上是可以发生的)。
userdata指针将包含作为第二个参数传递给SDL_SetEventFilter的数据,因此如果使用SDL_SetEventFilter(HandleAppEvents,NULL),用户数据将为NULL。
在SDL_APP_WILLENTERBACKGROUND上,如果我没记错的话,你什么都不用做。我已经有一段时间没有启动我的iOS应用程序了,但是我认为SDL自己处理它的所有内部状态(包括阻塞事件循环,然后重新启动它)。您必须自己处理的事件是SDL_APP_LOWMEMORY和SDL_APP_TERMINATING,您如何处理特定于应用程序的事件(删除纹理、空闲内存等,它特别超出了SDL )。
发布于 2013-10-02 07:03:21
从这条线上可以看出,您必须停止在SDL_APP_WILLENTERBACKGROUND上的游戏循环,并在SDL_APP_WILLENTERFOREGROUND上恢复游戏循环,以避免崩溃。
https://stackoverflow.com/questions/18563710
复制相似问题