私はOSXでCocoaを既存のc/c ++メインループと一緒に使用しようとした最初の人ではないことを知っていますが、これまでに出会ったソリューションはあまり好きではないので、別のアイデアを思いつきました。 d話し合いたい。私が見つけた最も一般的な方法(glut、glfw、SDL、そしてQTでも)は、ポーリングを使用してNSApplications runメソッドを置き換え、イベントを自分で処理することです。
nextEventMatchingMask:untilDate:inMode:dequeue:
これには、新しいイベントがあるかどうかを確認するために常にポーリングする必要があるため、CPUが実際にアイドル状態になることはないという大きな欠点があります。さらに、NSApplications run関数内で行われているのはそれだけではないため、この代替品を使用してください。
だから私がやりたいのは、カカオのrunLoopを無傷に保つことです。独自のタイマーメソッドがc++で実装されていると想像してください。これらのメソッドは通常、メインループ内で管理および起動されます(これは例としてのほんの一部です)。私の考えは、すべてのループ部分をセカンダリスレッドに移動し(NSApplicationの実行は、私の知る限りメインスレッドから呼び出す必要があるため)、カスタムイベントを派生バージョンのNSApplicationに投稿して、その中で適切に処理することです。 sendEvent:メソッド。たとえば、タイマーがc ++ループの発火で測定された場合、NSApplicationにカスタムイベントを送信します。NSApplicationは、アプリケーションのloopFunc()関数(メインスレッドにも存在します)を実行し、c++イベントチェーンにイベントを適切に送信します。 。それで、まず第一に、これは良い解決策になると思いますか?そうであれば、
otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:
次に、次のようなものを使用します。
[NSApp postEvent:atStart:]
NSApplicationに通知します。
(otherEventWithTypeで)ウィンドウに関する情報なしでイベントを投稿したいのですが、その部分を単に無視できますか?
次に、次のようなNSApplicationssendEvent関数を上書きすることを想像します。
- (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内のカスタムイベントを投稿して確認する方法ですか。これは、ポーリングせずにココアを既存の実行ループに統合するための有効なアプローチだと思いますか?