VALUE rbgobj_make_boxed(gpointer p, GType gtype) { const RGObjClassInfo* cinfo; VALUE result; boxed_holder* holder; if (!p) return Qnil; cinfo = GTYPE2CINFO(gtype); result = rbgobj_boxed_s_allocate(cinfo->klass); Data_Get_Struct(result, boxed_holder, holder); if (cinfo->flags & RBGOBJ_BOXED_NOT_COPY){ holder->boxed = p; holder->own = FALSE; } else { holder->boxed = g_boxed_copy(gtype, p); holder->own = TRUE; } return result; }
static void boxed_mark(boxed_holder* p) { const RGObjClassInfo* cinfo = GTYPE2CINFO(p->type); if (cinfo && cinfo->mark) cinfo->mark(p->boxed); }
VALUE rbgobj_gtype_to_ruby_class(GType gtype) { const RGObjClassInfo *cinfo; cinfo = GTYPE2CINFO(gtype); return cinfo ? cinfo->klass : Qnil; }
VALUE rbgobj_make_boxed_default(gpointer p, GType gtype) { const RGObjClassInfo *cinfo; cinfo = GTYPE2CINFO(gtype); return rbgobj_make_boxed_raw(p, gtype, cinfo->klass, cinfo->flags); }
void rbgobj_param_spec_initialize(VALUE self, GParamSpec *pspec) { pspec_holder* holder; Data_Get_Struct(self, pspec_holder, holder); pspec = g_param_spec_ref(pspec); g_param_spec_sink(pspec); holder->instance = pspec; holder->cinfo = GTYPE2CINFO(G_PARAM_SPEC_TYPE(pspec)); g_param_spec_set_qdata(pspec, qparamspec, (gpointer)self); }
static void boxed_free(boxed_holder* p) { const RGObjClassInfo* cinfo = GTYPE2CINFO(p->type); if (cinfo && cinfo->free) cinfo->free(p->boxed); if (p->own && p->boxed) g_boxed_free(p->type, p->boxed); free(p); }
static void boxed_free(boxed_holder *holder) { const RGObjClassInfo *cinfo; cinfo = GTYPE2CINFO(holder->type); if (cinfo && cinfo->free) cinfo->free(holder->boxed); if (holder->own && holder->boxed) g_boxed_free(holder->type, holder->boxed); free(holder); }
void rbgobj_boxed_not_copy_obj(GType gtype) { RGObjClassInfo* cinfo = (RGObjClassInfo*)GTYPE2CINFO(gtype); cinfo->flags |= RBGOBJ_BOXED_NOT_COPY; }
static VALUE type_register(int argc, VALUE* argv, VALUE self) { VALUE type_name, flags; volatile VALUE class_init_proc = Qnil; GType parent_type; GTypeInfo* info; rb_scan_args(argc, argv, "03", &type_name, &info, &flags); { const RGObjClassInfo* cinfo = rbgobj_lookup_class(self); if (cinfo->klass == self) rb_raise(rb_eTypeError, "already registered"); } { VALUE superclass = rb_funcall(self, rb_intern("superclass"), 0); const RGObjClassInfo* cinfo = rbgobj_lookup_class(superclass); if (cinfo->klass != superclass) rb_raise(rb_eTypeError, "super class must be registered to GLib"); parent_type = cinfo->gtype; } if (NIL_P(type_name)) { VALUE s = rb_funcall(self, rb_intern("name"), 0); if (strlen(StringValuePtr(s)) == 0) rb_raise(rb_eTypeError, "can't determine type name"); type_name = rb_funcall( rb_eval_string("lambda{|x| x.gsub(/::/,'') }"), rb_intern("call"), 1, s); } { GTypeQuery query; g_type_query(parent_type, &query); info = g_new0(GTypeInfo, 1); info->class_size = query.class_size; info->base_init = NULL; info->base_finalize = NULL; info->class_init = class_init_func; info->class_finalize = NULL; info->class_data = (gpointer)class_init_proc; info->instance_size = query.instance_size; info->n_preallocs = 0; info->instance_init = NULL; info->value_table = NULL; } { GType type = g_type_register_static(parent_type, StringValuePtr(type_name), info, NIL_P(flags) ? 0 : NUM2INT(flags)); G_RELATIVE(self, class_init_proc); rbgobj_register_class(self, type, TRUE, TRUE); { RGObjClassInfo* cinfo = (RGObjClassInfo*)rbgobj_lookup_class(self); cinfo->flags |= RBGOBJ_DEFINED_BY_RUBY; } { GType parent = g_type_parent(type); const RGObjClassInfo* cinfo = GTYPE2CINFO(parent); VALUE m = rb_define_module_under(self, RubyGObjectHookModule); if (! (cinfo->flags & RBGOBJ_DEFINED_BY_RUBY)) { rb_define_method(m, "initialize", gobj_initialize, -1); } rb_include_module(self, m); } return Qnil; } }
void rbgobj_register_type(VALUE klass, VALUE type_name, GClassInitFunc class_init) { GType parent_type; GTypeInfo *info; { const RGObjClassInfo *cinfo = rbgobj_lookup_class(klass); if (cinfo->klass == klass) rb_raise(rb_eTypeError, "already registered class: <%s>", RBG_INSPECT(klass)); } { VALUE superclass = rb_funcall(klass, rb_intern("superclass"), 0); const RGObjClassInfo *cinfo = rbgobj_lookup_class(superclass); if (cinfo->klass != superclass) rb_raise(rb_eTypeError, "super class must be registered to GLib: <%s>", RBG_INSPECT(superclass)); parent_type = cinfo->gtype; } if (NIL_P(type_name)) { VALUE klass_name = rb_funcall(klass, rb_intern("name"), 0); if (strlen(StringValueCStr(klass_name)) == 0) rb_raise(rb_eTypeError, "can't determine type name: <%s>", RBG_INSPECT(klass)); type_name = rb_funcall(klass_name, rb_intern("gsub"), 2, rb_str_new_cstr("::"), rb_str_new_cstr("")); } { GTypeQuery query; g_type_query(parent_type, &query); /* TODO: Why new? g_type_register_static() doesn’t retain a copy, so * this should be allocated on the stack. */ info = g_new0(GTypeInfo, 1); info->class_size = query.class_size; info->base_init = NULL; info->base_finalize = NULL; info->class_init = class_init; info->class_finalize = NULL; info->class_data = NULL; info->instance_size = query.instance_size; info->n_preallocs = 0; info->instance_init = NULL; info->value_table = NULL; } { GType type = g_type_register_static(parent_type, StringValueCStr(type_name), info, 0); rbgobj_register_class(klass, type, TRUE, TRUE); { RGObjClassInfo *cinfo = (RGObjClassInfo *)rbgobj_lookup_class(klass); cinfo->flags |= RBGOBJ_DEFINED_BY_RUBY; } { GType parent = g_type_parent(type); const RGObjClassInfo *cinfo = GTYPE2CINFO(parent); VALUE initialize_module; initialize_module = rb_define_module_under(klass, RubyGObjectHookModule); if (!(cinfo->flags & RBGOBJ_DEFINED_BY_RUBY)) { rbg_define_method(initialize_module, "initialize", rg_initialize, -1); } rb_include_module(klass, initialize_module); } } }