Files
bluelib/core/object.c

147 lines
3.4 KiB
C
Raw Normal View History

2025-08-16 16:03:55 +01:00
#include "object.h"
#include "type.h"
#include <blue/core/class.h>
#include <blue/core/macros.h>
#include <blue/core/object.h>
2025-08-16 16:03:55 +01:00
#include <blue/core/thread.h>
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 *z__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 *z__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 *z__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_retain(struct _b_object *p)
{
p->obj_ref++;
return p;
}
void b_release(struct _b_object *p)
{
if (p->obj_ref > 1) {
p->obj_ref--;
}
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);
}