I know, that I am not the first one to try to use Cocoa on OSX together with an existing c/c++ main loop, but I am not really liking the solutions I came across so far so I came up with a different idea I'd like to discuss. The most common way I found (in glut, glfw, SDL and also QT I think) is to use polling to replace NSApplications run method and process the events yourself with this:
nextEventMatchingMask:untilDate:inMode:dequeue:
This has the big disadvantage that the cpu is never really idle since you have to poll the whole time to check if there are any new events, furthermore its not the only thing going on inside NSApplications run function, so it might break some details if you use this replacement.
So what I'd like to do is to keep the cocoa runLoop intact. Imagine you'd have your own timer methods implemented in c++ which would usually be managed and fired inside your main loop (this is just a small part as an example). My idea would be to move all my looping portions to a secondary thread (since NSApplication run needs to be called from the main thread as far as I know), and then post custom Events to my derived version of NSApplication that handles them appropriately inside its sendEvent: method. For instance if my timers measured in my c++ loop fire, I'd post a custom event to NSApplication that in turn runs loopFunc() function of my application (residing in the mainthread as well) which appropriately sends the events down my c++ event chain. So first of all, do you think this would be a good solution? If yes, how would you implement that in cocoa, I only found this method inside the NSEvent Reference to post custom NSApplicationDefined events:
otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:
and then use something like:
[NSApp postEvent:atStart:]
to notify NSApplication.
I'd rather post an event without any information about the window (in otherEventWithType), can I simply ignore that part?
Then I'd imagine to overwrite NSApplications sendEvent function similar to this:
- (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];
}
sorry for the long post, but this has been bothering me quite a bit since I am really not happy with what I found about this subject so far. Is this how I'd post and check for a custom event inside NSApplication, and do you think this is a valid approach to integrate cocoa into an existing runloop without polling?