[ruby-gnome2-doc-cvs] [Hiki] update - How to Implement Ruby-GNOME2

Back to archive index

ruby-****@sourc***** ruby-****@sourc*****
2004年 6月 7日 (月) 23:17:41 JST


-------------------------
REMOTE_ADDR = 218.231.180.27
REMOTE_HOST = 
        URL = http://ruby-gnome2.sourceforge.jp//?How+to+Implement+Ruby-GNOME2
-------------------------
  = How to implement Ruby-GNOME2
  This document explains how to implement an extension for Ruby-GNOME2.
  
  == Signals and Properties
  Accessors methods (((*set*))/((*get*))) for properties are automatically generated.  Signals are also directly handled by GLib::Instantiatable#signal_connect.  So, you do not need to manually implement them anymore.
  
  == Deprecated/Obsolete classes/methods
  Don't implement them.
  
  == Macros
  You need to know that there are some macros which can help you to easily implement a new class/method.  
  Almost of those macros are in the header files glib/src/rbgobject.h, rbglib.h and gtk/src/rbgtk.h.
  
  === Define class/interface
  These macros are used in Init_*() functions:
  
  --- G_DEF_CLASS(gtype, name, module)
  --- G_DEF_CLASS2(gtype, name, module, mark, free)
      Define a class. If you want to define mark and free functions by yourself, use G_DEF_CLASS2.
      This returns a new ruby class value.
  
  --- G_DEF_CLASS3(gtype_name, name, module)
      Define a class dynamicaly. This is for private gtype classes such as GdkScreenX11, GdkWindowImplWin32.
      This returns nothing. These classes can't define the methods/constants by themselves. And these classes appear since a method which creates the private gtype has been called by ruby script.
  
  --- G_DEF_INTERFACE(gtype, name, module)
  --- G_DEF_INTERFACE2(gtype, name, module, mark, free)
      Define a module. If you want to define mark and free functions by yourself, use G_DEF_INTERFACE2.
  
  --- void rbgobj_boxed_not_copy_obj(GType gtype)
      Use this method if the GBoxed object shouldn't be copied during its RVALUE conversion (for example in GBOXED2RVAL or G_INITIALIZE).
  
  === Initialize object
  These macros are used in class constructors (methods ((*initialize*))):
  
  --- G_INITIALIZE(obj, cobj)
  --- RBGTK_INITIALIZE(obj,gtkobj)
  --- RBGST_INITIALIZE(obj,gstobj)
      Initialize an object. If the class is a descendant of GtkObject, use RBGTK_INITIALIZE.  If the class in a descendant of GstObject, use RBGST_INITIALIZE.
  
  === Convert Ruby <-> GLib/GTK
  
  --- RVAL2GOBJ(obj)
  --- GOBJ2RVAL(gobj)
      VALUE(GLib::Object) <-> GObject
  
  --- RVAL2BOXED(obj)
  --- BOXED2RVAL(cobj, gtype)
      VALUE(GLib::Boxed) <-> GBoxed
  
  --- RVAL2GENUM(obj, gtype)
  --- GENUM2RVAL(gobj, gtype)
      VALUE(GLib::Enum) <-> GEnum
  
  --- RVAL2GFLAGS(obj, gtype)
  --- GFLAGS2RVAL(gobj, gtype)
      VALUE(GLib::Flags) <-> GFlags
  
  --- RVAL2CSTR(v)
  --- CSTR2RVAL(s)
      VALUE(String) <-> gchar*
  
  --- CSTR2RVAL2(s)
      Convert gchar* s to VALUE(String) and then call g_free(s).
  
  --- RVAL2CBOOL(v)
  --- CBOOL2RVAL(b)
      VALUE(true or false) <-> gboolean
  
  --- GVAL2RVAL(v)
      GValue(GLib::Value) -> RValue. 
      RVAL2GVAL(v) is not yet prepared. If you want to convert RValue to GValue, then use rbgobj_rvalue_to_gvalue():
  
    GValue gval = {0,};
    g_value_init(&gval, RVAL2GTYPE(value));
    
    rbgobj_rvalue_to_gvalue(value, &gval);
    /* then use gval... */
  
  --- GEV2RVAL(ev)
  --- RVAL2GEV(ev)
