luaの実行環境を作る話の続き。

 

ウォッチ式の表示においてListStoreをTreeStoreに代えてみました。また、テーブルの要素を全て拾うようにしました。

luaのテーブルの要素にC側からアクセスする方法と、TreeViewへの登録方法を調べながらだったので半日仕事になってしまいました。

 

 

localなテーブルtにグローバルなテーブルt2(t2はt3を含む)を加えている。2箇所あるブレークポイントの間でグローバルなテーブルt3(t3.tokyo)を書き換えており、それがt(t.sub.country.tokyo)にも反映されている。

 

leafpadをフォークしてluaの実行環境を作る話の続き。

 

作ってばかりいても仕方ないので、少し動かしてみました。

 

Cairoのサーフェースをgtkのdrawableに持ってくる方法が分かったのでグラフィック部分を少し改変しました。今まで一旦pngに書き出してから、imageウィジェットに取り込んでいました。


但し、何か描画するごとにcairo=>drawableへの転送をやらないと、実際に更新されて見えないので、改変前後で速度的には余り差がありません。

 

リサージュ図形(リサジュー曲線、が正しいらしい)を描いてみました。描画中に表示更新した時の体感速度は、大昔の富士通FM-7よりちょっと速い位。日立MB-S1とか終末期のPC-88には完全に負けている、と思います。

 

更新しなければ一瞬です、念の為。

 

グラフィックスウィンドウをluaのガベコレ任せにしているのは相変わらず。調子に乗って次々に開いていると、突然消滅する。

 

 

leafpadをフォークしてluaの実行環境を作る話の続き。

 

UIを一部変更して変数を表示するように改変し、今まで標準出力に垂れ流していたローカル変数情報を表示するようにしてみた。

 

GtkTreeViewとかGtkListStoreとかは妙にごちゃごちゃしていて嫌いなのだけれど、他にこれといった方法が思い浮かばないので仕方なく使っている。

 

変数の表示について
ローカルについては特に問題無い。またグローバル変数については、lua5.1では擬似インデックスを指定するだけでアクセスできる(5.2以降は変更されたらしい)。上位値をどうするか、検討中。

 

関数の表示について

luaの関数は基本的に無名関数なので関数名は余り意味を持たない。下手にアクセスしようとするとセグメンテーションエラーになる。定義された場所(ソース上の行番号情報)から何かコピーしてこようかと思う。
その他、userdataやCfunctionの扱いをどうするか。

 

まだまだ先は長い。

 

ローカル変数 d は関数 a が返してきた関数を保持している。取り敢えず、定義箇所の行番号情報を表示させている。

 

自分宛てメモ。

 

ファンクションキーにステップイン(Trace Into)やステップオーバーの呼び出しを割り当てたところ、期待通りに動かない状況に遭遇した。

 

当初、これらにはluaの起動(lua_pcall)は呼ばせていなかった。


しかし、

 

  1. UIでブレークポイントを設定し、
  2. lua_hookを設定し、
  3. Runコマンドでlua_pcall()を呼び出し、
  4. 一時停止した後にファンクションキーを押下してステップイン(Trace Into)やステップオーバーを実行する。

 

というのは、如何にも間抜けな感じがしたので、luaが動いていない時ならファンクションキー押下で何時でもステップイン(Trace Into)やステップオーバーを実行できるように改変したところ、

  • luaは実行されるが実行中にステップイン(Trace Into)やステップオーバーを受け付けない

という状態になってしまった。

 

 

症状
luaは実行されるが実行中にステップイン(Trace Into)やステップオーバーを受け付けない

 

 

原因
lua実行中はgtkの待ちループ(gtk_main)に戻らないため。

 

ファンクションキー押下でステップイン(Trace Into)やステップオーバーを開始しようとすると、(メニューアイテムにアタッチされた)コールバック関数が呼び出され、そこで

  1. フラグ類の初期化
  2. lua_pcall()をコール

という処理が行われる。

 

即ち、lua_pcall()が終了するまでコールバック関数の中であり、これが終わるまで同じイベント(ステップインやステップオーバーは往々にして連打される)は実行されない。

 

Runコマンド(これも同様にファンションキー押下で呼び出される)も状況は同じなのだが、lua_hookで抜けた時にgtk_main_iteration_doで待ちループを動かしてイベントを拾っている(これによりファンクションキーによるStop動作を実現)。

 

 

