コード例 #1
0
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;
}
コード例 #2
0
static void
boxed_mark(boxed_holder* p)
{
    const RGObjClassInfo* cinfo = GTYPE2CINFO(p->type);
    if (cinfo && cinfo->mark)
        cinfo->mark(p->boxed);
}
コード例 #3
0
ファイル: rbgobj_type.c プロジェクト: aurelj/ruby-gnome2
VALUE
rbgobj_gtype_to_ruby_class(GType gtype)
{
    const RGObjClassInfo *cinfo;

    cinfo = GTYPE2CINFO(gtype);
    return cinfo ? cinfo->klass : Qnil;
}
コード例 #4
0
ファイル: rbgobj_boxed.c プロジェクト: adamhooper/ruby-gnome2
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);
}
コード例 #5
0
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);
}
コード例 #6
0
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);
}
コード例 #7
0
ファイル: rbgobj_boxed.c プロジェクト: pkorenev/ruby-gnome2
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);
}
コード例 #8
0
void
rbgobj_boxed_not_copy_obj(GType gtype)
{
    RGObjClassInfo* cinfo = (RGObjClassInfo*)GTYPE2CINFO(gtype);
    cinfo->flags |= RBGOBJ_BOXED_NOT_COPY;
}
コード例 #9
0
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;
    }
}
コード例 #10
0
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);
        }
    }
}