部分食

D40, Ai-s ED300/4.5(IF), darktableによる現像及びトリミング
ISO400, 1/200s, 絞り8

 

皆既食(食の最大の頃)

D40, Ai-s ED300/4.5(IF), darktableによる現像及びトリミング
ISO400, 1/4s, 絞り開放

 

1月31日は皆既月食でした。関東は曇りの予報でしたが快晴に恵まれ、絶好の観測・撮影日和となりました。


いつもどおり部屋の前の路上で撮影を始めたのですが、高度が高くて電線が邪魔になってしまい皆既前に部屋に引き上げざるを得ませんでした。ところが運良く室内から月が見えたので撮影を再開しました。

 

そうして暫く続けたのですが、皆既終了までには部屋の軒先の上に隠れてしまったのと、室内とはいえ窓開放状態で寒かったのとで月食終了を待たずに撮影を終えました。

 

 

探すと意外に見つからなかったので。

 

余りに初歩的というか基本的なことなので、記事にする人が少ないだけと思いますがハマりどころはちゃんとあります。

 

コンテキストメニューの呼び出し(マウス右クリックでポップアップされる奴)の際、ポップアップ直前に "populate_popup" というイベントが発生します。このイベントにコールバック関数をアタッチして必要な処理を行う訳です。

このコールバック関数はvoidで値を戻しません。このため既定の処理を完全に無くしてしまうことが出来ないと思います(可能な場合はgbooleanを返すようになっている)。

 

コールバック関数cb_populate_popupは引数にオブジェクトとポップアップするメニュー(以下menu)を引きます。

このmenuをgtk_widget_destroyで破壊すれば、デフォルトのコンテキストメニューを抑止できます。破壊してから自前で用意したものに差し替えれば、それを呼び出すことも可能です。マウスのボタンイベントやキーボードのキープレスイベントをチェックするよりスマートかも知れません。


しかしこのイベントは、デフォルトのコンテキストメニューを拡張するのが一番有用な使い方ではなかろうか、と思います。

 

拡張方法は簡単で、引数にあるmenuにmenuitemを付け加えるだけです。勿論、付け加えたmenuitemのコールバック関数(シグナルはactivate)は自分で書かなくてはなりません。

 

そして、ここに冒頭に書いた落とし穴がありました。

 

それは、gtk_widget_show_all(menu) を呼ばないと拡張した分が表示されない、というもの。

 

よく考えれば気づきそうなものなのですが、ここでの処理の後ポップアップの表示へと流れていくので、表示関係の細かいところは当然やってくれるものと思い込んでいたのでした。

 

さて、今回弄ったのはGtkSourceViewのpopulate_popupでした。GtkSourceViewはGtkTextViewの派生widgetであり、populate_popupもtextviewのそれのままです。

 

そのせいか、追加したmenuitemがtextviewのデフォルト部分の直上に置かれており、その上にSourceViewで加わった、undo/redo部分が乗る格好になってしまっています。
回避方法はあるのかも知れませんが、今回は追求しませんでした。GtkSourceView3.0では修正されているのかも知れません。

 

実行中の様子。新規に追加した "Add watch"が中程に挟まってしまっている。

 

 

コールバック関数の例。引数viewがGtkTextViewになっていますが、実際はGtkSourceViewです。


static void cb_populate_popup(GtkTextView *view, GtkMenu *menu,
                                                    gpointer data)
{
    GtkWidget *item;
    item = gtk_menu_item_new_with_mnemonic(_("_Add watch"));
    g_signal_connect(G_OBJECT(item), "activate",
        G_CALLBACK(cb_activate_add_watch), view);
    gtk_menu_shell_prepend(GTK_MENU_SHELL(menu),
                                    gtk_separator_menu_item_new());
    gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
    gtk_widget_show_all(menu);
}

 

 

 

コネクトはこんな感じ。

// コンテキストメニューの拡張
g_signal_connect(G_OBJECT(view), "populate-popup",
    G_CALLBACK(cb_populate_popup), NULL );

 

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に変更した。

 


Search

Calendar

S M T W T F S
    123
45678910
11121314151617
18192021222324
25262728   
<< February 2018 >>

Archive

Mobile

qrcode

Selected Entry

Link

Profile

Search

Other

Powered

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