対策
直接、lua_pcallを呼ばず、gtkのアイドルに投げる。

g_idle_add(luautil_run_common,NULL);

これにより、ファンションキー押下で呼び出されたコールバックが終了した後、luautil_run_commonが呼び出される。

 

関数gboolean luautil_run_common(gpointer data)は、各種初期化やlua_hookを設定した後、lua_pcallを呼ぶ(その後のエラー処理も行う)。

 

 

自分宛てメモ。

 

当初実装する予定でなかった、ステップオーバー機能を実装してみた。その際遭遇した事について。

 

luaのデバッグインターフェース(C APIのほう)では、デバッグフックを呼ぶ際のイベントにcallイベントを使えるようになっている。

 

このイベントを設定すると、「フックは新しい関数に入った直後、その関数が引数を取得する前に呼ばれる。」となっている。
デバッグフックにて、ここでイベント源からlineイベントを外すように設定する。すると、次にフックするのはcall, return, count の何れかのイベントになる。行ごとのフックを無くすことで、「関数実行時のステップオーバー」を実装することができる。
なお、今回は行単位で動くデバッガなのでcountは最初から使っていない。

 

症状

このように目論んで動かしてみたのだが、確かにブレークポイントで一度止めてからのステップオーバーは正常に動作したのだが、(Runコマンドの代わりに)最初から呼び出すと暫く読み飛ばしてからストップするようになった。

関数の中に関数が出現しても正常に読み飛ばせるように、カウンタを使ってネストをチェックしているのだけれど、そのカウント値が吊り合わない。

 

原因

プログラムの呼び出しそのものが「関数呼び出し1回目」として扱われていたため。Luaの文法にはCのmain関数に相当するものがないので意識していなかったのだが、確かにLuaの実行は組み込み元からの関数呼び出しによる。

 

対策
callイベント時にカウンタ値が 正でなければ lineイベントを継続するようにしておいて、カウンタの初期値を 0 から -1に変更した。

 

2018年2月6日、記事内容に重大な事実誤認があったので一部修正及び削除。

関連記事はこちら

 

 

自分宛てメモ。

 

未だにGtk+-2.0を使っている。理由は「枯れているから」なのだが、一つ失敗したことがあったので。

 

出力メッセージの国際化をgettextを用いて行ったのだが、どういうことかメニュー周辺の文字列が置換されなかった。

 

理由はgettextの仕組みと、Gtkの融通の無さにあった。

 

gettextはアプリケーション内でマークされた文字を、事前に用意されたファイルのものと置き換えることで各言語に対応しようとする。
 

例1)

puts( _("it is fine today.") );

_()は"it is fine today."をキーにして対応する翻訳を探しだして返す、という動作をする(はず)。

 

例2)
char *hoge[] = { "hoge", "piyo", "fuga" };
for ( i = 0; i < 2; i++ ) {
    puts( hoge[i] );
}

最初の配列は、単純に _("hoge") とかやると関数呼び出しに置換されてしまいエラーとなるので、N_("hoge")とする。 N_(string) は (string)に置換される。コンパイラから見ると何もしていないのと同じ。xgettextが拾い出す為の印に過ぎない。

次に puts( _(hoge[i]) ); とする。

 

使おうと思う関数の引数に _() を挿入できる場合はこれで良いのだが、そうでない場合、例えば文字列を含むオブジェクトを渡す場合(通常、Cは構造体のポインタを渡す)はお手上げである。
Gtk+-2.0のUI Manager でメニューを構築しようとする時がまさにこの状態。Gtk側に何かフックでもあって処理ルーチンを外挿できるとかになっていれば良いのだが、そんなものは(多分)無い。例え存在したとしても、バグ要因やセキュリティホールになりやすいと思う。

 

なので結局、メニュー用の個別関数を使って組み上げるしか方法がないことになる。UI Managerは全体の見通しが効くし、アイテムの挿抜も容易で便利だったので、こんなことで使えなくなるのは残念。

 

尚、UI Manager や actions関係は Gtk3では軒並み廃止されてしまった。これは国際化対応以前にGtkBuilderと機能的に重複する(ように見える)のが主な理由ではなかろうか。

 

 

メニューは翻訳されていないが、ダイアログ内の文字列は翻訳されている。

 

自分宛てメモ。

 

GtkSourceStyleSchemeを用いたGtkSouceView(GtkSouceBuffer)の色付けは自動で行われる。
しかし、手動でGtkSourceStyleSchemeの情報をもらって、何かに流用したいこともある。

 

