diff --git a/common/luaclass.c b/common/luaclass.c index 329e38e9b..b5fda74dd 100644 --- a/common/luaclass.c +++ b/common/luaclass.c @@ -22,6 +22,20 @@ #include "common/luaclass.h" #include "common/luaobject.h" +struct lua_class_property +{ + /** ID matching the property */ + awesome_token_t id; + /** Name of the property */ + const char *name; + /** Callback function called when the property is found in object creation. */ + lua_class_propfunc_t new; + /** Callback function called when the property is found in object __index. */ + lua_class_propfunc_t index; + /** Callback function called when the property is found in object __newindex. */ + lua_class_propfunc_t newindex; +}; + typedef struct { int id; @@ -85,6 +99,33 @@ luaA_openlib(lua_State *L, const char *name, lua_pop(L, 2); } +static int +lua_class_property_cmp(const void *a, const void *b) +{ + const lua_class_property_t *x = a, *y = b; + return x->id > y->id ? 1 : (x->id < y->id ? -1 : 0); +} + +BARRAY_FUNCS(lua_class_property_t, lua_class_property, DO_NOTHING, lua_class_property_cmp) + +void +luaA_class_add_property(lua_class_t *lua_class, + awesome_token_t token, + const char *name, + lua_class_propfunc_t cb_new, + lua_class_propfunc_t cb_index, + lua_class_propfunc_t cb_newindex) +{ + lua_class_property_array_insert(&lua_class->properties, (lua_class_property_t) + { + .id = token, + .name = name, + .new = cb_new, + .index = cb_index, + .newindex = cb_newindex + }); +} + void luaA_class_setup(lua_State *L, lua_class_t *class, const char *name, diff --git a/common/luaclass.h b/common/luaclass.h index f04f48e78..6a6b2ebb4 100644 --- a/common/luaclass.h +++ b/common/luaclass.h @@ -23,6 +23,11 @@ #define AWESOME_COMMON_LUACLASS #include "common/signal.h" +#include "common/tokenize.h" + +typedef struct lua_class_property lua_class_property_t; + +ARRAY_TYPE(lua_class_property_t, lua_class_property) #define LUA_OBJECT_HEADER \ signal_array_t signals; @@ -44,8 +49,12 @@ typedef struct signal_array_t signals; /** Allocator for creating new objects of that class */ lua_class_allocator_t allocator; + /** Class properties */ + lua_class_property_array_t properties; } lua_class_t; +typedef int (*lua_class_propfunc_t)(lua_State *, lua_object_t *); + int luaA_type(lua_State *, int); const char * luaA_typename(lua_State *, int); @@ -57,6 +66,9 @@ void luaA_openlib(lua_State *, const char *, const struct luaL_reg[], const stru void luaA_class_setup(lua_State *, lua_class_t *, const char *, lua_class_allocator_t, const struct luaL_reg[], const struct luaL_reg[]); +void luaA_class_add_property(lua_class_t *, awesome_token_t, const char *, + lua_class_propfunc_t, lua_class_propfunc_t, lua_class_propfunc_t); + #define LUA_CLASS_FUNCS(prefix, lua_class) \ static inline int \ luaA_##prefix##_class_add_signal(lua_State *L) \ diff --git a/common/luaobject.h b/common/luaobject.h index faa379447..7bebcc220 100644 --- a/common/luaobject.h +++ b/common/luaobject.h @@ -200,6 +200,13 @@ int luaA_object_emit_signal_simple(lua_State *); return 1; \ } +#define LUA_OBJECT_EXPORT_PROPERTY(pfx, type, field, pusher) \ + static int \ + luaA_##pfx##_get_##field(lua_State *L, type *object) \ + { \ + pusher(L, object->field); \ + return 1; \ + } /** Garbage collect a Lua object. * \param L The Lua VM state.