やすしです。

From: Hiroshi IGARASHI <igarashi / ueda.info.waseda.ac.jp>
Subject: [ruby-ext:01010] Re: GtkType vs Ruby
Date: Sun, 26 Mar 2000 18:44:24 +0900

> > GtkTypeを key、各 objectの Init_gtk_*()の中の rb_define_class_under()で
> > の返り値を valueにした hashを作りたいんですが:
> 
> 新しいtypeを追加可能な VALUE get_gtk_type(GtkObject *) の
> 代替物を作ろうという意図ですよね。

おお、意図を書いていなかった‥。その通りです。ごめんなさい。(__)

> > 1) rb_define_class_under()の時点では、全ての Gtk+の objectは type
> > systemで initializeされてない(と思う)。
> 
> 確かにinit.cで
>     Init_gtk_gtk();
> 
>     gtk_init(&argc, &argv);
> の前で呼ばれているのですが、gtk_xxxx_get_type()でGtkType値を
> 得ることは……やはりできないかなぁ。

gtk_init()するまえに gtk_*()を使うのは危いですね‥。

で、どんな感じかと言うと:

VALUE rbgtk_type_lookup_hash;

void
rbgtk_type_reg(type, klass)
  GtkType type;
  VALUE klass;
{
  if (rb_hash_aref(rbgtk_type_lookup_hash, INT2NUM(type)) == Qnil)
    (rb_hash_aset(rbgtk_type_lookup_hash, INT2NUM(type), klass);
}

void Init_gtk_widget()
{
  gWidget = rb_define_class_under(mGtk, "Widget", gObject);
  rbgtk_type_reg(gtk_widget_get_type(), gWidget);
  :
  :
}


ですかね。これの問題は二つあって、

- rbgtk_type_reg()を全ての class init function(Init_gtk_xxxx())で書かな
ければならない。

- programの中で使われない widgetも Gtk+の type systemで initializeされる

です。もちろん、gtk_init()は Init_gtk*()の前に持ってこなければなりません
ね。

> > 2) はじめて instanceを作った時に hashを作ると、大量の objectを使う
> > programで遅くなりそう。
> 
> どういう感じなのかぴんとこないのですが、

こっちの場合は例えば、set_gobject()の中で:

void
set_gobject(obj, gtkobj)
    VALUE obj;
    GtkObject *gtkobj;
{
    VALUE data;

    rbgtk_type_reg(GTK_OBJECT_TYPE(gtkobj), RBGTK_OBJ_CLASS(obj));
    :
    :
}

ですかね‥。RBGTK_OBJ_CLASS()ってのはどうやるかわからないですが(ぉぃ

instanceを持たないやつ(Gtk::Boxとか)は、いらないですよね?

> 1)でできれば、その方がいいのですが。

ですね。
--
         yashi