無料ブログはココログ

« 2012年4月 | トップページ | 2013年6月 »

2013年5月

2013年5月16日 (木)

レイアウト系

レイアウトやビューなど表示のごく基本のところをまとめておく。

Javaのオブジェクト指向コーディングをMindのコーディングにどうやって対応させるかの問題にいきなり直面した(^^;。
まずレイアウト系のオブジェクトの扱いだが、たとえばJavaでは、

    layout1 = new LinearLayout( this );

などと書いて「layout1」という名前のリニアレイアウトのインスタンスを作るが、このオブジェクト(Java内部ではたぶんポインタ)をMindへ渡されても何も使い道が無い。さらには、Javaレベルの「layout1」なる名前もまたMind側からは見えない/見たくないものである。そもそもMindでプログラムを書くのだから名前はすべてMind側で(たとえば適当な日本語名で)決めるべきものである。
結果として以下のようにした。

  ------------------------------------------------------------------------
  (Mind)
          _レイアウトは   レイアウト
    ~略~
    リニアレイアウトを生成し _レイアウトに 入れ

                                          (注:変数名の頭にアンダースコアを付ける
                                               のはMindのルールではなく単に筆者の
                                               好みである。局所変数と大域変数とで
                                               区別がつきやすいようにしている)
                          ↓
  (Java)
          private  LinearLayout[] linearLayouts = new LinearLayout[20];
    ~略~
    linearLayouts[seqno] = new LinearLayout( this );
  ------------------------------------------------------------------------

 Mindの「リニアレイアウトを生成」でリニアレイアウトのインスタンスを作ることにする。実際には単純に1から始まる整数(通し番号)を生成するだけであり、これで個々のリニアレイアウトを識別する。
 JavaではMindから渡された通し番号(上記で"seqno")を添え字としてリニアレイアウトのインスタンスを配列として管理する。先に書いたようにJava側で個別インスタンスに名前を付けても使い道が無いが配列要素は無名なのでちょうど良い。

 ビューについても同様で以下のようにした。
  ------------------------------------------------------------------------
  (Mind)
         _案内文は       ビュー
    ~略~
    テキストビューを生成し _案内文に 入れ

                          ↓
  (Java)
          private TextView[] textViews = new TextView[20];
    ~略~
    textViews[seqno] = new TextView( this );
  ------------------------------------------------------------------------

 Mind側ではレイアウトの時と同様、「テキストビューを生成」によって通し番号を生成しその番号で管理する。またテキストビューのほかにボタンやチェックボックスなど他のビュータイプも一括して操作できるよう、それらを表すタイプ情報も含めて管理している。(実は先のレイアウトもMindでは複数のレイアウトタイプを番号で識別している)

 レイアウトとテキストビューをそれぞれ1つ扱うMindのプログラムは次のようになる。
    ----------------------------------------------------------------------------
    メインとは
                    _レイアウトは  レイアウト
                    _案内文は      ビュー
      (レイアウト)
            リニアレイアウトを生成し  _レイアウトに  入れ
            垂直を                    _レイアウトに  子の追加方向を設定し
            _レイアウトを  レイアウトをアクティビティに追加し
      (ビュー)
            テキストビューを生成し  _案内文に  入れ
            18を                  _案内文に  文字のサイズを設定し
            「こんにちは」を        _案内文に  文字を設定し
            _案内文を  _レイアウトに  ビューを追加し
            。
    ----------------------------------------------------------------------------

  上のソースコード末尾の「ビューを追加」について補足する。
 引数は <元ビュー> と <先レイアウト> だが、Mind側での型管理が無いとすると、たとえば
    ----------------------------------------------------------------------------------
    _テキスト1を  _リニアレイアウト1に    テキストビューをリニアレイアウトに追加し
    _テキスト1を  _フレームレイアウト1に  テキストビューをフレームレイアウトに追加し
    ・・・
    _ボタン1を    _リニアレイアウト1に    ボタンビューをリニアレイアウトに追加し
  _ボタン1を  _フレームレイアウト1に  ボタンビューをフレームレイアウトに追加し
    ・・・
    ----------------------------------------------------------------------------------

のように、全組み合わせの処理単語(関数)を設置する必要が出て、これはいかにも苦しい。
Mind側に最低限の型管理を導入することできれいなコードになるようにした(1つの「ビューを追加」で済む)



参考URL: 「日本語プログラミング言語Mind」 (スクリプツ・ラボ)

2013年5月 7日 (火)

AndroidでMindをどうやって動かすか(2)

 MindではMコードがオブジェクトコードの実体であるため、当然だがMコードファイル(.mco)の扱いが重要となる。
 しかし Android OS から見た狭義のプログラムは JavaのクラスファイルとC(JNI)の共有ライブラリの2つであり、当然だがMコードは関与されない。そのためファイルの設置や読み出しは自前で行う必要がある。

 まず設置については、パッケージ(.apk)の中にMコードファイルを含めておき、アプリ起動時にそれが自動展開されるのが良いのだが、調べたところこの目的に合致したのが assets/ ディレクトリだった。
 assets/ ディレクトリは元々、画像や音楽ファイルを置くような用途を想定されているらしく、Read Only なアクセスとなるがMコードへは書き込みは無いためその点も都合が良い。また、Mindで使うUnicodeの変換テーブルなどのデータファイルもここに置くことにした。
 読み出しについては、MコードのロードはC管轄なのでCで読めると良かったのだがどうも困難なようで(Cから普通のファイルのようにはアクセスできない)、仕方なくJavaで読み出したあと、Cの初期化関数呼び出し時に渡すようにした。

 開発時のディレクトリ構成(プロジェクトフォルダ内)は以下のようになる。

MindSample/
|
|-- AndroidManifest.xml
|
|-- assets                              ←プログラムからロードするファイルはここ
|   |-- bin
|   |   |-- euc-uni-encode.bin              ←Unicodeテーブル
|   |   `-- uni-euc-decode.bin
|   `-- mco
|       `-- main.mco                        ←Mコードファイル(Mindプログラム本体)
|
|-- bin
|   |-- MindSample-debug.apk
|   ~略~
|   |-- classes
|   |   `-- jp
|           `-- co
|               `-- scriptslab
|                   `-- MindSample
|                       |-- MindSampleActivity.class
|
|-- jni                                 ←Mindのカーネルはここへ
|   |-- 0ker.c
|   |-- 1ker.c
|   |-- 2ker0.c
|   |-- 2ker1.c
|   ~略~
|   |-- sources
|   `-- unixdep.c
|
|-- libs                                ←カーネルの生成場所
|   `-- armeabi
|       `-- libdllker.so
|
|-- mind4andr                           ←Mind記述のプログラム
|   |-- andrlib                             ←ランタイムライブラリ(2)
|   |   |-- andr_basicoutput.src
|   |   |-- andr_init.src
|   |   ~略~
|   |   `-- obj
|   |-- app                                 ←ユーザ記述のMindプログラム
|   |   |-- sample.src
|   |   `-- obj
|   |-- file                                ←ランタイムライブラリ(1)
|   |   |-- asm_osdep.src
|   |   |-- asmequ.src
|   |   ~略~
|   |   `-- obj
|   `-- lib
|       |--
|       `--
|
|-- obj
|   `-- local
|       `-- armeabi
|           |-- libdllker.so
|           `-- objs
|               `-- dllker
|                   |-- dllker.o
|                   |-- dllker.o.d
|                   |-- osfunc.o
|                   `-- osfunc.o.d
|
|-- res
|   |-- layout                          ←res/layout/main.xml は置かない
|   `-- values
|       `-- strings.xml
|
`-- src
    `-- jp
        `-- co
            `-- scriptslab
                `-- MindSample
                    `-- MindSampleActivity.java


 assets/ 以下では、サブディレクトリ mco/ にMコードを格納し、bin/ にはUnicode変換用のテーブルを置いた。単にここに置いておけばビルド時に .apk に含めてもらえる。

 jni/ フォルダにはMind用のC記述プログラム(以下、単にカーネルと言うことにする)を格納している。カーネルのオブジェクトファイル群は obj/ 配下に格納され、そのうちメインのオブジェクトである libdllker.so がJava側ビルド時に libs/ に複写されこれが最終的な .apk に含められるようだ。
 libs/armeabi/ という名称から分かるように、ARM系CPU専用となっているため他のCPUでは走行できない点に注意が必要だ。他のCPUも別のカーネルを用意すれば良いのだと思うが今のところはARM向けということで進むことにする。

 mind4andr/ フォルダへはMind記述のプログラムを格納する。
 ライブラリの順位は低いほうから file → andrlib → app である。app/内にユーザ記述のMindソースを置くことにしたがこのあたりはこの先変更するかも知れない。ソケット(通信)・グラフィック・その他のためにさらに別ディレクトリが必要になると思うが追々やっていくことにする。

 res/ フォルダでは、Androidのプログラミングで必ず登場する res/layout/main.xml(レイアウトを記述するファイル)はMindでの開発では使わない。レイアウトはすべてプログラム記述とするためである。これに関係するが、書籍やWebサイトでの多くのサンプルプログラムはレイアウトを main.xml に記述しており、プログラム記述のものを探すのに苦労した。



参考URL: 「日本語プログラミング言語Mind」 (スクリプツ・ラボ)

2013年5月 3日 (金)

AndroidでMindをどうやって動かすか(1)

 Mindは(Windows,Linuxとも)だいぶ以前から、コンパイラが「Mコード」と呼ぶ中間コードを生成し、(Mindで言う)「カーネル」の中にある「ディスパッチャ」と呼ぶごく小さなルーチンがそれを逐次実行する方式になっている。
 たとえばMindのオブジェクトコードは拡張子が .mco というバイナリファイルになっていおり、OSから見ると単なるデータファイルのように見えるがこれがプログラムの本体である。

 検討初期からAndroidでも基本的にこの機構のまま行けるだろうと思ったが実際その通りだった。
 ちなみに現段階ではコンパイラはAndroid向けを別途作ったわけではなく、LinuxのMindコンパイラをそのまま使っている。MコードがOS非依存になっているおかげである。(将来的には内部の文字コードの関係から別開発の必要が生じるかも知れないが)

 Androidではプログラム記述がJava必須となっている。しかしJNIという機構があり部分的に C, C++ で記述できることになっている。一方、現行のMindは「カーネル」(ディスパッチャやプリミティブな機能の定義部分)が C記述であるため、C を媒介にすることで間接的にMindを動かすことができるだろうと考え、やってみたところこれもその通りだった。
 Java, C, Mind の処理分担を図で示すと以下のようになる。

001_3_cut_3

 図では三つが同じ分量のように見えるが、当然ながらユーザが記述したプログラムはMindのコードとなるため、プログラム規模が一定以上あればMindのコードが多くを占めることになる。
 これは重要な点だが、MindのソースコードがCやJavaに変換されるわけではない。CやJavaのプログラムも併用するのは確かだが、それらはMindの実行時、最下位レベルではCPUやOSを駆動する必要からそこを経由するに過ぎない。

- 文字コードについて -

 今のところ内部処理はLinux版のMindを(コンパイラ、ランタイムライブラリとも)そのままEUCコードで走らせており、Android側との境界でUTF-8に変換している。
 本来であればMindの内部処理もUnicodeにしておけば良いのだが、Mindの利点である高度な文字列操作を行うには同じUnicodeでも固定幅コード(Mindの実績ではUCS2)を使う必要があるため、Androidとの境界でコード変換が必要(たとえば UTF-8 ←→ UCS2)という点では変わりない。



参考URL: 「日本語プログラミング言語Mind」 (スクリプツ・ラボ)

2013年5月 2日 (木)

開発環境

開発環境は2012年設置なので現時点(2013年4月)では少し古いかも知れない。
当初はWindows環境で始めたが将来のオンラインでの開発サービスを考え、Linuxに切り換えた。

(標準ツール)

OS: Red Hat Enterprise Linux 5.2
    (注:OSは64bit走行, Mindの開発ツールは32bit走行)

Java: JDK 6  (javacのバージョン 1.6.0_31)

Android SDK: r18
    (注:Eclipseは使わずコンソールベースで行う)

Android NDK(Native Development Kit): r8b
     (Native開発環境 C言語で記述できるように)

ant: 1.8.4
     (NDKをコンソールベースで行うのに必要)

(自作ツール:Linux版Mindで作成(コンソールでの開発を容易にする))

createavd/deleteavd     avdの作成/削除を容易にする
createproj              プロジェクトの作成を容易にする
genjnicode/genjnihead   Cのスケルトンやヘッダを出力
installcur/uninstallcur パッケージのインストール・アンインストールを容易にする
makecur                 パッケージのmakeを容易にする


参考URL: 「日本語プログラミング言語Mind」 (スクリプツ・ラボ)

« 2012年4月 | トップページ | 2013年6月 »