fx: re-arrange type system to allow for reflection
This commit is contained in:
+54
-49
@@ -9,42 +9,46 @@
|
||||
#include <fx/stream.h>
|
||||
#include <fx/thread.h>
|
||||
|
||||
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_object)
|
||||
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
||||
FX_TYPE_CLASS_BEGIN(fx_object)
|
||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
||||
FX_INTERFACE_ENTRY(to_string) = NULL;
|
||||
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
|
||||
FX_TYPE_CLASS_DEFINITION_END(fx_object)
|
||||
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
|
||||
FX_TYPE_CLASS_END(fx_object)
|
||||
|
||||
FX_TYPE_DEFINITION_BEGIN(fx_object)
|
||||
FX_TYPE_ID(0x45f15a2c, 0x6831, 0x4bef, 0xb350, 0x15c650679211);
|
||||
FX_TYPE_NAME("fx.object");
|
||||
FX_TYPE_CLASS(fx_object_class);
|
||||
FX_TYPE_DEFINITION_END(fx_object)
|
||||
|
||||
fx_result fx_object_instantiate(
|
||||
struct fx_type_registration *type,
|
||||
struct fx_type_info *type,
|
||||
struct _fx_object **out_object)
|
||||
{
|
||||
struct _fx_object *out = malloc(type->r_instance_size);
|
||||
struct _fx_object *out = malloc(type->ty_instance_size);
|
||||
if (!out) {
|
||||
return FX_RESULT_ERR(NO_MEMORY);
|
||||
}
|
||||
|
||||
memset(out, 0x0, type->r_instance_size);
|
||||
memset(out, 0x0, type->ty_instance_size);
|
||||
|
||||
out->obj_magic = FX_OBJECT_MAGIC;
|
||||
out->obj_type = type;
|
||||
out->obj_ref = 1;
|
||||
|
||||
struct fx_queue_entry *entry = fx_queue_first(&type->r_class_hierarchy);
|
||||
struct fx_queue_entry *entry = fx_queue_first(
|
||||
&type->ty_class_hierarchy);
|
||||
while (entry) {
|
||||
struct fx_type_component *comp
|
||||
= fx_unbox(struct fx_type_component, entry, c_entry);
|
||||
const struct fx_type_info *class_info = comp->c_type->r_info;
|
||||
void *private_data
|
||||
= (char *)out + comp->c_instance_private_data_offset;
|
||||
struct fx_type_component *comp = fx_unbox(
|
||||
struct fx_type_component,
|
||||
entry,
|
||||
c_entry);
|
||||
const struct fx_type_info *class_info = comp->c_type;
|
||||
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 (class_info->ty_instance_init) {
|
||||
class_info->ty_instance_init(out, private_data);
|
||||
}
|
||||
|
||||
if (comp->c_type == type) {
|
||||
@@ -59,9 +63,9 @@ fx_result fx_object_instantiate(
|
||||
return FX_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
struct _fx_object *fx_object_create(fx_type type)
|
||||
struct _fx_object *fx_object_create(fx_type_id type)
|
||||
{
|
||||
struct fx_type_registration *type_reg = fx_type_get_registration(type);
|
||||
struct fx_type_info *type_reg = fx_type_info_get_by_id(type);
|
||||
if (!type_reg) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -84,27 +88,23 @@ void fx_object_to_string(const struct _fx_object *p, fx_stream *out)
|
||||
to_string,
|
||||
p,
|
||||
out);
|
||||
fx_stream_write_fmt(
|
||||
out,
|
||||
NULL,
|
||||
"<%s@%p>",
|
||||
p->obj_type->r_info->t_name,
|
||||
p);
|
||||
fx_stream_write_fmt(out, NULL, "<%s@%p>", p->obj_type->ty_name, p);
|
||||
}
|
||||
|
||||
bool fx_object_is_type(const struct _fx_object *p, fx_type type)
|
||||
bool fx_object_is_type(const struct _fx_object *p, fx_type_id type)
|
||||
{
|
||||
if (fx_type_id_compare(&p->obj_type->r_info->t_id, type) == 0) {
|
||||
if (fx_type_id_compare(&p->obj_type->ty_id, type) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct fx_type_component *comp
|
||||
= fx_type_get_component(&p->obj_type->r_components, type);
|
||||
struct fx_type_component *comp = fx_type_get_component(
|
||||
&p->obj_type->ty_components,
|
||||
type);
|
||||
|
||||
return comp != NULL;
|
||||
}
|
||||
|
||||
void *fx_object_get_private(const struct _fx_object *object, fx_type type)
|
||||
void *fx_object_get_private(const struct _fx_object *object, fx_type_id type)
|
||||
{
|
||||
if (!object) {
|
||||
return NULL;
|
||||
@@ -112,12 +112,13 @@ void *fx_object_get_private(const struct _fx_object *object, fx_type type)
|
||||
|
||||
assert(object->obj_magic == FX_OBJECT_MAGIC);
|
||||
|
||||
if (fx_type_id_compare(&object->obj_type->r_info->t_id, type) == 0) {
|
||||
if (fx_type_id_compare(&object->obj_type->ty_id, type) == 0) {
|
||||
return (char *)object + object->obj_main_priv_offset;
|
||||
}
|
||||
|
||||
struct fx_type_component *comp
|
||||
= fx_type_get_component(&object->obj_type->r_components, type);
|
||||
struct fx_type_component *comp = fx_type_get_component(
|
||||
&object->obj_type->ty_components,
|
||||
type);
|
||||
if (!comp) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -125,7 +126,7 @@ void *fx_object_get_private(const struct _fx_object *object, fx_type type)
|
||||
return (char *)object + comp->c_instance_private_data_offset;
|
||||
}
|
||||
|
||||
void *fx_object_get_protected(const struct _fx_object *object, fx_type type)
|
||||
void *fx_object_get_protected(const struct _fx_object *object, fx_type_id type)
|
||||
{
|
||||
if (!object) {
|
||||
return NULL;
|
||||
@@ -133,8 +134,9 @@ void *fx_object_get_protected(const struct _fx_object *object, fx_type type)
|
||||
|
||||
assert(object->obj_magic == FX_OBJECT_MAGIC);
|
||||
|
||||
struct fx_type_component *comp
|
||||
= fx_type_get_component(&object->obj_type->r_components, type);
|
||||
struct fx_type_component *comp = fx_type_get_component(
|
||||
&object->obj_type->ty_components,
|
||||
type);
|
||||
if (!comp) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -142,7 +144,7 @@ void *fx_object_get_protected(const struct _fx_object *object, fx_type type)
|
||||
return (char *)object + comp->c_instance_protected_data_offset;
|
||||
}
|
||||
|
||||
void *fx_object_get_interface(const struct _fx_object *object, fx_type type)
|
||||
void *fx_object_get_interface(const struct _fx_object *object, fx_type_id type)
|
||||
{
|
||||
if (!object) {
|
||||
return NULL;
|
||||
@@ -150,12 +152,12 @@ void *fx_object_get_interface(const struct _fx_object *object, fx_type type)
|
||||
|
||||
assert(object->obj_magic == FX_OBJECT_MAGIC);
|
||||
|
||||
return fx_class_get_interface(object->obj_type->r_class, type);
|
||||
return fx_class_get_interface(object->obj_type->ty_class, type);
|
||||
}
|
||||
|
||||
enum fx_status fx_object_get_data(
|
||||
const struct _fx_object *object,
|
||||
fx_type type,
|
||||
fx_type_id type,
|
||||
void **priv,
|
||||
void **prot,
|
||||
void **iface)
|
||||
@@ -166,8 +168,9 @@ enum fx_status fx_object_get_data(
|
||||
|
||||
assert(object->obj_magic == FX_OBJECT_MAGIC);
|
||||
|
||||
struct fx_type_component *comp
|
||||
= fx_type_get_component(&object->obj_type->r_components, type);
|
||||
struct fx_type_component *comp = fx_type_get_component(
|
||||
&object->obj_type->ty_components,
|
||||
type);
|
||||
if (!comp) {
|
||||
return FX_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
@@ -181,7 +184,7 @@ enum fx_status fx_object_get_data(
|
||||
}
|
||||
|
||||
if (iface) {
|
||||
*iface = (char *)object->obj_type->r_class
|
||||
*iface = (char *)object->obj_type->ty_class
|
||||
+ comp->c_class_data_offset;
|
||||
}
|
||||
|
||||
@@ -202,19 +205,21 @@ void fx_object_unref(struct _fx_object *p)
|
||||
}
|
||||
|
||||
p->obj_ref = 0;
|
||||
const struct fx_type_registration *type = p->obj_type;
|
||||
const struct fx_type_info *type = p->obj_type;
|
||||
|
||||
struct fx_queue_entry *cur = fx_queue_last(&type->r_class_hierarchy);
|
||||
struct fx_queue_entry *cur = fx_queue_last(&type->ty_class_hierarchy);
|
||||
while (cur) {
|
||||
struct fx_type_component *comp
|
||||
= fx_unbox(struct fx_type_component, cur, c_entry);
|
||||
struct fx_type_component *comp = fx_unbox(
|
||||
struct fx_type_component,
|
||||
cur,
|
||||
c_entry);
|
||||
|
||||
const struct fx_type_info *class_info = comp->c_type->r_info;
|
||||
void *private_data
|
||||
= (char *)p + comp->c_instance_private_data_offset;
|
||||
const struct fx_type_info *class_info = comp->c_type;
|
||||
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);
|
||||
if (class_info->ty_instance_fini) {
|
||||
class_info->ty_instance_fini(p, private_data);
|
||||
}
|
||||
|
||||
cur = fx_queue_prev(cur);
|
||||
|
||||
Reference in New Issue
Block a user