2013-04-10 5 views
0

우리는 테스트 목적으로 NSWindow에 "cocos Player"를 표시하는 컨텐츠 편집기를 구축하고 있습니다. 사용자는 일부 내용을 테스트 한 다음 창을 닫을 수 있습니다.cocos2d Mac 종료 및 시작시 런타임

그래서 코코스를 종료하고 동일한 응용 프로그램 내에서 다시 시작할 수 있어야합니다.

CC_MAC_USE_DISPLAY_LINK_THREAD 스레딩 모델을 사용하면 모든 것이 작동합니다. 이 작업을하려면 CCDirectorMac에 수정해야했습니다. CCDirectorMac | stopAnimation에서 _runningThreadCC_MAC_USE_DISPLAY_LINK_THREAD을 사용할 때 #if#elif에 의해 nil로 설정되지 않았기 때문에 nil으로 설정해야했습니다.

어쨌든 이제 감독을 "끝내고"나중에 문제없이 다시 시작할 수 있습니다.

내 질문 비록이 : 만약 내가 cocos2D의 가끔 사용과 함께 AppKit 편집기를 구축하고 내 스레딩 모델은 실제로 CC_MAC_USE_MAIN_THREAD 설명서에 제안되어 있습니까?

내가 CC_MAC_USE_MAIN_THREAD를 사용합니까

나는 라인에 stopAnimation에서의 HANG를 얻을 :

CVDisplayLinkStop(displayLink);

나는 메인 스레드가 잘 될 것입니다 우리의 도구 스레딩 문제를 피할 거라고 생각해. 성능은 중요하지 않습니다. NSWindow에서 cocos2d를 종료하고 다시 시작하는 샘플 코드를 찾을 수 없습니다. 여기 내 가정은 테스트되지 않은 바닷물 (또는 거의 테스트하지 않은 바닷물)입니다. 종료/재시작을

내 단계는 다음과 같습니다

  1. 전화 [[CCDirector sharedDirector] end]
  2. stopAnimation 다음
  3. 내가 스레딩에 원래

어떤 조언을했던 것과 같은 방법적인 Cocos2D 다시 초기화 호출 맥 데스크톱 애플 리케이션을위한 모델 ... 그리고 왜 CVDisplayLinkStop 교수형 크게 감사하겠습니다.

미리 감사드립니다. 좋아

+0

내 앱에서 똑같은 동작이 발생합니다. CC_MAC_USE_MAIN_THREAD (내가 얻은 이상한 문제를 해결하는)로 전환하면 앱을 종료하려고 할 때 중단됩니다 ([[CCDirector sharedDirector] end]를 호출). 이걸 알아 냈어? –

답변

1

, 나는이 게시물과 애플 메일 링리스트에 그 답을 읽은 후 그것을 알아 냈 : http://lists.apple.com/archives/quartz-dev/2006/Oct/msg00056.html

CC_MAC_USE_MAIN_THREAD를 사용하여 디스플레이 링크 스레드가 주 스레드에서 drawScene:을 실행하는 performSelector:onThread:waitUntilDone:를 사용합니다. waitUntilDone: 매개 변수에 YES을 전달하므로 기본 스레드가 drawScene: 호출을 처리 할 때까지 디스플레이 링크 스레드 을 차단합니다.

다음은 cocos2d 코드의 관련 부분입니다. 디스플레이 링크 스레드에서 MyDisplayLinkCallback이 호출됩니다. 메인 쓰레드는 디스플레이 링크 스레드 마감 디스플레이 링크 콜백 할 때까지 CVDisplayLinkStop()블록을 실행하려고 할 때

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; 
} 

문제가 나타납니다.콜백은 메인 스레드가 drawScene : call을 처리하기를 기다리는 것과 동시에, 두 스레드 모두 교착 상태 인이됩니다.

- (void) stopAnimation 
{ 
    ... 

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

이제 해결 방법을 알려드립니다. 디스플레이 링크 스레드를 차단 해제하는 drawScene: 호출을 강제 실행하기 위해 주 스레드의 runloop을 실행하는 라인을 추가했습니다. 그렇게하면 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); 
    ... 
} 

만이 해결 방법 지금은 나에게 충분하다.

+0

고마워요! 커스텀 OpenGLView와 비슷한 문제가 있었지만, Retina 디스플레이에 대해서만 마찬가지였습니다. 'waitUntilDone'을'YES'에서'NO'로 바꾸면 시작시 멈추지 않습니다. –

관련 문제