良い答えではないことはわかっていますが、独自の単純なデータフロー フレームワークを作成する必要があります。
私はプロトタイプの DF サーバーを (私の友人と一緒に) 作成しましたが、これにはまだ実装されていない機能がいくつかあります。メッセージで整数データとトリガー データしか渡すことができず、並列処理をサポートしていません。この作業は省略しました。コンポーネントのプロデューサー ポートには、初期化時に設定されたコンシューマー ポートへの関数ポインターのリストがあり、それを呼び出します (リストが空でない場合)。そのため、イベントが発生すると、コンポーネントはデータフロー グラフのツリーのようなウォークスルーを実行します。整数とトリガーで動作するため、非常に高速です。
また、1 つのコンシューマー ポートと 1 つのプロデューサー ポートを持つ奇妙なコンポーネントを作成しました。これは単にデータを通過させるだけですが、別のスレッドで行います。コンシューマー ルーチンは、データを配置してプロデューサー側スレッドにフラグを設定するだけなので、すぐに終了します。汚いですが、それは私のニーズに合っています。ツリーウォークの長いプロセスを切り離します。
お気づきかもしれませんが、これは、グラフのサイズが問題にならない、迅速なタスクのための低トラフィックの非同期システムです。
残念ながら、あなたの問題は私のものとは多くの点で異なります.1つのデータフローシステムが別のデータフローシステムと異なる可能性があるのと同じように、同期、並列、ストリーム処理ソリューションが必要です。
DFサーバーの最大の問題はディスパッチャーだと思います。同時実行性、衝突、スレッド、優先度...前述のとおり、私は問題をスキップしただけで、解決していません。あなたもそれをスキップする必要があります。また、他の問題もスキップする必要があります。
発車係
同期 DF アーキテクチャの場合、特別な場合を除き、すべてのコンポーネントをサイクルごとに 1 回実行する必要があります。それらには単純な前提条件があります: 入力データが利用可能か? そのため、コンポーネントをスキャンして、データが利用可能な場合は、それらを無料の呼び出し元スレッドに渡す必要があります。それらすべてを処理した後、処理されていない N 個のコンポーネントが残ります。リストを再度処理する必要があります。2 回目の処理の後、M が残ります。N == M の場合、サイクルは終了します。
コンポーネントの数が 100 未満であれば、ある種の同じものが機能すると思います。
バインディング
そうです、バインドの最良の方法はビジュアル プログラミングです。エディターを終了するまで、構成のようなコードは、次のような insetad を使用する必要があります。
// disclaimer: not actual code
Component* c1 = new AddComponent();
Component* c2 = new PrintComponent();
c2->format = "The result is %d\n";
bind(c1->result,c2->feed);
書きやすい、読みやすい、その他の希望は?
メッセージ
コンポーネントのポート間で純粋な raw パケットを渡す必要があります。プロデューサーとコンシューマーのポートのポインターのペアを含み、「ディスパッチャー」が使用する処理済みフラグを含むバインディングのリストのみが必要です。
通話の問題
問題は、プロデューサがコンシューマ ポートを呼び出すのではなく、コンポーネントを呼び出す必要があることです。すべてのコンポーネント (クラス) 変数と発火はコンポーネント内にあります。そのため、プロデューサーはコンポーネントの共通エントリ ポイントを直接呼び出してコンシューマーの ID を渡すか、ポートを呼び出して、それが属するコンポーネントの任意のメソッドを呼び出す必要があります。
したがって、いくつかの制限に耐えることができる場合は、先に進んで軽量フレームワークを作成してください。それは良い仕事ですが、小さなコンポーネントを書いて、それらがどれほどスマートに接続されて素晴らしいアプリを構築できるかを見るのは、究極の楽しみです.
さらに質問がある場合は、お気軽にお問い合わせください。ここで「データフロー」キーワードをスキャンすることがよくあります。
おそらく、プログラムのより単純なデータフローのモデルを見つけ出すことができます。