#include "object.h" #include "type.h" #include #include #include #include B_TYPE_CLASS_DEFINITION_BEGIN(b_object) B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) B_INTERFACE_ENTRY(to_string) = NULL; B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) B_TYPE_CLASS_DEFINITION_END(b_object) B_TYPE_DEFINITION_BEGIN(b_object) B_TYPE_ID(0x45f15a2c, 0x6831, 0x4bef, 0xb350, 0x15c650679211); B_TYPE_CLASS(b_object_class); B_TYPE_DEFINITION_END(b_object) b_result b_object_instantiate( struct b_type_registration *type, struct _b_object **out_object) { struct _b_object *out = malloc(type->r_instance_size); if (!out) { return B_RESULT_ERR(NO_MEMORY); } memset(out, 0x0, type->r_instance_size); out->obj_magic = B_OBJECT_MAGIC; out->obj_type = type; out->obj_ref = 1; b_queue_iterator q_it; b_queue_foreach (&q_it, &type->r_class_hierarchy) { struct b_type_component *comp = b_unbox(struct b_type_component, q_it.entry, c_entry); const struct b_type_info *class_info = comp->c_type->r_info; void *private_data = (char *)out + comp->c_instance_private_data_offset; if (class_info->t_instance_init) { class_info->t_instance_init(out, private_data); } if (comp->c_type == type) { out->obj_main_priv_offset = comp->c_instance_private_data_offset; } } *out_object = out; return B_RESULT_SUCCESS; } struct _b_object *b_object_create(b_type type) { struct b_type_registration *type_reg = b_type_get_registration(type); if (!type_reg) { return NULL; } struct _b_object *out = NULL; b_result result = b_object_instantiate(type_reg, &out); if (b_result_is_error(result)) { b_error_release(result); return NULL; } return out; } void b_object_to_string(struct _b_object *p, struct b_stream *out) { B_CLASS_DISPATCH_VIRTUAL_V(b_object, B_TYPE_OBJECT, p, to_string, p, out); b_stream_write_fmt(out, NULL, "<%s@%p>", p->obj_type->r_info->t_name, p); } void *b_object_get_private(struct _b_object *object, b_type type) { if (b_type_id_compare(&object->obj_type->r_info->t_id, type) == 0) { return (char *)object + object->obj_main_priv_offset; } struct b_type_component *comp = b_type_get_component(&object->obj_type->r_components, type); if (!comp) { return NULL; } return (char *)object + comp->c_instance_private_data_offset; } void *b_object_get_protected(struct _b_object *object, b_type type) { struct b_type_component *comp = b_type_get_component(&object->obj_type->r_components, type); if (!comp) { return NULL; } return (char *)object + comp->c_instance_protected_data_offset; } void *b_object_get_interface(struct _b_object *object, b_type type) { return z__b_class_get_interface(object->obj_type->r_class, type); } struct _b_object *b_object_ref(struct _b_object *p) { p->obj_ref++; return p; } void b_object_unref(struct _b_object *p) { if (p->obj_ref > 1) { p->obj_ref--; return; } p->obj_ref = 0; const struct b_type_registration *type = p->obj_type; struct b_queue_entry *cur = b_queue_last(&type->r_class_hierarchy); while (cur) { struct b_type_component *comp = b_unbox(struct b_type_component, cur, c_entry); const struct b_type_info *class_info = comp->c_type->r_info; void *private_data = (char *)p + comp->c_instance_private_data_offset; if (class_info->t_instance_fini) { class_info->t_instance_fini(p, private_data); } cur = b_queue_prev(cur); } p->obj_magic = 0; p->obj_type = NULL; free(p); }