メインループ前回は、Blenderユーザから見てわかりやすいオペレータ実行時の処理を題材にしてBlenderの内部処理を説明しました。今回はプログラムを書く人の視点を考え、プログラムの最初に実行されるmain関数の処理がどのソースコードに記載されているのか確認したあと、main関数の延長で実行されるアプリケーションのメインループで行われていることを見ていきたいと思います。main関数が宣言されています。関数を呼び出してアプリケーションのメインループに入ります。本記事では、Blenderの初期化処理には触れずに、メインループの中身を見ていきたいと思います。ループでアプリケーションのメインループに入ります。メインループに入ったあとは、ユーザがBlenderを閉じない限りループ内の処理を繰り返します。Graphについて理解する必要があります。2.8より導入された、オブジェクト間の依存関係を表現したグラフです。Graphを使って更新したオブジェクトに依存するオブジェクトのみを更新することで、処理量を少なくすることができます。Graphの評価が完了していない状態で、ユーザからのオペレータが実行できないようにするためです。Graphの評価が完了していない状態でオペレータが実行されてしまうと、正しい描画結果が得られなくなってしまいます。関数の詳細とともにまた別の場所で詳細を見ていきたいと思います。関数は、GHOST経由でOSで発生したイベントを取得します。Toolkitの略です。GHOSTが存在することで、BlenderはさまざまなOS上でアプリケーションを動作でき、かつOSに依存した実装をGHOST内に閉じ込めることができています。GHOSTについては、別の機会に詳しく内部構造を解析した結果をまとめたいと思います。関数の処理を見てみましょう。ウィンドウマネージャに登録されたタイマからのイベントを扱う。関数は、メインスレッド以外から呼び出されることを禁止しています。これは、GHOSTを使ったイベント制御をマルチスレッドで行う利点がないことと、グローバル変数を積極的に利用しているGHOSTの処理で、マルチスレッドに起因するバグを発生させることを防ぐためであると考えられます。関数は、OS上で発生したイベントを取得します。OS上で発生したイベントは、Windows/Mac/Linuxなどそれぞれで異なる手続きでイベントを扱わなくてはならないのですが、このあたりの処理の違いはGHOSTが隠蔽してくれます。関数の役割は、OS上で発生したイベントをBlenderのウィンドウにOSに依存しない形で登録することです。関数は、ウィンドウマネージャに登録されたタイマからタイマイベントが発生しているかどうかを確認します。OS上のイベントが発生していなく、ウィンドウマネージャに登録されたタイマからもイベントが発生していない場合は、5msだけスリープします。このように、イベントが発生していたらイベントの結果を即座に反映してインタラクティブ性を失わないようにするとともに、イベントが発生していない場合はCPUを休ませるような処理になっています。関数によって処理されます。関数は長い関数ですが、関数内で行っている処理を簡単にまとめると次のようになります。返したときに設定される値です。APIの観点からも説明していますので、こちらも参考にしてみてください。返すと、その後のイベントハンドラの処理が呼ばれなくなることがわかります。関数などによってイベントが処理されると、Blender内のデータが変化する場合があります。Blender内のデータが変化したことで再描画などが必要だと判断されると、Notificationとしてウィンドウマネージャに登録されます。関数は、ウィンドウマネージャに登録されたNotificationを処理するための関数です。関数が行っていることは単純で、スクリーン、エリア、リージョンの順にNotificationを処理するだけです。関数で再描画する対象を決めることが主になります。関数にて再描画が必要とされたスクリーン、エリア、リージョンを再描画します。関数によって描画処理を行います。関数で呼び出されて描画されます。関数によりフロントバッファとバックバッファをスワップして終了です。これでメインループの1ループ分の処理が完了したことになります。まとめると、Blenderのメインループでは以下の処理を繰り返していると言えるでしょう。OSやウィンドウマネージャに登録されたイベントを取得し、各ウィンドウが持つイベントキューに追加する各ウィンドウが持つイベントキューのイベントを処理するイベント処理によって再描画が必要となったスクリーン、エリア、リージョンに再描画フラグを立てる再描画フラグが立っているスクリーン、エリア、リージョンを描画するおわりにBlenderの主要な処理であるメインループについて解析してみました。メインループの処理を解析したことにより、Blenderの全体像が明らかになってきました。この中で一番の発見であったのは、UIを持つアプリケーションにおいて頻繁に利用されるアーキテクチャ「MVCパターン」に従って、Blenderが実装されているということです。アーキテクチャが理解できたことで、今後のソースコードの解析が捗りそうです。派生したクラス)の登録処理について解析したいと思います。