/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /********************************************************************** rbgobj_typeinstance.c - $Author: sakai $ $Date: 2007/07/04 13:13:19 $ created at: Sat May 27 14:18:55 JST 2006 Copyright (C) 2002-2006 Ruby-GNOME2 Project Team Copyright (C) 2002,2003 Masahiro Sakai **********************************************************************/ #include "rbgprivate.h" VALUE cInstantiatable; typedef void (*ClassInfoCallbackFunc) (gpointer instance, const RGObjClassInfo *class_info, gpointer user_data); static VALUE instantiatable_s_allocate(VALUE klass) { rb_raise(rb_eTypeError, "abstract class"); } static VALUE instantiatable_get_gtype(VALUE self) { return rbgobj_gtype_new(G_TYPE_FROM_INSTANCE(rbgobj_instance_from_ruby_object(self))); } static VALUE instantiatable_clone(VALUE self) { rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(self))); } /**********************************************************************/ static void each_cinfo(gpointer instance, ClassInfoCallbackFunc func, gpointer user_data) { const GType gtype = G_TYPE_FROM_INSTANCE(instance); GType* interfaces; guint n_interfaces = 0; interfaces = g_type_interfaces(gtype, &n_interfaces); { guint i; for (i = 0; i < n_interfaces; i++) { const RGObjClassInfo *info; info = GTYPE2CINFO_NO_CREATE(interfaces[i]); if (info) func(instance, info, user_data); } } g_free(interfaces); { GType type; for (type = gtype; type != G_TYPE_INVALID; type = g_type_parent(type)) { const RGObjClassInfo *info; info = GTYPE2CINFO_NO_CREATE(type); if (info) func(instance, info, user_data); } } } static void call_cinfo_free(gpointer instance, const RGObjClassInfo *cinfo, gpointer user_data) { if (cinfo->free) cinfo->free(instance); } static void call_cinfo_mark(gpointer instance, const RGObjClassInfo *cinfo, gpointer user_data) { if (cinfo->mark) cinfo->mark(instance); } void rbgobj_instance_call_cinfo_mark(gpointer instance) { each_cinfo(instance, call_cinfo_mark, NULL); } void rbgobj_instance_call_cinfo_free(gpointer instance) { each_cinfo(instance, call_cinfo_free, NULL); } void rbgobj_gc_mark_instance(gpointer instance) { VALUE obj = rbgobj_ruby_object_from_instance2(instance, FALSE); rb_gc_mark(obj); } /**********************************************************************/ void Init_gobject_typeinstance() { /* should be renamed to GLib::Instance? */ cInstantiatable = rb_define_class_under(mGLib, "Instantiatable", rb_cObject); rb_extend_object(cInstantiatable, mMetaInterface); rb_define_alloc_func(cInstantiatable, (VALUE(*)_((VALUE)))instantiatable_s_allocate); rb_define_method(cInstantiatable, "gtype", instantiatable_get_gtype, 0); rb_define_method(cInstantiatable, "clone", instantiatable_clone, 0); }