#include "../fx/type.h" #include #include #include struct fx_type_registration; #define FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR \ (fx_type_function_iterator_get_type()) #define FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR \ (fx_type_property_iterator_get_type()) FX_DECLARE_TYPE(fx_type_function_iterator); FX_DECLARE_TYPE(fx_type_property_iterator); FX_TYPE_CLASS_DECLARATION_BEGIN(fx_type_function_iterator) FX_TYPE_CLASS_DECLARATION_END(fx_type_function_iterator) FX_TYPE_CLASS_DECLARATION_BEGIN(fx_type_property_iterator) FX_TYPE_CLASS_DECLARATION_END(fx_type_property_iterator) FX_API fx_type_id fx_type_function_iterator_get_type(); FX_API fx_type_id fx_type_property_iterator_get_type(); struct fx_type_p { struct fx_type_info *ty_info; fx_assembly *ty_assembly; }; struct fx_type_function_iterator_p { struct fx_namemap *it_src; struct fx_namemap_entry *it_cur; }; struct fx_type_property_iterator_p { const fx_type_info *it_cur_type; struct fx_namemap *it_src; struct fx_namemap_entry *it_cur; }; /*** PRIVATE FUNCTIONS ********************************************************/ extern struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key); extern struct fx_type_info *fx_type_info_get_by_name(const char *name); extern fx_function *fx_type_info_get_function_by_name( const struct fx_type_info *ty, const char *name); static const fx_assembly *type_get_assembly(const struct fx_type_p *ty) { return ty->ty_assembly; } static fx_status type_set_assembly(struct fx_type_p *ty, fx_assembly *assembly) { ty->ty_assembly = assembly; return FX_SUCCESS; } static const char *type_get_name(const struct fx_type_p *ty) { return ty->ty_info->ty_name; } static fx_type_flags type_get_flags(const struct fx_type_p *ty) { return ty->ty_info->ty_flags; } const fx_function *type_get_function( const struct fx_type_p *ty, const char *name) { return fx_type_info_get_function_by_name(ty->ty_info, name); } fx_iterator *type_get_functions(const struct fx_type_p *ty) { fx_type_function_iterator *it_obj = fx_object_create( FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); struct fx_type_function_iterator_p *it = fx_object_get_private( it_obj, FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); it->it_src = &ty->ty_info->ty_functions; it->it_cur = fx_namemap_first(it->it_src); return it_obj; } const fx_property *type_get_property( const struct fx_type_p *ty, const char *name) { struct fx_type_info *cur = ty->ty_info; while (cur) { const fx_property *prop = fx_type_info_get_property_by_name( cur, name); if (prop) { return prop; } if (fx_type_id_compare(&cur->ty_id, FX_TYPE_OBJECT) == 0) { break; } cur = fx_type_info_get_by_id(&cur->ty_parent_id); } return NULL; } static fx_iterator *type_get_properties(const struct fx_type_p *ty) { fx_type_property_iterator *it_obj = fx_object_create( FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); struct fx_type_property_iterator_p *it = fx_object_get_private( it_obj, FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); it->it_cur_type = ty->ty_info; it->it_src = &ty->ty_info->ty_properties; it->it_cur = fx_namemap_first(it->it_src); while (!it->it_cur) { if (fx_type_id_compare(&it->it_cur_type->ty_id, FX_TYPE_OBJECT) == 0) { break; } const struct fx_type_info *next_type = fx_type_info_get_by_id( &it->it_cur_type->ty_parent_id); if (!next_type) { break; } it->it_cur_type = next_type; it->it_cur = fx_namemap_first(&it->it_cur_type->ty_properties); } if (!it->it_cur) { fx_iterator_set_status(it_obj, FX_ERR_NO_DATA); } return it_obj; } static fx_type_id type_get_id(const struct fx_type_p *ty) { return &ty->ty_info->ty_id; } static const fx_type *type_get_parent(const struct fx_type_p *ty) { if (fx_type_id_compare(&ty->ty_info->ty_id, FX_TYPE_OBJECT) == 0) { return NULL; } return fx_type_get_by_id(&ty->ty_info->ty_parent_id); } static void *type_get_interface( const struct fx_type_p *ty, fx_type_id interface_id) { return fx_class_get_interface(ty->ty_info->ty_class, interface_id); } /*** PUBLIC FUNCTIONS *********************************************************/ fx_type *__fx_type_create(struct fx_type_info *type_info) { fx_type *out = fx_object_create(FX_REFLECTION_TYPE_TYPE); if (!out) { return NULL; } struct fx_type_p *p = fx_object_get_private( out, FX_REFLECTION_TYPE_TYPE); p->ty_info = type_info; return out; } const fx_assembly *fx_type_get_assembly(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0( FX_REFLECTION_TYPE_TYPE, type_get_assembly, ty); } fx_status fx_type_set_assembly(fx_type *ty, fx_assembly *assembly) { FX_CLASS_DISPATCH_STATIC( FX_REFLECTION_TYPE_TYPE, type_set_assembly, ty, assembly); } const char *fx_type_get_name(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_name, ty); } fx_type_flags fx_type_get_flags(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_flags, ty); } const fx_function *fx_type_get_function(const fx_type *ty, const char *name) { FX_CLASS_DISPATCH_STATIC( FX_REFLECTION_TYPE_TYPE, type_get_function, ty, name); } fx_iterator *fx_type_get_functions(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0( FX_REFLECTION_TYPE_TYPE, type_get_functions, ty); } const fx_property *fx_type_get_property(const fx_type *ty, const char *name) { FX_CLASS_DISPATCH_STATIC( FX_REFLECTION_TYPE_TYPE, type_get_property, ty, name); } fx_iterator *fx_type_get_properties(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0( FX_REFLECTION_TYPE_TYPE, type_get_properties, ty); } const fx_type *fx_type_get_by_id(fx_type_id id) { struct fx_type_info *ty = fx_type_info_get_by_id(id); return ty ? ty->ty_metatype : NULL; } const fx_type *fx_type_get_by_name(const char *name) { struct fx_type_info *ty = fx_type_info_get_by_name(name); return ty ? ty->ty_metatype : NULL; } fx_type_id fx_type_get_id(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_id, ty); } const fx_type *fx_type_get_parent(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0( FX_REFLECTION_TYPE_TYPE, type_get_parent, ty); } void *fx_type_get_interface(const fx_type *ty, fx_type_id interface_id) { FX_CLASS_DISPATCH_STATIC( FX_REFLECTION_TYPE_TYPE, type_get_interface, ty, interface_id); } /*** VIRTUAL FUNCTIONS ********************************************************/ static void type_init(fx_object *obj, void *priv) { } static void type_fini(fx_object *obj, void *priv) { } /*** ITERATOR FUNCTIONS *******************************************************/ static enum fx_status function_iterator_move_next(const fx_iterator *obj) { struct fx_type_function_iterator_p *it = fx_object_get_private( obj, FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); if (!it->it_cur) { return FX_ERR_NO_DATA; } it->it_cur = fx_namemap_next(it->it_src, it->it_cur); return it->it_cur ? FX_SUCCESS : FX_ERR_NO_DATA; } static fx_value function_iterator_get_value(const fx_iterator *obj) { struct fx_type_function_iterator_p *it = fx_object_get_private( obj, FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); if (!it->it_cur) { return FX_VALUE_EMPTY; } struct fx_type_function *func = fx_unbox( struct fx_type_function, it->it_cur, f_entry); return FX_VALUE_OBJECT(func->f_func); } static enum fx_status property_iterator_move_next(const fx_iterator *obj) { struct fx_type_property_iterator_p *it = fx_object_get_private( obj, FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); if (!it->it_cur) { return FX_ERR_NO_DATA; } it->it_cur = fx_namemap_next(it->it_src, it->it_cur); if (!it->it_cur) { if (fx_type_id_compare(&it->it_cur_type->ty_id, FX_TYPE_OBJECT) == 0) { return FX_ERR_NO_DATA; } const struct fx_type_info *next_type = fx_type_info_get_by_id( &it->it_cur_type->ty_parent_id); if (!next_type) { return FX_ERR_NO_DATA; } it->it_cur_type = next_type; it->it_cur = fx_namemap_first(&it->it_cur_type->ty_properties); } return it->it_cur ? FX_SUCCESS : FX_ERR_NO_DATA; } static fx_value property_iterator_get_value(const fx_iterator *obj) { struct fx_type_property_iterator_p *it = fx_object_get_private( obj, FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); if (!it->it_cur) { return FX_VALUE_EMPTY; } struct fx_type_property *prop = fx_unbox( struct fx_type_property, it->it_cur, p_entry); return FX_VALUE_OBJECT(prop->p_prop); } /*** CLASS DEFINITION *********************************************************/ FX_TYPE_CLASS_BEGIN(fx_type) FX_TYPE_CLASS_END(fx_type) FX_TYPE_DEFINITION_BEGIN(fx_type) FX_TYPE_ID(0xec8b2679, 0x5c73, 0x4ec9, 0xa04e, 0x3f72881b5b5a); FX_TYPE_NAME("fx.reflection.type"); FX_TYPE_CLASS(fx_type_class); FX_TYPE_INSTANCE_PRIVATE(struct fx_type_p); FX_TYPE_INSTANCE_INIT(type_init); FX_TYPE_INSTANCE_FINI(type_fini); FX_TYPE_DEFINITION_END(fx_type) FX_TYPE_CLASS_BEGIN(fx_type_function_iterator) FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterator, FX_TYPE_ITERATOR) FX_INTERFACE_ENTRY(it_move_next) = function_iterator_move_next; FX_INTERFACE_ENTRY(it_erase) = NULL; FX_INTERFACE_ENTRY(it_get_value) = function_iterator_get_value; FX_TYPE_VTABLE_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR) FX_TYPE_CLASS_END(fx_type_function_iterator) FX_TYPE_DEFINITION_BEGIN(fx_type_function_iterator) FX_TYPE_ID(0xb29012d5, 0x4d6c, 0x4e3c, 0x9fe5, 0x7d1a8a9e1075); FX_TYPE_NAME("fx.reflection.type.function_iterator"); FX_TYPE_EXTENDS(FX_TYPE_ITERATOR); FX_TYPE_CLASS(fx_type_class); FX_TYPE_INSTANCE_PRIVATE(struct fx_type_function_iterator_p); FX_TYPE_DEFINITION_END(fx_type_function_iterator) FX_TYPE_CLASS_BEGIN(fx_type_property_iterator) FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterator, FX_TYPE_ITERATOR) FX_INTERFACE_ENTRY(it_move_next) = property_iterator_move_next; FX_INTERFACE_ENTRY(it_erase) = NULL; FX_INTERFACE_ENTRY(it_get_value) = property_iterator_get_value; FX_TYPE_VTABLE_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR) FX_TYPE_CLASS_END(fx_type_property_iterator) FX_TYPE_DEFINITION_BEGIN(fx_type_property_iterator) FX_TYPE_ID(0x91fcbdd4, 0x7c54, 0x48c2, 0xa5a4, 0x186f76efd84c); FX_TYPE_NAME("fx.reflection.type.property_iterator"); FX_TYPE_EXTENDS(FX_TYPE_ITERATOR); FX_TYPE_CLASS(fx_type_property_iterator_class); FX_TYPE_INSTANCE_PRIVATE(struct fx_type_property_iterator_p); FX_TYPE_DEFINITION_END(fx_type_property_iterator)