| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-16 16:15:53
       
   | 
むとうです。
さかいさんのglibですが、遅ればせながらざっと見てみました。
短い期間にここまで作るのってすごいですね。私には無理かも...(^^;)。
んで、一応、質問など。
正直確認してないのにコメントしてるところがありますがご容赦ください。
他の方も何かコメントあったらメールしてくださいね。
ここって、Ruby-GNOME2のキモの部分だと思いますんで奮ってご参加ください。
#このメールに対しても、glibのソースに対してでも構いません。
====
全体:
・関数の宣言を他(gtkとか)と合わせませんか?
  static
  VALUE hoge
    ↓
  static VALUE
  hoge
rbglib.c:
前から疑問だったのですが...gErrorって使っていないですよね。
もし使っていないようだったら削除しちゃいませんか?
    gError = rb_define_class_under(mGLib, "Error", rb_eRuntimeError);
rbgobj_object.c:
・rbgobj_set_gobj()で、
  ・Data_Wrap_Struct(rb_cData, cinfo->mark, &g_object_unref, gobj);
    って、&が必要ですか?(gtkなんかはこのパターンの時、使っていないので...)
  ・/* XXX */のところでcinfoがNULLの時ってあるんですか?
  異常系のみの場合は、rb_bug()かなんかの方が良くないですか?
・clear_gobject()って使う予定アリですか?
・rbgobj_make_gobject()を廃止してrbgobj_make_gobject_auto_type()に
 統合しちゃマズイですかね?
 んで、名前も汎用的なモノにしてgtk/gnome等でも使うと。
 なんか、この辺、複雑すぎる気がするんですよね...。
・_gobject_to_ruby(), _gobject_from_ruby()って何に使うんですか?
 (不勉強ですみません)
・gobj_smethod_added()って何に使うんでしょうか?
rbgobj_param.c:
・例えば、rb_define_method(rbgobj_cParamSpec, "name", &get_name, 0);
 で、&get_nameなのはなぜでしょうか。
・rbgobj_param_spec_get_struct()とrbgobj_param_spec_wrap()って、
 Ruby/GTKで言うところのget_xxxxとmake_xxxxですよね....。この辺の
 名称ってできればRuby/GTK統一したいですね...。
 #この辺、後述します。
===
以下、提案
・rbgobj_class_info形を RGObjClassInfoみたいに大文字使ってちょっと短く
 して、かつ、いかにも型っぽくしません?
・rbgobj_class_infoですが、新たに2つのメンバを追加しませんか。
 
struct _rbgobj_class_info {
    VALUE klass;
    GType gtype;
    void (*mark)(GObject *);
    void (*free)(GObject *);
    void (*ref)(GObject *);     
    void (*unref)(GObject *);
};
んで、rbgobj_gobject.cのrbgobj_set_gobject()を以下のような感じ。
----------------
void
rbgobj_set_gobject(obj, gobj)
    VALUE obj;
    GObject* gobj;
{
    VALUE data;
    const rbgobj_class_info* cinfo = rbgobj_lookup_class(rb_class_of(obj));
    if (cinfo)
	cinfo->ref(gobj);
	data = Data_Wrap_Struct(rb_cData, cinfo->mark, cinfo->unref, gobj);
    else
	data = Data_Wrap_Struct(rb_cData, gobj_mark, g_object_unref, gobj); 
        /* ↑ここ必要かなぁ? */
    g_object_set_data_full(gobj, RUBY_GOBJECT_OBJ_KEY,
                           (gpointer)obj, delete_gobject);
    rb_ivar_set(obj, id_relatives, Qnil);
    rb_ivar_set(obj, id_gobject_data, data);
    st_add_direct(gobject_object_list, (char*)obj, (char*)obj);
}
----------------
こうすれば、make_hoge()って全部マクロにできると思うんですよね。
#rbgtk.cとか独自でhoge_refしてるところは全部修正しないとですがきれいに
#なるかなと。
===
よくわかってないのでとんちんかんなことを言っているかもしれませんが...
rbgobj_value.cのrbgobj_gvalue_to_rvalue()とrbgobj_rvalue_to_gvalue()ですが、
これって、結局のところVALUE<->GValueの相互自動変換ですよね?
であれば、rbgobj_make_gobject()とかも同様のメソッド名で統一できたらすっきり
しそうな気がするのですがいかがでしょう?
rbgobj_gvalue2r()
rbgobj_r2gvalue()
rbgobj_gobj2r()  → rbgobj_get_value_from_gobject(),rbgobj_make_gobject()の置き換え
rbgobj_r2gobj()  →rbgobj_get_gobject()の置き換え
無理かなぁ?実装してもいないで勝手に言ってます。すみません(^^;)
-- 
.:% Masao Mutoh<mu...@hi...>
 | 
| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-16 16:25:57
       
   | 
むとうです。
On Mon, 17 Jun 2002 01:15:47 +0900
Masao Mutoh <mu...@hi...> wrote:
> むとうです。
> 
(略)
> ===
> 以下、提案
> ・rbgobj_class_info形を RGObjClassInfoみたいに大文字使ってちょっと短く
>  して、かつ、いかにも型っぽくしません?
> ・rbgobj_class_infoですが、新たに2つのメンバを追加しませんか。
>  
> struct _rbgobj_class_info {
>     VALUE klass;
>     GType gtype;
>     void (*mark)(GObject *);
>     void (*free)(GObject *);
>     void (*ref)(GObject *);     
>     void (*unref)(GObject *);
> };
あ、これダメかな。gtk_widget_ref(GtkWidget *)とかを考えると 
先ほどの例では、rbgobj_set_gobject(obj, gobj)の中で、refに渡す
gobjを動的にキャストしないとですね。
なんかうまい手はないかなぁ。
-- 
.:% Masao Mutoh<mu...@hi...>
 | 
| 
     
      
      
      From: Masahiro S. <s01...@sf...> - 2002-06-16 18:52:11
       
   | 
