From 82bb20c6af93ea7bb1b298d1530523e1a213bf62 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 25 May 2026 17:24:47 +0100 Subject: [PATCH] fx.reflection: implement fx_property --- .../include/fx/reflection/property.h | 34 +++++ fx.reflection/property.c | 140 ++++++++++++++++++ 2 files changed, 174 insertions(+) diff --git a/fx.reflection/include/fx/reflection/property.h b/fx.reflection/include/fx/reflection/property.h index 4aabe4f..83c6b7a 100644 --- a/fx.reflection/include/fx/reflection/property.h +++ b/fx.reflection/include/fx/reflection/property.h @@ -1,4 +1,38 @@ #ifndef FX_REFLECTION_PROPERTY_H_ #define FX_REFLECTION_PROPERTY_H_ +#include +#include + +FX_DECLS_BEGIN; + +#define FX_REFLECTION_TYPE_PROPERTY (fx_property_get_type()) + +FX_DECLARE_TYPE(fx_property) + +FX_TYPE_CLASS_DECLARATION_BEGIN(fx_property) +FX_TYPE_CLASS_DECLARATION_END(fx_property) + +typedef fx_status ( + *fx_property_getter)(const fx_value *, const fx_property *, fx_value *); +typedef fx_status ( + *fx_property_setter)(fx_value *, const fx_property *, fx_value *); + +FX_API fx_type_id fx_property_get_type(void); + +FX_API fx_property *fx_property_create( + const char *name, + fx_property_getter get, + fx_property_setter set); + +FX_API const char *fx_property_get_name(const fx_property *prop); +FX_API fx_status fx_property_get_value( + const fx_property *prop, + const fx_value *container, + fx_value *out); +FX_API fx_status fx_property_set_value( + const fx_property *prop, + fx_value *container, + fx_value *new_value); + #endif diff --git a/fx.reflection/property.c b/fx.reflection/property.c index e69de29..6a624ca 100644 --- a/fx.reflection/property.c +++ b/fx.reflection/property.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include + +struct fx_property_p { + fx_property *prop_self; + char *prop_name; + fx_property_getter prop_getter; + fx_property_setter prop_setter; +}; + +/*** PRIVATE FUNCTIONS ********************************************************/ + +static const char *property_get_name(const struct fx_property_p *prop) +{ + return prop->prop_name; +} + +static fx_status property_get_value( + const struct fx_property_p *prop, + const fx_value *container, + fx_value *out) +{ + if (!prop->prop_getter) { + return FX_ERR_NOT_SUPPORTED; + } + + return prop->prop_getter(container, prop->prop_self, out); +} + +static fx_status property_set_value( + const struct fx_property_p *prop, + fx_value *container, + fx_value *new_value) +{ + if (!prop->prop_setter) { + return FX_ERR_NOT_SUPPORTED; + } + + return prop->prop_setter(container, prop->prop_self, new_value); +} + +/*** PUBLIC FUNCTIONS *********************************************************/ + +fx_property *fx_property_create( + const char *name, + fx_property_getter getter, + fx_property_setter setter) +{ + fx_property *prop = fx_object_create(FX_REFLECTION_TYPE_PROPERTY); + if (!prop) { + return NULL; + } + + struct fx_property_p *p = fx_object_get_private( + prop, + FX_REFLECTION_TYPE_PROPERTY); + + p->prop_name = fx_strdup(name); + if (!p->prop_name) { + fx_property_unref(prop); + return NULL; + } + + p->prop_self = prop; + p->prop_getter = getter; + p->prop_setter = setter; + + return prop; +} + +const char *fx_property_get_name(const fx_property *prop) +{ + FX_CLASS_DISPATCH_STATIC_0( + FX_REFLECTION_TYPE_PROPERTY, + property_get_name, + prop); +} + +fx_status fx_property_get_value( + const fx_property *prop, + const fx_value *container, + fx_value *out) +{ + FX_CLASS_DISPATCH_STATIC( + FX_REFLECTION_TYPE_PROPERTY, + property_get_value, + prop, + container, + out); +} + +fx_status fx_property_set_value( + const fx_property *prop, + fx_value *container, + fx_value *new_value) +{ + FX_CLASS_DISPATCH_STATIC( + FX_REFLECTION_TYPE_PROPERTY, + property_set_value, + prop, + container, + new_value); +} + +/*** VIRTUAL FUNCTIONS ********************************************************/ + +static void property_init(fx_object *obj, void *priv) +{ +} + +static void property_fini(fx_object *obj, void *priv) +{ + struct fx_property_p *p = priv; + if (p->prop_name) { + free(p->prop_name); + p->prop_name = NULL; + } +} + +/*** CLASS DEFINITION + * *********************************************************/ + +FX_TYPE_CLASS_BEGIN(fx_property) + FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) + FX_INTERFACE_ENTRY(to_string) = NULL; + FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT) +FX_TYPE_CLASS_END(fx_property) + +FX_TYPE_DEFINITION_BEGIN(fx_property) + FX_TYPE_ID(0x7007a5ef, 0x3caf, 0x4215, 0x8c0b, 0xd54bf8195624); + FX_TYPE_NAME("fx.reflection.property"); + FX_TYPE_CLASS(fx_property_class); + FX_TYPE_INSTANCE_PRIVATE(struct fx_property_p); + FX_TYPE_INSTANCE_INIT(property_init); + FX_TYPE_INSTANCE_FINI(property_fini); +FX_TYPE_DEFINITION_END(fx_property)