-     VALUE(Gtk::Event) <-> GtkEvent
+     VALUE(Gdk::Event) <-> GdkEvent
  
  --- GLIST2ARY(list)
  --- GSLIT2ARY(list)
      GList/GSList of GObject -> Array
  
  --- GLIST2ARY2(list)
  --- GSLIT2ARY2(list)
      GList/GSList of GBoxed -> Array
  
  === Convert RGObjClassInfo <-> GType,Ruby class/instance
  --- CLASS2CINFO(klass)
      Class -> RGObjClassInfo
  --- GTYPE2CINFO(gtype)
      GType -> RGObjClassInfo
  --- RVAL2CINFO(obj)
      VALUE -> RGObjClassInfo
  
  === Convert GType <->Ruby class/instance
  --- GTYPE2CLASS(gtype)
      GType -> Class
  --- CLASS2GTYPE(klass)
      Class -> GType
  --- RVAL2GTYPE(obj)
      VALUE -> GType
  
  === Relatives
  This saves an object from the GC. Usually obj is self and rel is child widget/object or proc object.
  
  --- G_RELATIVE(obj, rel)
      Make a relation.
  --- G_RELATIVE2(obj, rel, id, hash_key)
      Make a removable relation.
  --- G_REMOVE_RELATIVE(obj, id, hash_key)
      Remove a relation.
  
  === Setter methods
  --- G_DEF_SETTER(klass, name)
  --- G_DEF_SETTERS(klass)
      These macros can be used to implement automatically setters methods with operator ((*=*)).  
      You implement by yourself the method set_hoge(aValue), and then you call G_DEF_SETTER(klass, "hoge").
  
   set_hoge(a)          #return self (implemented by yourself)
   hoge=(a)             #return a    (created automatically from set_hoge)
  
  If you have several set methods in a single class, then you can call G_DEF_SETTERS which will do the magic for all of them.
  
  === Define constants
  --- G_DEF_CONSTANTS(mod, type, strip_prefix)
      Define constants of Module/Class from GType. G_DEF_CONSTANTS is used with G_DEF_CLASS.
      Here is a practical example from Gtk::Window source code:
  
    /* Define Gtk::Window::TOPLEVEL and Gtk::Window::POPUP. */
    G_DEF_CLASS(GTK_TYPE_WINDOW_TYPE, "Type", gWindow);
    G_DEF_CONSTANTS(gWindow, GTK_TYPE_WINDOW_TYPE, "GTK_WINDOW_");
  
  --- G_RENAME_CONSTANT(orig, alt)
      Rename constants which has been defined with G_DEF_CONSTANTS().
  
  --- G_RENAME_NICK(orig, alt)
      Rename nick of GEnum/GFlags which start numerical character. 
      Ruby/GLib define the methods of GFlags from nick automatically. If nick starts numerical character, it causes a syntax error.
  
  === Block
  --- G_BLOCK_PROC()
      This macro calls either rb_f_lambda() (Ruby <= 1.7.x) or rb_block_proc() (Ruby >= 1.8.x).
      You shouldn't use rb_f_lambda() or rb_block_proc() directly, if you want to produce portable code.
  
  === Argument of properties as hash
  --- G_SET_PROPERTIES(self, properties)
      This macro will help you to implement set_hoge(a, {:foo => 0, :bar =>"hoge"}) for properties.
  
  === Symbol properties
  --- G_SET_SYMBOL_PROPERTY(gtype, name)
      Define this in Init_*() for properties which use Symbol instead of String (e.g. Gtk::Stock).
  
  === Implement class which does not conform to GType system (no G*_TYPE_* macros)
  You can either use traditional method, or implement the class as a GBoxed object.
  
  Here is an example for the class ((*Foo*)):
  
  (1) Create the following function, which will return a GLib type for our class:
  
        GType foo_get_type(void) {
            static GType our_type = 0;
            if (our_type == 0) {
                our_type = g_boxed_type_register_static("Foo",
                                                        (GBoxedCopyFunc)foo_copy,
                                                        (GBoxedFreeFunc)g_free);
            }
            return our_type;
        }
      
      If Foo has foo_ref/foo_unref, then use them instead of foo_copy, g_free.
  
  (2) Create the following function, which will return a copy of an objet from our class:
  
        Foo* foo_copy(const Foo* foo) {
            Foo* new_foo;
            g_return_val_if_fail (foo != NULL, NULL);
            new_foo = g_new(Foo, sizeof(Foo));
            *new_foo = *foo;
            return new_foo;
        }
      
      Rarely, there are some objects which shouldn't make copy and shouldn't free them, you may need to write it as follows:
  
        Foo* foo_copy(const Foo* foo) {
            return (Foo*)foo;
        }
        void foo_free(gpointer foo) {
            /* do nothing */
        }
        GType foo_get_type(void) {
            static GType our_type = 0;
            if (our_type == 0) {
                our_type = g_boxed_type_register_static("Foo",
                                                        (GBoxedCopyFunc)foo_copy,
                                                        (GBoxedFreeFunc)foo_free);
            }
            return our_type;
        }
       
      Furthermore, some objects may need to do g_free() there in this case.
  
  (3) Define a G*_TYPE_* macro:
  
        #define G_TYPE_FOO         (foo_get_type())
  
  (4) You can now call in your Init_*() function:
  
        void Init_foo(void) {
            VALUE cFoo = G_DEF_CLASS(G_TYPE_FOO, "Foo", aModule);
            /* ... */
        }
  
  (5) And for conversions:
  
        /* Ruby -> GLib */
        RVAL2BOXED(objet, G_TYPE_FOO);
  
        /* GLib -> Ruby */
        BOXED2RVAL(objet, G_TYPE_FOO))
  
  === GError handling
  --- RAISE_GERROR(GError* error)
      This macro will throw a Ruby exception according to the error code.
  
  === GLib::Object#signal_connect's block variables set manually
  --- G_DEF_SIGNAL_FUNC(klass, signal_name, signal_g2r_func);
  --- signal_g2r_func(guint num, const GValue* values);
      You can define with these macros block variables for signals by yourself.  
      These macros should be used only in special case (since signals are automatically handled).
  
  === Recommended editors
  If you develop Ruby-GNOME2 with GNU Emacs, I recommend you to customize your ~/.emacs file as follows:
  
   (c-add-style
    "ruby"
    '("bsd"
      (c-basic-offset . 4)
      (c-offsets-alist
       (case-label . 2)
       (label . 2)
  
        (statement-case-open . 2)
        (statement-case-intro . 2))))
   
   (add-hook 'c-mode-common-hook
             '(lambda () (setq indent-tabs-mode nil)))
  
  - ((<Masao>))





ruby-gnome2-cvs メーリングリストの案内
Back to archive index