Я перепробовал все, что мог, но не повезло.
У меня есть проект, который по сути является «интерпретатором» языка программирования. Таким образом, события передаются в цикл интерпретатора, интерпретированный код делает что угодно (в этом случае обновляет битовую карту памяти), затем цикл интерпретатора возвращается и возвращается обработчик событий. В конце концов вызывается drawRect приложения, и растровое изображение памяти обращается к NSView. Это все самое лучшее из того времени.
Но ... есть несколько ситуаций, когда интерпретируемый «код» хочет вызвать короткую анимацию, и делает это, обновляя битовую карту памяти, используя usleep () в течение нескольких миллисекунд, обновляя битовую карту памяти, usleep ( ) и т. д. Анимация занимает чуть меньше секунды, поэтому блокировка потоков не должна быть проблемой.
Проблема в том, что ни одна из анимаций не отображается, и экран не обновляется до тех пор, пока не истечет интерпретированный код, и событие не вернется.
Функция сна, которая вызывается, когда интерпретированный код указывает, что она хочет спать, выглядит следующим образом:
void KSleep(DWORD tm) {
if( [pView lockFocusIfCanDraw] ) {
inSleep = true;
[pView setNeedsDisplay:YES];
[pView display];
[pView drawRect:NSMakeRect(0, 0, pView.frame.size.width, pView.frame.size.height)];
[pView unlockFocus];
}
usleep(tm*1000);
}
'inSleep' - это глобальная переменная, которую я настроил для целей тестирования, 'pView' - это глобальный NSView * для единственного представления окна. ПРИМЕЧАНИЕ. Да, часть приведенного выше кода является избыточной, я просто включил ее, чтобы показать, что я пробовал многочисленные комбинации, пытаясь указать ОС, что представление грязное, и обновить его. Никто из них не работал.
Код drawRect (удаляющий весь код, который выполняет обычное перетаскивание растрового изображения) выглядит следующим образом:
-(void)drawRect:(CGRect)rect {
CGContextRef context = [[NSGRaphicsContext currentContext] graphicsPort];
CGContextSaveGState(context);
if( inSleep ) CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
else CGContextSetRGBFillColor(context, 1.0, 1.0, 0.0, 1.0);
CGContextFillRect(context, CGRectMake(0,0,200,200));
CGContextRestoreGState(context);
}
Итак:
1) Событие -mouseDown () происходит и вызывает интерпретатор с событием.
2) Интерпретированный код обращается к растровому изображению (я игнорирую это здесь, поскольку это не важно для работы или не работает обновления экрана), и вызывает 'sleep.'
3) Переводчик, увидев вызов сна, вызывает Ksleep () (см. Выше).
4) Ksleep блокирует фокус, который, кажется, создает контекст, поскольку без этого отладчик выдает предупреждения о контексте 0x0 во время функции drawRect (), а с помощью lockFocus он не имеет и, по-видимому, имеет допустимое значение контекста .
5) Ksleep помечает представление как нуждающееся в обновлении и вызывает (по-разному) «display» и / или «drawRect» и т. Д.
6) Процедура drawRect получает контроль (точки останова указывают, что в этом отношении все работает нормально). 'inSleep' установлен правильно. Он выполняет все действия в drawRect, как и ожидалось. Но НИЧЕГО не показывает на дисплее, пока ...
7) drawRect возвращается к Ksleep, время ожидания истекает, интерпретатор продолжает интерпретацию, интерпретированный код выполняет больше прорисовки и больше снов, примерно 10 раз (таким образом повторяя шаги 2-7 примерно 10 раз).
С момента запуска программы до тех пор, пока действие мыши не вызовет попытку «анимации», в представлении отображается желтый прямоугольник. Как только происходит щелчок мыши, вызывающий «анимацию», НИЧЕГО не обновляется в окне до тех пор, пока анимация полностью не завершится (хотя drawRect IS выполняется несколько раз в течение этой попытки анимации), ТОГДА прямоугольник становится синим. Но точки останова показывают, что выполнение проходит через drawRect (с true inSleep) каждый раз, когда вызывается подпрограмма KSleep ().
Это что-то нить? (Программа явно не создает никаких потоков.)
Я не особо ищу предложения о том, как избежать структуры анимации / KSleep, я понимаю, что это не самый предпочтительный метод работы Macos, но это попытка портировать старый проект из другого места и изменить ' интерпретировать код, чтобы избежать этого не представляется возможным.
Спасибо за любые идеи или предложения.