2 * luaobject.h - useful functions for handling Lua objects
4 * Copyright © 2009 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifndef AWESOME_COMMON_LUAOBJECT
23 #define AWESOME_COMMON_LUAOBJECT
25 #include "common/luaclass.h"
28 #define LUAA_OBJECT_REGISTRY_KEY "awesome.object.registry"
30 int luaA_settype(lua_State
*, lua_class_t
*);
31 void luaA_object_setup(lua_State
*);
32 void * luaA_object_incref(lua_State
*, int, int);
33 void luaA_object_decref(lua_State
*, int, const void *);
35 /** Store an item in the environment table of an object.
36 * \param L The Lua VM state.
37 * \param ud The index of the object on the stack.
38 * \param iud The index of the item on the stack.
39 * \return The item reference.
42 luaA_object_ref_item(lua_State
*L
, int ud
, int iud
)
44 /* Get the env table from the object */
45 luaA_getuservalue(L
, ud
);
46 void *pointer
= luaA_object_incref(L
, -1, iud
< 0 ? iud
- 1 : iud
);
47 /* Remove env table */
52 /** Unref an item from the environment table of an object.
53 * \param L The Lua VM state.
54 * \param ud The index of the object on the stack.
58 luaA_object_unref_item(lua_State
*L
, int ud
, void *pointer
)
60 /* Get the env table from the object */
61 luaA_getuservalue(L
, ud
);
63 luaA_object_decref(L
, -1, pointer
);
64 /* Remove env table */
68 /** Push an object item on the stack.
69 * \param L The Lua VM state.
70 * \param ud The object index on the stack.
71 * \param pointer The item pointer.
72 * \return The number of element pushed on stack.
75 luaA_object_push_item(lua_State
*L
, int ud
, const void *pointer
)
77 /* Get env table of the object */
78 luaA_getuservalue(L
, ud
);
80 lua_pushlightuserdata(L
, (void *) pointer
);
83 /* Remove env table */
89 luaA_object_registry_push(lua_State
*L
)
91 lua_pushliteral(L
, LUAA_OBJECT_REGISTRY_KEY
);
92 lua_rawget(L
, LUA_REGISTRYINDEX
);
95 /** Reference an object and return a pointer to it.
96 * That only works with userdata, table, thread or function.
97 * \param L The Lua VM state.
98 * \param oud The object index on the stack.
99 * \return The object reference, or NULL if not referenceable.
102 luaA_object_ref(lua_State
*L
, int oud
)
104 luaA_object_registry_push(L
);
105 void *p
= luaA_object_incref(L
, -1, oud
< 0 ? oud
- 1 : oud
);
110 /** Reference an object and return a pointer to it checking its type.
111 * That only works with userdata.
112 * \param L The Lua VM state.
113 * \param oud The object index on the stack.
114 * \param class The class of object expected
115 * \return The object reference, or NULL if not referenceable.
118 luaA_object_ref_class(lua_State
*L
, int oud
, lua_class_t
*class)
120 luaA_checkudata(L
, oud
, class);
121 return luaA_object_ref(L
, oud
);
124 /** Unreference an object and return a pointer to it.
125 * That only works with userdata, table, thread or function.
126 * \param L The Lua VM state.
127 * \param oud The object index on the stack.
130 luaA_object_unref(lua_State
*L
, const void *pointer
)
132 luaA_object_registry_push(L
);
133 luaA_object_decref(L
, -1, pointer
);
137 /** Push a referenced object onto the stack.
138 * \param L The Lua VM state.
139 * \param pointer The object to push.
140 * \return The number of element pushed on stack.
143 luaA_object_push(lua_State
*L
, const void *pointer
)
145 luaA_object_registry_push(L
);
146 lua_pushlightuserdata(L
, (void *) pointer
);
152 void signal_object_emit(lua_State
*, signal_array_t
*, const char *, int);
154 void luaA_object_connect_signal(lua_State
*, int, const char *, lua_CFunction
);
155 void luaA_object_disconnect_signal(lua_State
*, int, const char *, lua_CFunction
);
156 void luaA_object_connect_signal_from_stack(lua_State
*, int, const char *, int);
157 void luaA_object_disconnect_signal_from_stack(lua_State
*, int, const char *, int);
158 void luaA_object_emit_signal(lua_State
*, int, const char *, int);
160 int luaA_object_connect_signal_simple(lua_State
*);
161 int luaA_object_disconnect_signal_simple(lua_State
*);
162 int luaA_object_emit_signal_simple(lua_State
*);
164 #define LUA_OBJECT_FUNCS(lua_class, type, prefix) \
165 LUA_CLASS_FUNCS(prefix, lua_class) \
166 static inline type * \
167 prefix##_new(lua_State *L) \
169 type *p = lua_newuserdata(L, sizeof(type)); \
171 (lua_class).instances++; \
172 luaA_settype(L, &(lua_class)); \
175 lua_setmetatable(L, -2); \
176 luaA_setuservalue(L, -2); \
177 lua_pushvalue(L, -1); \
178 /** @todo This is wrong we shouldn't copy the existing signals from */ \
179 /* the class, but I'm too lazy for doing this correctly right now. */ \
180 foreach(sig, (lua_class).signals) \
182 signal_t s = { .id = sig->id }; \
183 signal_array_insert(&p->signals, s); \
185 luaA_class_emit_signal(L, &(lua_class), "new", 1); \
189 #define OBJECT_EXPORT_PROPERTY(pfx, type, field) \
190 fieldtypeof(type, field) \
191 pfx##_get_##field(type *object) \
193 return object->field; \
196 #define LUA_OBJECT_EXPORT_PROPERTY(pfx, type, field, pusher) \
198 luaA_##pfx##_get_##field(lua_State *L, type *object) \
200 pusher(L, object->field); \
204 int luaA_object_tostring(lua_State
*);
206 #define LUA_OBJECT_META(prefix) \
207 { "__tostring", luaA_object_tostring }, \
208 { "connect_signal", luaA_object_connect_signal_simple }, \
209 { "disconnect_signal", luaA_object_disconnect_signal_simple }, \
210 { "emit_signal", luaA_object_emit_signal_simple },
214 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80