Mind 9 の開発背景

# はじめに

　Mind Version 9 （Mind9）の開発も大詰めに来ています。なんとか年内にリリースしたいと思っています。着手は2022年の8月だったので2年4カ月も経過してしまいました。Mindのプロジェクトとしては最長です。初版Mind（1985年）のときは、グラフィックライブラリや通信ライブラリなどすべて含めても8カ月ぐらいでしたので、それと比べるとかなり長いです(^^;

# GUI機能の追加

　Mind9の大きな機能追加としてGUIアプリケーション（ウィンドゥを開くアプリケーション）を作成できることが挙げられます。
　GUIエンジンとして Mind7 でも使っていたTcl/Tkを再び採用しました。Mind7の時はTcl/Tk 8.3という版でしたが今回はTcl/Tk8.6になります（Tcl/Tkは最近9が出ているらしいのでそのうち切り替えたいと思います）。

　以前のMind7ではGUIを使うためにかなりの部分でTcl/Tkレベルのスクリプトを書く必要がありましたが、その形態はいわば、プログラム言語の中に別のプログラム言語を抱えるようなもので、自分としてもいまひとつの感がありました。Mind9ではTcl/Tkスクリプトは完全に隠されており、MindだけでGUIアプリを記述できるようになりました。

　最近は他のプログラム言語でもGUIエンジンとしてTcl/Tkを使うようになっているようです。Python のGUIライブラリ Tkinter が有名で、ほかにもRuby/Tkなどもあるようです。他言語では明らかにTcl/Tkのコマンドに１対１で対応する実装のようですが、Mind9ではプログラムを簡略化するため、より抽象的な表現で済むよう（Tcl/Tkのことをまったく知らなくて済むよう）介入をしています。ソースコードを見ただけではTcl/Tkが使われていると思えないぐらいです。

　Mind9で書いた簡単なサンプルプログラムのソースと画面、その次にMind7で書いたものも併せてお見せします。

（Mind9）
```mind:hellowin.src
メインとは
　　　　　　　　ボタン１は	変数
　　　　メインウィンドゥで　ボタンのＩＤを取得し　ボタン１に　入れ
　　　　「これを押すと終了します」を　ボタン１に　テキストを設定し
　　　　実行終りの　実行情報を　ボタン１に　イベント処理を登録し
　　　　ボタン１を　有効化して配置する。

```
![snap-hwllowin-mind9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166411/08ed52fa-774a-fc99-4c0d-6d2b4d016547.png)

（Mind7）（古いMindです。生のTcl/Tkコードを書く個所があります）
```mind:hellowin.src

イベント分岐とは　本定義　（パラメータ・・、パラメータ数、イベント名　→　・）
	文字列事例をとる
		"exit"なら　実行終り
		例外なら　　イベント引数を捨て
	事例終り。

メインとは
	「button .b1 -text {これを押すと終了します} -command {mindcmd exit}」を　評価し
	「pack .b1」を　評価する。
```

![snap-hwllowin-mind7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166411/313f9f47-de52-5cd4-22d3-b0030f8dd283.png)

　一方でコンパイラはMind8のそれとあまり変わっておらず、GUI向けとしてコンパイラに機能追加したのは起動オプションの追加などごくわずかです。したがってGUI機能のすべてはライブラリ管轄となります。

　ユーザ作成のアプリケーションを配布するときは Tcl/Tkのランタイムライブラリ（GUIエンジン）を同梱する必要がありますが、アプリケーションのフォルダ内に同梱できるため一般的なアプリケーションプログラムの配布とそれほど変わりません。アプリの配布を受け取った人はTcl/Tkを別途インストールする必要はなく、自己完結型のパッケージソフトとして扱えます。

# MindとTcl/Tkとの連携はこんな感じです

　以下はGUIライブラリを作ったことの自身の振り返りとして、MndのプログラムとGUIエンジンであるTcl/Tkモジュールとのインターフェースについてお話します。（実はMind7のときからこのような手法をとっていたので当時とあまり変わっていません）

　Mind記述アプリ
　　→Mind記述のMindランタイム
　　　→C記述のMindランタイム(カーネル)
　　　　→DLL呼び出し→Tcl/Tkモジュール

という手順でMindからTcl/Tkの呼び出しを行います。
　イベントが発生したときは上記を逆にたどり、最終的にMind記述の処理単語が動いてイベント処理をおこなう形となります。

　Tcl/TkはDLL形態のモジュールとして提供されていて、ユーザ作成のアプリからTcl/Tkを呼び出すインターフェースが備わっており、非常によくできた仕組みだと思っています。
 　したがって「言語のランタイムの配下にTcl/Tkを組み入れる」ことはそれほどの困難はありませんでした。
　とはいえ、アプリケーションを主としてTcl/Tkを従とする組み方は書籍も含めて文献が非常に少なく、Mind7のときに一度やっているはずなのに試行錯誤が必要でした。
　Tcl/Tkモジュールを多少カスタマイズしソースからコンパイルし直すこともやっています。
　この記事を読まれている方は、MindにTcl/Tkを組み入れることなぞ特別なことで自分には関係ないと思われるかも知れませんが、実質的には C（C++でもほぼ同じ）で書いたアプリケーションにTcl/Tkを組み入れることに等しく、組み入れる方法は有用だと思いますので、いつかは記事にしてみたいと思っています。
   
# IDのこと

　先のMind9で書いた hellowin.src というソースですが、以下がポイントです。

```
　　　　　　　　ボタン１は	変数
　　　　メインウィンドゥで　ボタンのＩＤを取得し　ボタン１に　入れ
```

　上記はTcl/Tkレベルで言えば以下のようなコードに対応します。

```
button .button1
```

　Tcl/Tkではウィジェット（GUIのパーツのこと）を作成するにはボタンなら「button」というコマンドを発行します。その第１引数がウィジェット名であり、他のウィジェットと区別できれば任意の綴りでも良いというものです。上のコードでは .button という名前を指定しています。
　しかしMindのプログラムとして見れば（何でもいいと言われても）ウィジェット名を考えるのは”余計な作業”てしかなく、Mind9のライブラリではウィジェット名は自動生成としています。その代わりに整数値の”ID”を使います。このIDで以降の操作を行います。

　先に挙げた hellowin.src にあるように、ボタンに表示するテキストと、それを押したときのイベント処理の指定はボタン生成の行とは別の行として記述しています。Tcl/Tkではパラメータ類はすべて buttonコマンドの引数として一気に記述しますが、ここが生のTcl/TkとMindで違うところです。
　hellowin.exe を走らせると最終的に以下のTcl/Tkコードが実行されます。

 ```
button .wbtn002 -text {これを押すと終了します} -command {mindcmd MC_801A}
pack .wbtn002
```
 
　実はIDを使うという手法は Mind for Androidのとき初めて導入し（そのときはJavaのAPIとやり取りをするため）、かなり良い方法であることが分かったので Mind9 でも使いました。Androidのときの経験が役に立ったことになります。