Я знаю, что я не первый, кто пытается использовать Cocoa на OSX вместе с существующим основным циклом c / c ++, но мне не очень нравятся решения, с которыми я столкнулся до сих пор, поэтому я придумал другое Идея, которую я хотел бы обсудить. Самый распространенный способ, который я нашел (в glut, glfw, SDL, а также QT, я думаю), это использовать опрос для замены метода запуска NSApplications и обрабатывать события самостоятельно следующим образом:
nextEventMatchingMask:untilDate:inMode:dequeue:
Это имеет большой недостаток в том, что процессор никогда по-настоящему не работает, так как вам нужно все время опрашивать, чтобы проверить, есть ли какие-либо новые события, кроме того, это не единственная вещь, которая происходит внутри функции запуска NSApplications, поэтому она может сломать некоторые подробности, если вы используете эту замену.
Итак, я хотел бы сохранить неповрежденным цикл запуска какао. Представьте, что у вас есть собственные методы таймера, реализованные в c ++, которые обычно управляются и запускаются внутри вашего основного цикла (это лишь небольшая часть в качестве примера). Моя идея состояла бы в том, чтобы переместить все мои циклические фрагменты во вторичный поток (так как запуск NSApplication необходимо вызывать из основного потока, насколько я знаю), а затем публиковать пользовательские события в моей производной версии NSApplication, которая обрабатывает их соответствующим образом внутри своего sendEvent: метод. Например, если мои таймеры были измерены в моем цикле c ++, я бы отправил пользовательское событие в NSApplication, которое, в свою очередь, запускает функцию loopFunc () моего приложения (также находящейся в mainthread), которая соответствующим образом отправляет события по моей цепочке событий c ++. ,
Итак, прежде всего, вы думаете, это было бы хорошим решением?
Если да, как бы вы реализовали это в какао, я нашел этот метод только в NSEvent Reference для публикации пользовательских событий NSApplicationDefined:
otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:
, а затем использовать что-то вроде:
[NSApp postEvent:atStart:]
для уведомления NSApplication.
Я бы предпочел опубликовать событие без какой-либо информации об окне (в otherEventWithType), могу ли я просто проигнорировать эту часть?
Тогда я бы хотел переписать функцию sendEvent NSApplications, подобную этой:
- (void)sendEvent:(NSEvent *)event
{
//this is my custom event that simply tells NSApplication
//that my app needs an update
if( [event type] == NSApplicationDefined)
{
myCppAppPtr->loopFunc(); //only iterates once
}
//transform cocoa events into my own input events
else if( [event type] == NSLeftMouseDown)
{
...
myCppAppPtr->loopFunc(); //also run the loopFunc to propagate input events
}
...
//dont break the cocoa event chain
[super sendEvent:event];
}
извините за длинный пост, но это меня немного беспокоит, так как я действительно не доволен тем, что я нашел по этому вопросу до сих пор. Так ли я размещал и проверял пользовательское событие внутри NSApplication, и считаете ли вы, что это правильный подход для интеграции какао в существующий цикл запуска без опроса?