さかいです。
From: Masao Mutoh <mu...@hi...>
Subject: [ruby-gnome2-devel-ja] GLib2読んでみました
Date: Mon, 17 Jun 2002 01:15:47 +0900
> さかいさんのglibですが、遅ればせながらざっと見てみました。
> 短い期間にここまで作るのってすごいですね。私には無理かも...(^^;)。
どういたしまして。
# でも、基本的にはgtkの方からコードを持ってきただけなので、
# そんな大した仕事じゃなかったですよん。
> 他の方も何かコメントあったらメールしてくださいね。
> ここって、Ruby-GNOME2のキモの部分だと思いますんで奮ってご参加ください。
> #このメールに対しても、glibのソースに対してでも構いません。
そうそう。僕からもお願いします。
今のコードはただの「たたき台」だと思って、
色々と改良してもらえると助かります。
> ====
> 全体:
> ・関数の宣言を他(gtkとか)と合わせませんか?
>   static
>   VALUE hoge
>     ↓
>   static VALUE
>   hoge
そうですね。
合わせようと思います。
> rbglib.c:
> 前から疑問だったのですが...gErrorって使っていないですよね。
> もし使っていないようだったら削除しちゃいませんか?
>     gError = rb_define_class_under(mGLib, "Error", rb_eRuntimeError);
使っていないとは思いますが、
glib-2.0ではエラーを一手に扱うGErrorという構造体があるので、
ひょっとしたらそれをラップする事もあるかなと思って、
一応そのまま持ってきました。
> rbgobj_object.c:
> ・rbgobj_set_gobj()で、
>   ・Data_Wrap_Struct(rb_cData, cinfo->mark, &g_object_unref, gobj);
>     って、&が必要ですか?(gtkなんかはこのパターンの時、使っていないので...)
あってもなくても、C言語の仕様的に同じはずです。
gtkに合わせて消しましょう。
>   ・/* XXX */のところでcinfoがNULLの時ってあるんですか?
>   異常系のみの場合は、rb_bug()かなんかの方が良くないですか?
XXXと書いたのは、cinfo->freeを呼ばなくしてしまった事についてでした。
何故そうしたかというと、先のメールでは書き忘れてしまいましたが
GObjectのリファレンスカウンタを実験的に使おうとしていたからです。
ちゃんと呼ぶようにも出来るのですが、cinfo->freeは現在使われていないので、
後回しでいっかと思って。(^^;;
> ・clear_gobject()って使う予定アリですか?
これもgtkからそのまま持ってきました。
gtkではgobj_destroy()がこの関数を使っているようですが、
GtkObjectと違ってGObjectにはdestroyが無いのでglibでは不要のはず。
gtkの方ではどうだろう……
> ・rbgobj_make_gobject()を廃止してrbgobj_make_gobject_auto_type()に
>  統合しちゃマズイですかね?
むとうさんの下の提案にあるように、結局
rbgobj_get_value_from_gobject()相当のものさえあれば
十分なんじゃないかという気がしてきました。
>  んで、名前も汎用的なモノにしてgtk/gnome等でも使うと。
>  なんか、この辺、複雑すぎる気がするんですよね...。
同感。たしかに複雑ですよね。
> ・_gobject_to_ruby(), _gobject_from_ruby()って何に使うんですか?
>  (不勉強ですみません)
rbgobj_gvalue_to_rvalue()とrbgobj_rvalue_to_gvalue()による
VALUE<->GValueの相互自動変換に使われます。
> ・gobj_smethod_added()って何に使うんでしょうか?
シグナルハンドラを特異メソッドとして書くためのもののようです。
> rbgobj_param.c:
> ・例えば、rb_define_method(rbgobj_cParamSpec, "name", &get_name, 0);
>  で、&get_nameなのはなぜでしょうか。
&が付いているのは、ただの癖です。
gtkに合わせて消しましょう。
> ・rbgobj_param_spec_get_struct()とrbgobj_param_spec_wrap()って、
>  Ruby/GTKで言うところのget_xxxxとmake_xxxxですよね....。この辺の
>  名称ってできればRuby/GTK統一したいですね...。
>  #この辺、後述します。
rbgobj_param.cは手をつけてはみたけど、今のコードは捨てたいなぁ。
GObjectでないGTypeInstanceをうまく扱えるような枠組みを作った上で、
書き直したい感じ。
> ===
> 以下、提案
> ・rbgobj_class_info形を RGObjClassInfoみたいに大文字使ってちょっと短く
>  して、かつ、いかにも型っぽくしません?
賛成です。
> ・rbgobj_class_infoですが、新たに2つのメンバを追加しませんか。
>  
> struct _rbgobj_class_info {
>     VALUE klass;
>     GType gtype;
>     void (*mark)(GObject *);
>     void (*free)(GObject *);
>     void (*ref)(GObject *);     
>     void (*unref)(GObject *);
> };
扱う対象をGObjectの派生クラスに限定するならば、
refとunrefはg_object_ref(),g_object_unref()だけでおっけーのはずなので、
ref,unrefは不要だと思います。
# gtk_object_ref(), gtk_widget_ref(), etc... はただの糖衣構文。
> んで、rbgobj_gobject.cのrbgobj_set_gobject()を以下のような感じ。
> ----------------
> void
> rbgobj_set_gobject(obj, gobj)
>     VALUE obj;
>     GObject* gobj;
> {
>     VALUE data;
> 
>     const rbgobj_class_info* cinfo = rbgobj_lookup_class(rb_class_of(obj));
> 
>     if (cinfo)
> 	cinfo->ref(gobj);
リファレンスカウンタについては僕もだいぶ混乱しているのですが、
現状だと、各クラスのinitializeの実装はunrefしないので、
ここでrefしてしまうのはまずそうな気がします。
# もちろん、unrefするようにinitializeの方を変更すれば良いのですが……
ストーリィ
1. initializeメソッド内で、hogehoge_new()を呼び出して、
   新しく作成されたオブジェクトのリファレンスを得る。
   この時点で、リファレンスカウンタは1
   
2. set_gobject()する
   ここでrefしてリファレンスカウンタは2になる。
   新しいリファレンスはrb_cDataのインスタンスが持っている。
3. initializeからリターン
   ここではunrefしていないので、リファレンスカウンタは2のまま。
4. Ruby側のラッパがGCされる。
   rb_cDataのインスタンスが持っていたリファレンスがunrefされるので、
   リファレンスカウンタは1
5. glib側のオブジェクトは解放されない。
> rbgobj_value.cのrbgobj_gvalue_to_rvalue()とrbgobj_rvalue_to_gvalue()ですが、
> これって、結局のところVALUE<->GValueの相互自動変換ですよね?
そうです。
シグナルハンドラの引数と返り値の変換を個別に書かなくても
良いようにするために導入してみました。
> であれば、rbgobj_make_gobject()とかも同様のメソッド名で統一できたらすっきり
> しそうな気がするのですがいかがでしょう?
> 
> rbgobj_gvalue2r()
> rbgobj_r2gvalue()
> rbgobj_gobj2r()  → rbgobj_get_value_from_gobject(),rbgobj_make_gobject()の置き換え
> rbgobj_r2gobj()  →rbgobj_get_gobject()の置き換え
これも賛成。
多分、問題ないと思います。
-- さかい
 | 
| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-17 15:36:32
       
   | 
むとうです。
まずはシンプルにして頭の中を整理したいなと。
On Mon, 17 Jun 2002 03:52:06 +0900
Masahiro Sakai <s01...@sf...> wrote:
> さかいです。
(略)
> > rbglib.c:
> > 前から疑問だったのですが...gErrorって使っていないですよね。
> > もし使っていないようだったら削除しちゃいませんか?
> >     gError = rb_define_class_under(mGLib, "Error", rb_eRuntimeError);
> 
> 使っていないとは思いますが、
> glib-2.0ではエラーを一手に扱うGErrorという構造体があるので、
> ひょっとしたらそれをラップする事もあるかなと思って、
> 一応そのまま持ってきました。
んじゃ、いったん削除しましょう。GErrorを実装するときがあれば
そのときにまた考えましょう。
> > rbgobj_object.c:
> >   ・/* XXX */のところでcinfoがNULLの時ってあるんですか?
> >   異常系のみの場合は、rb_bug()かなんかの方が良くないですか?
> 
> XXXと書いたのは、cinfo->freeを呼ばなくしてしまった事についてでした。
> 何故そうしたかというと、先のメールでは書き忘れてしまいましたが
> GObjectのリファレンスカウンタを実験的に使おうとしていたからです。
> 
> ちゃんと呼ぶようにも出来るのですが、cinfo->freeは現在使われていないので、
> 後回しでいっかと思って。(^^;;
えっと、まぁそうなんですが、使わないなら、gobj_mark()もいらなくなりますし
この際、削除した方がスッキリすると思います。
ふと思ったのですが、g_object_ref/unref前後(じゃなくても良いけど)のGObject
ってmalloc/freeって必要ないんですかね....。
> > ・clear_gobject()って使う予定アリですか?
> 
> これもgtkからそのまま持ってきました。
> gtkではgobj_destroy()がこの関数を使っているようですが、
> GtkObjectと違ってGObjectにはdestroyが無いのでglibでは不要のはず。
> gtkの方ではどうだろう……
gtkのgobj_destroy()の中でもあえて別関数化する必要は無さそうですねぇ。
当初は何か意図があったのかもしれませんが、これもいったん削除ということで。
 
> > ・_gobject_to_ruby(), _gobject_from_ruby()って何に使うんですか?
> >  (不勉強ですみません)
> 
> rbgobj_gvalue_to_rvalue()とrbgobj_rvalue_to_gvalue()による
> VALUE<->GValueの相互自動変換に使われます。
あ、ちょっと説明が悪かったですね。実は、Init_gobject_gobj()内の
rbgobj_register_r2g_func(rbgobj_cGObject, &_gobject_from_ruby);
rbgobj_register_g2r_func(G_TYPE_OBJECT, &_gobject_to_ruby);
の意図がちょっとわからなかったんです。
これって何を意図してるんでしょうか。
 
> > ・gobj_smethod_added()って何に使うんでしょうか?
> 
> シグナルハンドラを特異メソッドとして書くためのもののようです。
具体的にはどのようなコードを意図してるんでしょうか。
win = Gtk::Window.new
win.singleton_method_added(?????)
????
あり?全然イメージできないです....。ごめんなさい、教えてください。
 
> > ・rbgobj_param_spec_get_struct()とrbgobj_param_spec_wrap()って、
> >  Ruby/GTKで言うところのget_xxxxとmake_xxxxですよね....。この辺の
> >  名称ってできればRuby/GTK統一したいですね...。
> >  #この辺、後述します。
> 
> rbgobj_param.cは手をつけてはみたけど、今のコードは捨てたいなぁ。
> GObjectでないGTypeInstanceをうまく扱えるような枠組みを作った上で、
> 書き直したい感じ。
ひとまず、Ruby/GTKなんかに影響しない範囲であれば一度ざっくり削っちゃ
っていただいて構いません。
> > ・rbgobj_class_infoですが、新たに2つのメンバを追加しませんか。
> >  
> 扱う対象をGObjectの派生クラスに限定するならば、
> refとunrefはg_object_ref(),g_object_unref()だけでおっけーのはずなので、
> ref,unrefは不要だと思います。
> # gtk_object_ref(), gtk_widget_ref(), etc... はただの糖衣構文。
おぉ。なるほど、気づきませんでした。なら不要ですね。
> > んで、rbgobj_gobject.cのrbgobj_set_gobject()を以下のような感じ。
> > ----------------
> > void
> > rbgobj_set_gobject(obj, gobj)
> >     VALUE obj;
> >     GObject* gobj;
> > {
> >     VALUE data;
> > 
> >     const rbgobj_class_info* cinfo = rbgobj_lookup_class(rb_class_of(obj));
> > 
> >     if (cinfo)
> > 	cinfo->ref(gobj);
> 
> リファレンスカウンタについては僕もだいぶ混乱しているのですが、
> 現状だと、各クラスのinitializeの実装はunrefしないので、
> ここでrefしてしまうのはまずそうな気がします。
> # もちろん、unrefするようにinitializeの方を変更すれば良いのですが……
initializeの方でunrefって、unrefしたオブジェクトを使い回すということに
なるので、ちょっと気持ち悪い気がします。
> ストーリィ
> 
> 1. initializeメソッド内で、hogehoge_new()を呼び出して、
>    新しく作成されたオブジェクトのリファレンスを得る。
>    この時点で、リファレンスカウンタは1
これって、例えば、rbgtkbutton.cのbutton_initialize()とかのことを言ってますか?
どこでリファレンスカウンタが1になるのでしたっけ。ちょっとわからないんですが...。
> 2. set_gobject()する
>    ここでrefしてリファレンスカウンタは2になる。
>    新しいリファレンスはrb_cDataのインスタンスが持っている。
> 
> 3. initializeからリターン
>    ここではunrefしていないので、リファレンスカウンタは2のまま。
> 
> 4. Ruby側のラッパがGCされる。
>    rb_cDataのインスタンスが持っていたリファレンスがunrefされるので、
>    リファレンスカウンタは1
> 
> 5. glib側のオブジェクトは解放されない。
えっと、これって今のRuby/GTKの実装がってことでいいでしょうか?
さかいさん的には、2.でrefしなくても良いんじゃないかって解釈で良いでしょうか?
 
> > rbgobj_value.cのrbgobj_gvalue_to_rvalue()とrbgobj_rvalue_to_gvalue()ですが、
> > これって、結局のところVALUE<->GValueの相互自動変換ですよね?
> 
> そうです。
> シグナルハンドラの引数と返り値の変換を個別に書かなくても
> 良いようにするために導入してみました。
> 
> > であれば、rbgobj_make_gobject()とかも同様のメソッド名で統一できたらすっきり
> > しそうな気がするのですがいかがでしょう?
> > 
> > rbgobj_gvalue2r()
> > rbgobj_r2gvalue()
> > rbgobj_gobj2r()  → rbgobj_get_value_from_gobject(),rbgobj_make_gobject()の置き換え
> > rbgobj_r2gobj()  →rbgobj_get_gobject()の置き換え
> 
> これも賛成。
> 多分、問題ないと思います。
さらに、INT2FIXみたいなマクロを用意するとスッキリするかも。
 GOBJ2GVAL()
 RVAL2GVAL()
 GOBJ2RVAL()
 RVAL2GOBJ()
-- 
.:% Masao Mutoh<mu...@hi...>
 | 
| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-19 16:56:05
       
   | 
むとうです。 On Wed, 19 Jun 2002 15:20:18 +0900 Masahiro Sakai <s01...@sf...> wrote: > さかいです。 > > > XXXと書いたのは、cinfo->freeを呼ばなくしてしまった事についてでした。 > > > 何故そうしたかというと、先のメールでは書き忘れてしまいましたが > > > GObjectのリファレンスカウンタを実験的に使おうとしていたからです。 > > > > > > ちゃんと呼ぶようにも出来るのですが、cinfo->freeは現在使われていないので、 > > > 後回しでいっかと思って。(^^;; > > > > えっと、まぁそうなんですが、使わないなら、gobj_mark()もいらなくなりますし > > この際、削除した方がスッキリすると思います。 > > - mark用の関数をtype markerとして使うのは無理があるので、gobj_markは消す。 > - cinfo->freeが本当に要らないのかどうかは確信が持てないので保留。 > - rbgobj_lookup_*のAPIを練り直すことで、cinfoがNULLにならないようにする。 > > って感じでどうでしょうか。 良いですね。特に3つ目で、cinfoがNULLになる場合を想定するというのが変な 感じがしてました。 > > ふと思ったのですが、g_object_ref/unref前後(じゃなくても良いけど)のGObject > > ってmalloc/freeって必要ないんですかね....。 > > えっと、ちょっと想像できないのですが、どういうことでしょう? ごめんなさい。ちょっと寝ぼけてた(る)かも...。 忘れてください。 > > あ、ちょっと説明が悪かったですね。実は、Init_gobject_gobj()内の > > > > rbgobj_register_r2g_func(rbgobj_cGObject, &_gobject_from_ruby); > > rbgobj_register_g2r_func(G_TYPE_OBJECT, &_gobject_to_ruby); > > > > の意図がちょっとわからなかったんです。 > > これって何を意図してるんでしょうか。 > > rbgobj_cGObjectの派生クラス用のVALUE->GValueの変換関数として、 > _gobject_from_ruby() を登録し、 > G_TYPE_OBJECTの派生タイプ用のGValue->VALUEの変換関数として > _gobject_to_ruby() を登録しています。 あ、なんかわかってきたような。 rbgobj_object.cでこれを登録しているって言うことは、 ひょっとして、全てのGValue(当然GObjectも含む)<->VALUEの変換を rbgobj_gvalue_to_rvalue(),rbgobj_rvalue_to_gvalue()でやって しまうというのが意図ですか? ・・・(1) > # そういえば、この辺りはGClosureを使うようにしたときに > # だいぶヘボいコードにしてしまったので、rbgobj_closure.cの方とあわせて、 > # どなたか改良して貰えると助かります。 じゃ、おいおいやっていきましょう。 > > > リファレンスカウンタについては僕もだいぶ混乱しているのですが、 > > > 現状だと、各クラスのinitializeの実装はunrefしないので、 > > > ここでrefしてしまうのはまずそうな気がします。 > > > # もちろん、unrefするようにinitializeの方を変更すれば良いのですが…… > > > > initializeの方でunrefって、unrefしたオブジェクトを使い回すということに > > なるので、ちょっと気持ち悪い気がします。 > > initializeからリターンする前に最初のリファレンスをunrefしても、 > set_gobject()でのrefによってRubyのオブジェクト自身が > 新しいリファレンスを保持している事になるので、 > 僕はあんまし気持悪いとは感じてません。 > > > > 1. initializeメソッド内で、hogehoge_new()を呼び出して、 > > > 新しく作成されたオブジェクトのリファレンスを得る。 > > > この時点で、リファレンスカウンタは1 > > > > これって、例えば、rbgtkbutton.cのbutton_initialize()とかのことを言ってますか? > > どこでリファレンスカウンタが1になるのでしたっけ。ちょっとわからないんですが...。 > > その例でしたら、gtk_button_new()からリターンした時点で > 既にリファレンスカウンタは1になっていると思います。 > ちなみに、具体的に1をセットしているのはg_object_init() あぁ、そうか。それならrefの方は不要ですね。 > # と思ったら、gtk+側では floating object なんて概念もあるのか。 > # ややこしい…… > > > > 5. glib側のオブジェクトは解放されない。 > > > > えっと、これって今のRuby/GTKの実装がってことでいいでしょうか? > > 「他を変更せずにset_objectでrefするようにすると」です。 > > > さかいさん的には、2.でrefしなくても良いんじゃないかって解釈で良いでしょうか? > > 2.でrefしなくても実質的にはうまく行くんじゃないかとは思ってますが、 > これは気持悪いし、あまり自信がないです。 > 一方、2.でrefする事にすると、initialize側でunrefする必要があるはずで、 > 面倒臭そう…… initialize側で毎回unrefするというのは実装上、バグが多発しそうな気がします。 と考えると2.でrefしないというのも手ですよね。 > > と思っていたのですが、 > floating object の事とか見落としていたので、 > リファレンスカウンタについては、ちゃんと考え直そうと思います。 うぅぅ。ついていけませんでした(-_-;)。 #私もついていけるように勉強します。 > > さらに、INT2FIXみたいなマクロを用意するとスッキリするかも。 > > > > GOBJ2GVAL() > > RVAL2GVAL() > > GOBJ2RVAL() > > RVAL2GOBJ() もし、(1)の部分が正しいのであれば、上記は > > RVAL2GVAL() > > GVAL2RVAL() の2つですみます? それだと、 G2VALUE, VALUE2Gでも良いかも(短すぎ?)。 > この名前短くて良いですね。 > # そういえば、rvalueやRVALって「右辺値」を連想してしまいそう。(^^;; ははは。GVALはGlobal Valueを連想してしまったりして。 まぁ、たくさん使われる名前だから覚えてもらえるでしょう。 -- .:% Masao Mutoh<mu...@hi...>  | 
| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-20 13:03:01
       
   | 
むとうです。 On Thu, 20 Jun 2002 04:02:57 +0900 Masahiro Sakai <s01...@sf...> wrote: > さかいです。 > > あ、なんかわかってきたような。 > > rbgobj_object.cでこれを登録しているって言うことは、 > > ひょっとして、全てのGValue(当然GObjectも含む)<->VALUEの変換を > > rbgobj_gvalue_to_rvalue(),rbgobj_rvalue_to_gvalue()でやって > > しまうというのが意図ですか? ・・・(1) > > その通りです。 > # ただ、現在登録されている変換関数は圧倒的に不足していてますが。 なるほど。良い感じですね。 ひとつ、リファレンス的にGTK+かなんかのウィジェットを実装すれば、 後は同様に対応できそうですので、変換関数が不足しているのは今の 段階では問題ないと思います:->。 > > > floating object の事とか見落としていたので、 > > > リファレンスカウンタについては、ちゃんと考え直そうと思います。 > > > > うぅぅ。ついていけませんでした(-_-;)。 > > #私もついていけるように勉強します。 > > http://developer.gnome.org/doc/API/2.0/gtk/gtkobject.html > を見ると、以下のように書かれています。 > > The most interesting difference between GtkObject and GObject is the > "floating" reference count. A GObject is created with a reference > count of 1, owned by the creator of the GObject. (The owner of a > reference is the code section that has the right to call > g_object_unref() in order to remove that reference.) A GtkObject is > created with a reference count of 1 also, but it isn't owned by > anyone; calling g_object_unref() on the newly-created GtkObject is > incorrect. Instead, the initial reference count of a GtkObject is > "floating". The floating reference can be removed by anyone at any > time, by calling gtk_object_sink(). gtk_object_sink() does nothing if > an object is already sunk (has no floating reference). > > 多分互換性のためだと思うけど、気持悪いなぁ。 うーむ。もうちょっと下の方まで読むと This means that the container now owns a reference to the child widget (since it called g_object_ref()), and the child widget has no floating reference. The purpose of the floating reference is to keep the child widget alive until you add it to a parent container: って書いてありますね。「子供のリファレンスを管理するのは親ウィジェットだよ」 ということと受け止めましたがどうでしょうか。 私の勘(考えじゃないところに注意(^^;))が正しいとするとGObjectとGtkObject の違いは GObject - 管理するのは自分自身(のコード) GtkObject - 管理するのは親 ってことですかね。 「子供のウィジェットをunrefするタイミングを把握できるのは親」 という考えが正しければ、GtkObjectの方がしっくりくるような気もします。 #管理するのが自分自身の場合はデストラクタかなんかで #unrefするしかないような気もするので...。まぁ、それはそれでアリだと #思うのですけどね(^^;)。 ただし、この場合はコンテナ系のWidgetの場合は注意が必要ですね。 > でも、何となく分かってきた気がする…… > 単にgtkの方のset_gobject()を以下のように変更すれば、 > 最小限の変更で現在のコードと整合性が取れそう。 > > void > set_gobject(obj, gtkobj) > VALUE obj; > GtkObject *gtkobj; > { > gtkobj = gtk_object_ref(gtkobj); > gtk_object_sink(gtkobj); > rbgobj_set_gobject(obj, G_OBJECT(gtkobj)); > } 再び、同じ部分の引用ですが、 The purpose of the floating reference is to keep the child widget alive until you add it to a parent container: ということは、refもunrefもいらないんじゃないでしょうか。 親がaddされたタイミングでやってくれるので。 #この辺、単純に上記コメントを読んで勝手に解釈して勝手に言ってるだけです。 #gtk+のコードを追ってませんので間違えてたらごめんなさい。 > > > > さらに、INT2FIXみたいなマクロを用意するとスッキリするかも。 > > > > > > > > GOBJ2GVAL() > > > > RVAL2GVAL() > > > > GOBJ2RVAL() > > > > RVAL2GOBJ() > > > > もし、(1)の部分が正しいのであれば、上記は > > > > > > RVAL2GVAL() > > > > GVAL2RVAL() > > > > の2つですみます? > > GValueを得ても、実際に具体的な操作をするには > さらにそこからGObject*等を取り出さなくてはいけないので、 > 他の二つもあった方が便利で良いと思います。 なるほど、じゃぁ、残しましょう。 > ところで、この辺りのAPIを整理しようと > gtkディレクトリとgnomeディレクトリのソースを眺めていて、 > make_gobject()が思いの外使われていることに気が付きました。 > > rbgtk.cで使われているものを除いて、これらは全て > get_value_from_gobject()で必要十分だと思うのですが、 > make_gobject()が敢えて使われているのには何か理由があるのでしょうか? > make_gobject()は、gtk/glib側のオブジェクトとRuby側のオブジェクトの > 一対一対応関係を崩す危険があるので、APIとしては廃止したいのです。 コードの中身を見ても、あまり理由はないと思うんですけどね...。 特に私以外の方からコメントが無ければ、まずは廃止してしまいましょう。 どうしても必要な場合は逆に復活させればすむ話ですし。 ところで、結構議論が進んできたと思いますが、また、実装の方も さかいさんの方にお願いしちゃっても良いですか? コメントしかしていなくて恐縮ですが、しばらくはさかいさんに Ownerになっていただいていた方が良いと思いますので....。 > PS: > glibのコーディングスタイルで、指摘された部分は修正しました。 > 他にも合っていない部分があったら直して下さいませ。 ありがとうございます。 > PPS: > Ruby/Gtkって > http://www.gtk.org/bindings.html > には載ってないんですね…… そうですね〜。 http://erik.bagfors.nu/gnome/languages.html にはあるんですが(^^;)。 #載せてもらうようにメールした方が良いのかなぁ....。 -- .:% Masao Mutoh<mu...@hi...>  | 
| 
     
      
      
      From: Masahiro S. <s01...@sf...> - 2002-06-22 08:08:02
       
   | 
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: Re: [ruby-gnome2-devel-ja] Re: GLib2読んでみました Date: Thu, 20 Jun 2002 22:02:56 +0900 > > # ただ、現在登録されている変換関数は圧倒的に不足していてますが。 > > なるほど。良い感じですね。 > ひとつ、リファレンス的にGTK+かなんかのウィジェットを実装すれば、 > 後は同様に対応できそうですので、変換関数が不足しているのは今の > 段階では問題ないと思います:->。 ちなみに、不足しているのはGObjectを継承したタイプのためのコードではなくて、 むしろGBoxedとかGEnumとかGFlagとかそっちの方面です。 後はgdkの各種構造体の扱いの変更。 > うーむ。もうちょっと下の方まで読むと > This means that the container now owns a reference to the child widget > (since it called g_object_ref()), and the child widget has no floating > reference. > > The purpose of the floating reference is to keep the child widget alive > until you add it to a parent container: > > って書いてありますね。「子供のリファレンスを管理するのは親ウィジェットだよ」 > ということと受け止めましたがどうでしょうか。 > > 私の勘(考えじゃないところに注意(^^;))が正しいとするとGObjectとGtkObject > の違いは > > GObject - 管理するのは自分自身(のコード) > GtkObject - 管理するのは親 > > ってことですかね。 gtk的な意味での「親」は子のリファレンスを持っている内の一人に過ぎないので、 「親」が独占的に管理しているというわけでは無いと思います。 GtkObjectが異なるのは、newされた時点では誰にもownされていないという事 だけで。しかし、誰にもownされていないからといってリファレンスカウンタ を0にしておくというのも都合が悪いので、ちゃんとした身元引受人が一人で も見つかるまでの便宜的なものとして floating reference という概念をgtk は導入しているわけです。 なので、一度誰かにownされてfloating状態が解消されてしまえば、 後はGObjectと同じように扱えるはずです。 僕のset_gobject()のコードの意図はまさにそれで、 ref/sinkしてやることでGObjectと区別せずに扱えることを意図しています。 # 特に、Ruby側のオブジェクトがGCされるときに # GtkObjectをGObjectから区別せずにunref出来るようになる点が重要。 > > ところで、この辺りのAPIを整理しようと > > gtkディレクトリとgnomeディレクトリのソースを眺めていて、 > > make_gobject()が思いの外使われていることに気が付きました。 (snip) > コードの中身を見ても、あまり理由はないと思うんですけどね...。 > 特に私以外の方からコメントが無ければ、まずは廃止してしまいましょう。 > どうしても必要な場合は逆に復活させればすむ話ですし。 廃止してしまいました。 # 自分でcommitしておいてアレですが、少し急ぎすぎました。 # もう少しコメントを待つべきでしたね。 # すいません。 > ところで、結構議論が進んできたと思いますが、また、実装の方も > さかいさんの方にお願いしちゃっても良いですか? > コメントしかしていなくて恐縮ですが、しばらくはさかいさんに > Ownerになっていただいていた方が良いと思いますので....。 とりあえず、今議論している辺りは僕の方で実装したいと思ってます。 -- さかい  | 
| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-22 14:23:51
       
   | 
むとうです。 On Sat, 22 Jun 2002 17:07:57 +0900 Masahiro Sakai <s01...@sf...> wrote: > さかいです。 > > From: Masao Mutoh <mu...@hi...> > Subject: Re: [ruby-gnome2-devel-ja] Re: GLib2読んでみました > Date: Thu, 20 Jun 2002 22:02:56 +0900 > ちなみに、不足しているのはGObjectを継承したタイプのためのコードではなくて、 > むしろGBoxedとかGEnumとかGFlagとかそっちの方面です。 > 後はgdkの各種構造体の扱いの変更。 了解です。 > gtk的な意味での「親」は子のリファレンスを持っている内の一人に過ぎないので、 > 「親」が独占的に管理しているというわけでは無いと思います。 なるほど。 > GtkObjectが異なるのは、newされた時点では誰にもownされていないという事 > だけで。しかし、誰にもownされていないからといってリファレンスカウンタ > を0にしておくというのも都合が悪いので、ちゃんとした身元引受人が一人で > も見つかるまでの便宜的なものとして floating reference という概念をgtk > は導入しているわけです。 > > なので、一度誰かにownされてfloating状態が解消されてしまえば、 > 後はGObjectと同じように扱えるはずです。 > > 僕のset_gobject()のコードの意図はまさにそれで、 > ref/sinkしてやることでGObjectと区別せずに扱えることを意図しています。 > # 特に、Ruby側のオブジェクトがGCされるときに > # GtkObjectをGObjectから区別せずにunref出来るようになる点が重要。 了解です。 > > > ところで、この辺りのAPIを整理しようと > > > gtkディレクトリとgnomeディレクトリのソースを眺めていて、 > > > make_gobject()が思いの外使われていることに気が付きました。 > (snip) > > コードの中身を見ても、あまり理由はないと思うんですけどね...。 > > 特に私以外の方からコメントが無ければ、まずは廃止してしまいましょう。 > > どうしても必要な場合は逆に復活させればすむ話ですし。 > > 廃止してしまいました。 > > # 自分でcommitしておいてアレですが、少し急ぎすぎました。 > # もう少しコメントを待つべきでしたね。 > # すいません。 いや、いいですよ。CVSで管理してるから戻そうと思えばすぐ戻せますし。 > > ところで、結構議論が進んできたと思いますが、また、実装の方も > > さかいさんの方にお願いしちゃっても良いですか? > > コメントしかしていなくて恐縮ですが、しばらくはさかいさんに > > Ownerになっていただいていた方が良いと思いますので....。 > > とりあえず、今議論している辺りは僕の方で実装したいと思ってます。 お願いしますね! -- .:% Masao Mutoh<mu...@hi...>  | 
| 
     
      
      
      From: Masahiro S. <s01...@sf...> - 2002-06-19 19:03:06
       
   | 
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: Re: [ruby-gnome2-devel-ja] Re: GLib2読んでみました Date: Thu, 20 Jun 2002 01:56:00 +0900 > > - mark用の関数をtype markerとして使うのは無理があるので、gobj_markは消す。 > > - cinfo->freeが本当に要らないのかどうかは確信が持てないので保留。 > > - rbgobj_lookup_*のAPIを練り直すことで、cinfoがNULLにならないようにする。 > > > > って感じでどうでしょうか。 > > 良いですね。特に3つ目で、cinfoがNULLになる場合を想定するというのが変な > 感じがしてました。 ではそうしましょう。 > あ、なんかわかってきたような。 > rbgobj_object.cでこれを登録しているって言うことは、 > ひょっとして、全てのGValue(当然GObjectも含む)<->VALUEの変換を > rbgobj_gvalue_to_rvalue(),rbgobj_rvalue_to_gvalue()でやって > しまうというのが意図ですか? ・・・(1) その通りです。 # ただ、現在登録されている変換関数は圧倒的に不足していてますが。 > > 2.でrefしなくても実質的にはうまく行くんじゃないかとは思ってますが、 > > これは気持悪いし、あまり自信がないです。 > > 一方、2.でrefする事にすると、initialize側でunrefする必要があるはずで、 > > 面倒臭そう…… > > initialize側で毎回unrefするというのは実装上、バグが多発しそうな気がします。 > と考えると2.でrefしないというのも手ですよね。 そうですね。最初は気持悪いと思っていたのですが、 rbgobj_set_gobject()の用法を、initializeでのこの使い方に限定すれば、 refしないのがむしろ自然だという気が段々としてきました。 > > floating object の事とか見落としていたので、 > > リファレンスカウンタについては、ちゃんと考え直そうと思います。 > > うぅぅ。ついていけませんでした(-_-;)。 > #私もついていけるように勉強します。 http://developer.gnome.org/doc/API/2.0/gtk/gtkobject.html を見ると、以下のように書かれています。 The most interesting difference between GtkObject and GObject is the "floating" reference count. A GObject is created with a reference count of 1, owned by the creator of the GObject. (The owner of a reference is the code section that has the right to call g_object_unref() in order to remove that reference.) A GtkObject is created with a reference count of 1 also, but it isn't owned by anyone; calling g_object_unref() on the newly-created GtkObject is incorrect. Instead, the initial reference count of a GtkObject is "floating". The floating reference can be removed by anyone at any time, by calling gtk_object_sink(). gtk_object_sink() does nothing if an object is already sunk (has no floating reference). 多分互換性のためだと思うけど、気持悪いなぁ。 でも、何となく分かってきた気がする…… 単にgtkの方のset_gobject()を以下のように変更すれば、 最小限の変更で現在のコードと整合性が取れそう。 void set_gobject(obj, gtkobj) VALUE obj; GtkObject *gtkobj; { gtkobj = gtk_object_ref(gtkobj); gtk_object_sink(gtkobj); rbgobj_set_gobject(obj, G_OBJECT(gtkobj)); } > > > さらに、INT2FIXみたいなマクロを用意するとスッキリするかも。 > > > > > > GOBJ2GVAL() > > > RVAL2GVAL() > > > GOBJ2RVAL() > > > RVAL2GOBJ() > > もし、(1)の部分が正しいのであれば、上記は > > > > RVAL2GVAL() > > > GVAL2RVAL() > > の2つですみます? GValueを得ても、実際に具体的な操作をするには さらにそこからGObject*等を取り出さなくてはいけないので、 他の二つもあった方が便利で良いと思います。 ところで、この辺りのAPIを整理しようと gtkディレクトリとgnomeディレクトリのソースを眺めていて、 make_gobject()が思いの外使われていることに気が付きました。 rbgtk.cで使われているものを除いて、これらは全て get_value_from_gobject()で必要十分だと思うのですが、 make_gobject()が敢えて使われているのには何か理由があるのでしょうか? make_gobject()は、gtk/glib側のオブジェクトとRuby側のオブジェクトの 一対一対応関係を崩す危険があるので、APIとしては廃止したいのです。 -- さかい PS: glibのコーディングスタイルで、指摘された部分は修正しました。 他にも合っていない部分があったら直して下さいませ。 PPS: Ruby/Gtkって http://www.gtk.org/bindings.html には載ってないんですね……  | 
| 
     
      
      
      From: Yasushi S. <ya...@ya...> - 2002-06-17 17:59:48
       
   | 
やすしです。
わかるとこだけ…
At Tue, 18 Jun 2002 00:36:20 +0900,
Masao Mutoh wrote:
[...]
> > > ・gobj_smethod_added()って何に使うんでしょうか?
> > 
> > シグナルハンドラを特異メソッドとして書くためのもののようです。
> 
> 具体的にはどのようなコードを意図してるんでしょうか。
> 
> win = Gtk::Window.new
def win.show
  # do some
end
ってな具合に、object winに特異メソッドを定義すると ruby は 
Object#singleton_method_addedを呼びだすので、gobj_smethod_added()で 
overrideしてあるはず。
# はずしてたらごめんなさい…
--
       yashi
 | 
| 
     
      
      
      From: Masao M. <mu...@hi...> - 2002-06-18 15:47:05
       
   | 
むとうです。こんばんわ。 やすしさんご無沙汰です(^^;)。 On Tue, 18 Jun 2002 02:59:44 +0900 Yasushi Shoji <ya...@ya...> wrote: > やすしです。 > > わかるとこだけ… ありがとうございます、助かります。 > > > > ・gobj_smethod_added()って何に使うんでしょうか? > > > > > > シグナルハンドラを特異メソッドとして書くためのもののようです。 > > > > 具体的にはどのようなコードを意図してるんでしょうか。 > > > > win = Gtk::Window.new > > def win.show > # do some > end > > ってな具合に、object winに特異メソッドを定義すると ruby は > Object#singleton_method_addedを呼びだすので、gobj_smethod_added()で > overrideしてあるはず。 なるほど、そういえば、五十嵐さんの書かれたRuby/GTKの記事 にもbutton.clickedみたいなのが載ってた記憶が...。 と思ったら、README.EXTにも書いてありますね(^^;)。 -- .:% Masao Mutoh<mu...@hi...>  | 
| 
     
      
      
      From: Masahiro S. <s01...@sf...> - 2002-06-19 06:20:31
       
   | 
さかいです。 From: Masao Mutoh <mu...@hi...> Subject: Re: [ruby-gnome2-devel-ja] Re: GLib2読んでみました Date: Tue, 18 Jun 2002 00:36:20 +0900 > まずはシンプルにして頭の中を整理したいなと。 そうですね。 > んじゃ、いったん削除しましょう。GErrorを実装するときがあれば > そのときにまた考えましょう。 了解。 > > XXXと書いたのは、cinfo->freeを呼ばなくしてしまった事についてでした。 > > 何故そうしたかというと、先のメールでは書き忘れてしまいましたが > > GObjectのリファレンスカウンタを実験的に使おうとしていたからです。 > > > > ちゃんと呼ぶようにも出来るのですが、cinfo->freeは現在使われていないので、 > > 後回しでいっかと思って。(^^;; > > えっと、まぁそうなんですが、使わないなら、gobj_mark()もいらなくなりますし > この際、削除した方がスッキリすると思います。 - mark用の関数をtype markerとして使うのは無理があるので、gobj_markは消す。 - cinfo->freeが本当に要らないのかどうかは確信が持てないので保留。 - rbgobj_lookup_*のAPIを練り直すことで、cinfoがNULLにならないようにする。 って感じでどうでしょうか。 > ふと思ったのですが、g_object_ref/unref前後(じゃなくても良いけど)のGObject > ってmalloc/freeって必要ないんですかね....。 えっと、ちょっと想像できないのですが、どういうことでしょう? > あ、ちょっと説明が悪かったですね。実は、Init_gobject_gobj()内の > > rbgobj_register_r2g_func(rbgobj_cGObject, &_gobject_from_ruby); > rbgobj_register_g2r_func(G_TYPE_OBJECT, &_gobject_to_ruby); > > の意図がちょっとわからなかったんです。 > これって何を意図してるんでしょうか。 rbgobj_cGObjectの派生クラス用のVALUE->GValueの変換関数として、 _gobject_from_ruby() を登録し、 G_TYPE_OBJECTの派生タイプ用のGValue->VALUEの変換関数として _gobject_to_ruby() を登録しています。 > > > ・gobj_smethod_added()って何に使うんでしょうか? > > > > シグナルハンドラを特異メソッドとして書くためのもののようです。 > > 具体的にはどのようなコードを意図してるんでしょうか。 > > win = Gtk::Window.new > win.singleton_method_added(?????) > ???? > あり?全然イメージできないです....。ごめんなさい、教えてください。 yashiさんの書いている通りだと思います。 # そういえば、この辺りはGClosureを使うようにしたときに # だいぶヘボいコードにしてしまったので、rbgobj_closure.cの方とあわせて、 # どなたか改良して貰えると助かります。 > > リファレンスカウンタについては僕もだいぶ混乱しているのですが、 > > 現状だと、各クラスのinitializeの実装はunrefしないので、 > > ここでrefしてしまうのはまずそうな気がします。 > > # もちろん、unrefするようにinitializeの方を変更すれば良いのですが…… > > initializeの方でunrefって、unrefしたオブジェクトを使い回すということに > なるので、ちょっと気持ち悪い気がします。 initializeからリターンする前に最初のリファレンスをunrefしても、 set_gobject()でのrefによってRubyのオブジェクト自身が 新しいリファレンスを保持している事になるので、 僕はあんまし気持悪いとは感じてません。 > > 1. initializeメソッド内で、hogehoge_new()を呼び出して、 > > 新しく作成されたオブジェクトのリファレンスを得る。 > > この時点で、リファレンスカウンタは1 > > これって、例えば、rbgtkbutton.cのbutton_initialize()とかのことを言ってますか? > どこでリファレンスカウンタが1になるのでしたっけ。ちょっとわからないんですが...。 その例でしたら、gtk_button_new()からリターンした時点で 既にリファレンスカウンタは1になっていると思います。 ちなみに、具体的に1をセットしているのはg_object_init() # と思ったら、gtk+側では floating object なんて概念もあるのか。 # ややこしい…… > > 5. glib側のオブジェクトは解放されない。 > > えっと、これって今のRuby/GTKの実装がってことでいいでしょうか? 「他を変更せずにset_objectでrefするようにすると」です。 > さかいさん的には、2.でrefしなくても良いんじゃないかって解釈で良いでしょうか? 2.でrefしなくても実質的にはうまく行くんじゃないかとは思ってますが、 これは気持悪いし、あまり自信がないです。 一方、2.でrefする事にすると、initialize側でunrefする必要があるはずで、 面倒臭そう…… と思っていたのですが、 floating object の事とか見落としていたので、 リファレンスカウンタについては、ちゃんと考え直そうと思います。 > さらに、INT2FIXみたいなマクロを用意するとスッキリするかも。 > > GOBJ2GVAL() > RVAL2GVAL() > GOBJ2RVAL() > RVAL2GOBJ() この名前短くて良いですね。 # そういえば、rvalueやRVALって「右辺値」を連想してしまいそう。(^^;; -- さかい  |