おはようございます、高木です。

今回から、いよいよラッパーライブラリの具体的な内容について書いていくことにします。
まだ、ライブラリが完成したわけではないので、この連載では結果を解説するのではなく、試行錯誤する過程をそのまま記録していけたらと考えています。

ライブラリを実際に作っていくにあたって、クライアントコードがどんな感じに書けるのか、そのイメージをはっきりと決めておく必要があります。
その前に、典型的なTcl/Tkのスクリプトについて、まずは見ておくことにしましょう。

上のコードは、非常に簡単なTcl/Tkのスクリプトです。
これをwish(Tcl/Tkのシェル)を使って実行すると、exitと書かれたボタンを1つ持ったウィンドウが表示されます。
そして、exitボタンを押すとウィンドウが閉じ、プログラムは終了します。

以前紹介したことがあるC++/Tkでは、このコードをほぼそのままのイメージでC++で記述できるようです。

これはこれで面白いのですが、今回作ろうとしているラッパーライブラリでは、C++のコードとしてより自然な形になることを目指しています。
とはいえ、元になるTcl/Tkのスクリプトからあまりもかけ離れてしまうのもどうかと思います。
そこで、こんな風にできないか考えてみました。

Tcl/Tkでは、ウィジェットを作成する際に、-で始まるオプションをいくつも指定できます。
C++/Tkは、これを演算子の多重定義で実現しています。
けれども、それはC++のコードとしては決して自然とはいえません。

そうではなく、せっかくC++14を使うのだから、initializer_listを使ってオプションを好きなだけ指定できないか考えてみたのです。
initializer_listの要素にはTcl_Obj*のラッパーを指定してやれば、なんかいい感じにまとまりそうです。

textやcommandなどのウィジェットオプションは、それぞれ個別に定義してやる必要があるのでちょっと手間はかかりますが、そこは頑張るべきところでしょう。
もちろん、文字列で直接オプションを指定できるようにもしておくことで、将来的なTcl/Tkのバージョンアップにも対応できるようになります。

ここでもう少し考えないといけないことがあります。

Tcl/Tkはインタープリタを複数作ることができます。
これに対応するには、都度、何らかの形でインタープリタを指定してあげなければなりません。

上記のコードに現れるrootというのは、メインウィンドウを表す変数を想定しています。
インタープリタごとにメインウィンドウはひとつずつしか作れませんので、このrootを使ってインタープリタとひも付けてあげることができそうです。

ただ、このようなGUIがらみのコードであればメインウィンドウがあるのでよいのですが、次のようなTclスクリプトに対応するのは一工夫いりそうです。

このように、メインウィンドウがない場合は次のようにせざるを得ないでしょうね。

afterをinterpクラスのメンバにしてもいいのですが、それをやるとどんどんinterpクラスが肥大化してしまいます。
さすがにそれは嫌なので、evalメンバ関数を用意して、実際のコマンドは文字列で渡すようにしています。

上記のコードで、{ puts [incr x] }の部分はもう少しどうにかすべきだと思います。
できれば、ここでラムダ式を使うなどして、ネイティブコードとシームレスにつなげられるようにしたいものです。
その話は、またあらためて行うとして、今回はこの辺にしておきましょう。