fx.reflection: implement fx_property
This commit is contained in:
@@ -1,4 +1,38 @@
|
|||||||
#ifndef FX_REFLECTION_PROPERTY_H_
|
#ifndef FX_REFLECTION_PROPERTY_H_
|
||||||
#define FX_REFLECTION_PROPERTY_H_
|
#define FX_REFLECTION_PROPERTY_H_
|
||||||
|
|
||||||
|
#include <fx/macros.h>
|
||||||
|
#include <fx/value.h>
|
||||||
|
|
||||||
|
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
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#include <fx/macros.h>
|
||||||
|
#include <fx/reflection/property.h>
|
||||||
|
#include <fx/string.h>
|
||||||
|
#include <fx/value-type.h>
|
||||||
|
#include <fx/value.h>
|
||||||
|
#include <platform/callvm.h>
|
||||||
|
|
||||||
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user