Beispiel #1
0
/*
 *   Get a property from an intrinsic class modifier object.  Look up the
 *   property in my own modifier, and recursively in my superclass modifiers.
 */
int CVmObjClass::get_prop_from_mod(VMG_ vm_prop_id_t prop, vm_val_t *val,
                                   vm_obj_id_t self, vm_obj_id_t *source_obj,
                                   uint *argc)
{
    vm_obj_id_t sc;
    vm_obj_id_t mod_obj;

    /* if we have a modifier object, look it up in the modifier */
    if ((mod_obj = get_mod_obj()) != VM_INVALID_OBJ
        && vm_objp(vmg_ mod_obj)->get_prop(vmg_ prop, val, mod_obj,
                                           source_obj, argc))
    {
        /* got it - return it from the modifier */
        return TRUE;
    }

    /* 
     *   it's not in our modifier(s); check with any intrinsic superclass
     *   modifiers 
     */
    if (get_superclass_count(vmg_ self) != 0
        && (sc = get_superclass(vmg_ self, 0)) != VM_INVALID_OBJ)
    {
        /* we have a superclass - check it recursively */
        return ((CVmObjClass *)vm_objp(vmg_ sc))
            ->get_prop_from_mod(vmg_ prop, val, sc, source_obj, argc);
    }

    /* 
     *   we didn't find it, and we have no superclass, so there's nowhere
     *   else to look - return failure 
     */
    return FALSE;
}
Beispiel #2
0
/*
 *   Find the intrinsic class which the given modifier object modifies.  This
 *   can only be used with a modifier that modifies me or one of my
 *   superclasses.
 */
vm_obj_id_t CVmObjClass::find_mod_src_obj(VMG_ vm_obj_id_t self,
                                          vm_obj_id_t mod_obj)
{
    vm_obj_id_t my_mod_obj;
    vm_obj_id_t sc;
    
    /* 
     *   Is this one of my modifier objects?  It is if it's my most
     *   specialized modifier object (i.e., get_mod_obj()), or if my most
     *   specialized modifier object descends from the given object. 
     */
    my_mod_obj = get_mod_obj();
    if (my_mod_obj != VM_INVALID_OBJ
        && (mod_obj == my_mod_obj
            || vm_objp(vmg_ my_mod_obj)->is_instance_of(vmg_ mod_obj)))
    {
        /* it's one of mine, so I'm the intrinsic class mod_obj modifies */
        return self;
    }

    /* 
     *   It's not one of mine, so check my superclasses recursively.  If we
     *   have no direct superclass, we've failed to find the object.  
     */
    if (get_superclass_count(vmg_ self) == 0
        || (sc = get_superclass(vmg_ self, 0)) == VM_INVALID_OBJ)
        return VM_INVALID_OBJ;
    
    /* ask the superclass to find the modifier */
    return ((CVmObjClass *)vm_objp(vmg_ sc))
        ->find_mod_src_obj(vmg_ sc, mod_obj);
}
Beispiel #3
0
static const RGObjClassInfo *
rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent,
        gboolean create_class)
{
    GType fundamental_type;
    RGObjClassInfo* cinfo;
    RGObjClassInfoDynamic* cinfod;
    void* gclass = NULL;
    VALUE c;

    if (gtype == G_TYPE_INVALID)
        return NULL;

    cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype));
    if (cinfo)
        return cinfo;

    if (!create_class)
        return NULL;

    c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
    cinfo->gtype = gtype;
    cinfo->mark  = NULL;
    cinfo->free  = NULL;
    cinfo->flags = 0;

    fundamental_type = G_TYPE_FUNDAMENTAL(gtype);
    switch (fundamental_type) {
    case G_TYPE_POINTER:
    case G_TYPE_BOXED:
    case G_TYPE_PARAM:
    case G_TYPE_OBJECT:
    case G_TYPE_ENUM:
    case G_TYPE_FLAGS:
        if (NIL_P(parent)) parent = get_superclass(gtype);
        cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
        break;

    case G_TYPE_INTERFACE:
        cinfo->klass = rb_module_new();
        break;

    default:
        if (NIL_P(parent)) parent = get_superclass(gtype);
        if (NIL_P(parent)) {
            fprintf(stderr,
                    "%s: %s's fundamental type %s isn't supported\n",
                    "rbgobj_lookup_class_by_gtype",
                    g_type_name(gtype),
                    g_type_name(fundamental_type));
            return NULL;
        }
        cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
    }

    cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list,
             g_type_name(gtype));
    if (cinfod) {
        cinfo->mark = cinfod->mark;
        cinfo->free = cinfod->free;
        rb_define_const(cinfod->module, cinfod->name, cinfo->klass);
    }

    rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
    g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);

    if (G_TYPE_IS_CLASSED(gtype))
        gclass = g_type_class_ref(gtype);

    if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype))
        rbgobj_define_action_methods(cinfo->klass);

    if (G_TYPE_IS_INSTANTIATABLE(gtype)) {
        GType* interfaces = NULL;
        guint n_interfaces = 0;
        guint i;

        interfaces = g_type_interfaces(gtype, &n_interfaces);
        for (i = 0; i < n_interfaces; i++) {
            const RGObjClassInfo *iface_cinfo;
            iface_cinfo =
                rbgobj_lookup_class_by_gtype_without_lock(interfaces[i],
                        Qnil,
                        TRUE);
            rb_include_module(cinfo->klass, iface_cinfo->klass);
        }
        g_free(interfaces);
    }

    if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) {
        switch (fundamental_type) {
        case G_TYPE_OBJECT:
            rbgobj_init_object_class(cinfo->klass);
            break;
        case G_TYPE_ENUM:
            rbgobj_init_enum_class(cinfo->klass);
            break;
        case G_TYPE_FLAGS:
            rbgobj_init_flags_class(cinfo->klass);
            break;
        case G_TYPE_INTERFACE:
            rbgobj_init_interface(cinfo->klass);
            break;
        default:
            rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass);
            break;
        }
    }

    if (gclass)
        g_type_class_unref(gclass);

    return cinfo;
}