cocos2d Mac关闭和运行时启动

时间:2013-04-10 17:39:46

标签: cocos2d-iphone cocosbuilder

我们正在构建一个内容编辑器,在NSWindow中为了测试目的而调出一个“cocos Player”。用户可以测试一些内容,然后关闭窗口。

所以我需要能够关闭cocos并在同一个应用程序中重新启动。

如果我使用CC_MAC_USE_DISPLAY_LINK_THREAD线程模型,一切正常。我必须在CCDirectorMac中修复才能使其正常工作。在CCDirectorMac | stopAnimation中,我必须将_runningThread设置为nil,因为#if#elif在使用CC_MAC_USE_DISPLAY_LINK_THREAD时未将其设置为nil。

无论如何,现在我能够“结束”导演,然后在没有问题的情况下重新开始导演。

我的问题是:如果我正在构建一个AppKit编辑器,偶尔使用cocos2D我的线程模型真的是CC_MAC_USE_MAIN_THREAD,如文档中所建议的那样?

当我使用CC_MAC_USE_MAIN_THREAD时,我会在stopAnimation的行中找到 HANG

CVDisplayLinkStop(displayLink);

我认为主线程很好,可以避免我们工具的线程问题。性能不是问题。我找不到任何关闭并重新启动NSWindow中cocos2d的示例代码......所以我的假设是我在未经测试的水域(或经过少量测试的水域)。

我关闭/重启的步骤是:

  1. 致电[[CCDirector sharedDirector] end]
  2. 这会调用stopAnimation
  3. 然后以与原来相同的方式重新初始化cocos2d
  4. 对于Mac桌面应用程序的线程模型的任何建议......以及CVDisplayLinkStop挂起的原因将不胜感激。

    提前致谢。

2 个答案:

答案 0 :(得分:3)

好的,我在阅读这篇文章及其在Apple邮件列表上的答案后想出来了:http://lists.apple.com/archives/quartz-dev/2006/Oct/msg00056.html

使用CC_MAC_USE_MAIN_THREAD时,显示链接线程使用performSelector:onThread:waitUntilDone:在主线程上运行drawScene:。它为YES参数传递waitUntilDone:,因此显示链接线程阻止,直到主线程可以处理drawScene:调用。

这是cocos2d代码的相关片段。在显示链接线程上调用MyDisplayLinkCallback

static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
    CVReturn result = [(CCDirectorDisplayLink*)displayLinkContext getFrameForTime:outputTime];
    return result;
}

- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime
{
#if (CC_DIRECTOR_MAC_THREAD == CC_MAC_USE_DISPLAY_LINK_THREAD)
    ...
#else
    // Display link thread blocks here:
    [self performSelector:@selector(drawScene) onThread:_runningThread withObject:nil waitUntilDone:YES];
#endif
    return kCVReturnSuccess;
}

当主线程尝试运行CVDisplayLinkStop() 阻止直到显示链接线程中的显示链接回调结束时,会出现问题。由于回调是在等待主线程处理其drawScene:call的同时,两个线程都变为死锁

- (void) stopAnimation
{
    ...

    if( displayLink ) {
        // Main thread blocks here:
        CVDisplayLinkStop(displayLink);
    ...
}

所以,现在我的解决方法。我添加了一行来运行主线程的runloop,以强制执行drawScene:调用,从而解除对显示链接线程的阻塞。这样,当你致电CVDisplayLinkStop()时,你就是安全的。这是我的补充(cocos2d 2.1版本中的CCDirectorMac.m第473行):

- (void) stopAnimation
{
    ...

    if( displayLink ) {
#if (CC_DIRECTOR_MAC_THREAD != CC_MAC_USE_DISPLAY_LINK_THREAD)
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
#endif
        CVDisplayLinkStop(displayLink);
    ...
}

我不确定这是 正确的事情,可能有更好的方法来解决这个问题,但目前这种解决方法对我来说还不错。

答案 1 :(得分:0)

感谢这篇文章,它帮助我弄清楚了如何通过在单独线程(而不是主线程)上处理显示链接回调,在非cocos2d应用程序中解决相同的死锁。

{{1}}