Queued Message Handlerをよりうまく使うには ~メッセージキューの作成~

Queued Message Handler (QMH) のテンプレートでメッセージキューの作成/追加/削除する場合、Create All Message Queues.viを編集する必要があります。しかし、メッセージキューの数を変えるたびに手動でCreate All Message Queues.viを編集するのも手間です。配列やマップにすればそのような手間はなくなりますが、クラスタの名前でバンドル/バンドル解除が使えないことによって、メッセージキューの集合に含まれるキューの全部を配線から把握することが困難になります。ここでは何かうまい方法がないかを検討してみました。

一番手っ取り早い方法

一番手っ取り早いのは、Message Queuesのタイプ定義クラスタを配列にして、その配列の要素数だけメッセージキュー作成+Initializeのエンキューをする方法です。

配列の要素数だけメッセージキューを作成

この方法を利用する場合、次の条件があります。

  • メッセージキューの型はすべて同じ

メッセージキューの型にはいくつかのパターンがあると思います。

例

  • メッセージ:文字列や列挙体
  • データ:バリアントや文字列

これらをどう組み合わせてもいいですが、上記のブロックダイアグラムではクラスタを配列に変換しているため、すべてのメッセージキューで同じ型である必要があります。列挙体を用いる場合、すべてのメッセージ処理ループ(Message Handling Loop、MHL)で1つのタイプ定義列挙体を使いまわすならForループで繰り返し処理できますが、MHLでメッセージが変わるのが一般的で各MHLにメッセージのタイプ定義列挙体を持たせたいと考えた場合は、自動化は難しいです。この点から、メッセージは文字列のほうがいいと思います。文字列にはタイプミスという欠点がありますが、これによるバグは開発段階で見つけるものであり、一旦完成すれば動作面で大きな差はないと考えていいです。データ型は文字列でもバリアントでもいいですが、QMHのテンプレートではメッセージ/データに文字列/バリアントという組み合わせを使うので、テンプレートから変えないのが楽です。

この方法では、Forループで必要な数だけメッセージキューを作ってInitializeをエンキューするのは簡単ですが、問題はForループから出力されるメッセージキュー配列をどうやってタイプ定義クラスタにするかです。Forループの回数を決めるのにクラスタから配列に変換したので、Forループの後で配列からクラスタに変換すればよさそうですが、それはあまり有効ではありません。それは、配列からクラスタに変換する場合、変換後のクラスタの要素数をあらかじめ決める必要があるからです。

配列からクラスタに変換するときの要素数

この要素数は開発者が固定値を決めるもので、配列サイズとは関係ないものになります。この数はブロックダイアグラムを見ただけでは分からないので、私は使わないです。

この章の最初のブロックダイアグラムでは、クラスタに要素を入れるときに名前でバンドルではなく通常のバンドルを使っています。多くの場面では名前でバンドルを使ったほうがブロックダイアグラムを見ただけでどの要素に入れたか可視化できるので便利ですが、ここでは通常のバンドルのほうが拡張しやすいと考えています。そう考える理由は以下の通りです。

  • 要素を入れる順番は関係なく、過不足なく入れることが重要。
  • 名前でバンドルの場合、人が要素を選ぶことで重複や抜けが発生する可能性がある。
  • 通常のバンドルの場合、メッセージキューを増やすと入力が増えたことがブロックダイアグラムを見て分かる。名前でバンドルの場合はクラスタの要素数が増えても変化がなく、要素数が増えたことが分かりにくい。
通常のバンドルと名前でバンドル

通常のバンドルの場合はすべての要素が入力に表示されますが、名前でバンドルの場合は開発者がドラッグ&ドロップで増やさないといけません。メッセージキューを増やした場合、通常のバンドルでは入力が増えたことが見て分かるので、入力を忘れるというリスクを減らせます。1つずつ配線するのが面倒そうに見えますが、これも実は簡単にやることができます。クイックドロップのショートカットを使います。

クイックドロップ→Ctrl+W

まず、配列のほうを要素数以上に出力するようにします。とりあえず多ければいいです。そのあと、配列要素とバンドルを選んだ状態でCtrl+Spaceでクイックドロップを召喚します。クイックドロップのダイアログがある状態でCtrl+Wをおすと、不足分が自動配線されます。あとは、配列要素の超過分をドラッグ&ドロップでなくせばOKです。クイックドロップのショートカットを使いこなせればかなり楽になります。

プログラム的にメッセージキューを追加できないか?

結論を言うと、VI Scriptingを使えばできます。実際に、こんな感じのVIを作れば、メッセージキューをクラスタに追加できます。

Create All Message Queues.vi
Index ArrayとBundleを配線するVI Script

…VI Scriptを見るとかなり難しそうです。Create All Message Queues.viについては「一番手っ取り早い方法」で取り上げたものとほとんど同じですが、エラーケースストラクチャ/Index Array/Bundleにラベル名をつけています。VI Scriptではこのラベル名をもとに使用するノードを特定するので、ラベル名は必須です。このVI Scriptでは次のことをしています。

  1. Create All Message Queues.viのブロックダイアグラムにある壊れた配線を除去
  2. Create All Message Queues.viからError Case Structureという名前のケースストラクチャを取得し、” No Error “という名前のケースを取得。
  3. ” No Error “ケース内にある”Index Array”という名前のノードを取得。
  4. “Index Array”の出力数をクラスタの要素数と同じにする。その後、このノードの出力端子ノード配列を出力する。
  5. ” No Error “ケース内にある”Bundle”という名前のノードを取得し、入力端子ノード配列を出力する。
  6. “Index Array”の各出力端子と”Bundle”の各入力端子を自動配線する。

これは「一番手っ取り早い方法」をVI Scriptでやったことに相当します。ここまですれば、メッセージキューを増やしたり減らしたりしてもVI Scriptを実行するだけでCreate All Message Queues.viの修正が終了しますが…VI Scriptを作る労力に見合うかはメッセージキューの作成や変更の頻度次第です。もちろんVI Scriptを1回作れば何度でも使えますが、そこまでするかは謎です。私はここで作ったので使いまわす予定です。

右クリックメニューにできるか?

結論を言うと、たぶんできます。Create Shortcut Menu Plug-In From Template.viというVIがあって、そこから右クリックで使うメニューを作れます。まあでも、そこまでするか?とは思いますし、私は右クリックメニューを作ったことがありません。そのうち作るかもしれないですし、作らないかもしれません。…作らないと思います。

まとめ

今回は、QMHのメッセージキューを増やしたときにどうやれば効率的にメッセージキューの作成とInitializeメッセージのエンキューができるかを紹介しました。VI Scriptを1回作ればあとはそれを使えばいいですが、正直なところ面倒なので、Forループで繰り返し処理した後でバンドルで入れたほうが楽だと思います。これはあくまで私の個人的な手法ですが、参考になるところがあれば幸いです。

Github

GitHub – taacranzk/TN_QMH_Modification: LabVIEWのQueued Message Handlerをベースに手を加えたものです。
LabVIEWのQueued Message Handlerをベースに手を加えたものです。. Contribute to taacranzk/TN_QMH_Modification development by creating an ac…

タイトルとURLをコピーしました