そんな時の方法

 

既にBufferにはGtkSourceStyleSchemeの設定が完了しているものとする。

 

// buffer から scheme を得て、そこで定義されている情報を元にtagを設定する。
    GtkSourceStyleScheme *ss;
    GtkSourceStyle *style;
    gchar *color;

    ss = gtk_source_buffer_get_style_scheme(GTK_SOURCE_BUFFER(buffer));
    style = gtk_source_style_scheme_get_style(ss, "search-match" );

    if (style != NULL ){
        g_object_get(style,"background", &color, NULL);
    }

    gtk_text_buffer_create_tag(buffer, "searched",
        "background", color,
        //~ "foreground", "black",
        NULL);
    gtk_text_buffer_create_tag(buffer, "replaced",
        "background", color,
        //~ "background", "cyan",
        //~ "foreground", "black",
        NULL);
    g_free(color);
    


GtkTextTagの色設定をGtkSourceStyleSchemeからもらうことで見た目の統一感をだそう、というもの。
g_object_getで得たプロパティはコピーなので、用が済んだら適切に開放すること。

 

その一方、GtkSourceStyleSchemeやGtkSourceStyleはunrefしてはいけない。ややこしい。

 

 

 

leafpadを改造してluaの実行環境を作る話の続き。

 

いろいろ調べながらとはいえ、ちょっと時間かけ過ぎではなかろうか、というのが反省点ですね。

 

ログを見てみたら12月15日が一番古かったので、実にたっぷり1ヶ月以上費やしたことになります。途中、年末年始を挟んで4,5日弄っていなかった日もありますが。

 

機能説明

 

エディタ
GtkSourceViewを使った、1画面・1ファイルしか開けないメモ帳エディタ。保存していなくても、バッファ上のluaスクリプトを実行できます。それだけ。

 

デバッガ
ブレークポイント、コンティニュー、ステップオーバー インが可能。ローカル変数は自動ダンプ(単なる手抜き)。任意の変数やテーブルの参照設定は未だ実装せず。

 

グラフィックス
cairoライブラリを使った描点、描線、塗りつぶし、pangoによるテキスト表示。GtkWindowに直書きする方法を諦め、中間ファイル(png)経由で表示しています。故に、描画の様子を眺めようとすると時間がかかって実用的ではありません。ゲームとか、アニメーションとか、絶対無理。
一応、オブジェクトスタイルで書けるようにはしてありますがuserdataなのでlua側での継承は無理。キャンバスは複数持てるので、リソースの許す限り何枚でも描けます。
しかしGtkWindowの破壊をlua任せにするという思い切った仕様のため、たくさん開いておくと、放置してあったウィンドウがガベージコレクタに回収され唐突に消える、という暴挙が見られます。

 

 

作った本人しか使わないツールだし、凝りだすとキリがないので、まあ、こんなもんでしょう。デバッガは勿論、エディタも早々に2窓化しそうな気がしますけど。バグ出しのほうが先か。

 

luaからCを呼ぶ方法を理解したのが一番の収穫でした。既存のライブラリで何か書くならPythonが有利と思いますが、ライブラリをイチから自前で作らなくてはならない、とかだったらLuaのほうが簡単なような気がします。

 

 

色を変えながら100個ばかり点を打つ、というデモ。こんなもんでも、画面更新しながらだと4秒ほどかかってしまう。動いているところが見えて良い、という考え方もできるけど。勿論、更新しなければ一瞬です。

 

自分宛てメモ

自分宛てメモ

 

症状
例えばデスクトップ上で、不要なアイテムをゴミ箱に移動するだけでdbusサービスなtumblerdが仕事を始める。移動したアイテムについてのみ処理してくれれば良さそうなのだが、どうもHDD全域を見て回っているようで、ファイル数が増えてくると時間がかかって仕方がない。

 

対策
1)tumblerdをkillする。
HDDのアクセスがひどくなったら、都度killして止める

 

2)アンインストールする
 Synaptic等でパッケージ tumbler をアンインストールする。libtumbler-1-0は残しておいても良さそう。
 

その

Thunarでサムネイルが表示されなくなるかも知れないが、画像ビューアで代用する。

 


Search

Calendar

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     
<< April 2018 >>

Archive

Mobile

qrcode

Selected Entry

Link

Profile

Search

Other

Powered

無料ブログ作成サービス JUGEM