From 9fc354e06680895d0e7398ee1022943052cdc65c Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Sat, 25 Sep 2010 21:00:24 +0200 Subject: Implement a few bits of LdLua. Some comments in the source code have been updated. --- src/ld-lua-symbol.c | 2 + src/ld-lua.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++------ src/ld-lua.h | 5 +- 3 files changed, 147 insertions(+), 19 deletions(-) diff --git a/src/ld-lua-symbol.c b/src/ld-lua-symbol.c index 9b87f72..1278756 100644 --- a/src/ld-lua-symbol.c +++ b/src/ld-lua-symbol.c @@ -49,6 +49,8 @@ ld_lua_symbol_class_init (LdLuaSymbolClass *klass) object_class = G_OBJECT_CLASS (klass); object_class->finalize = ld_lua_symbol_finalize; + /* TODO: Override the "draw" method of LdSymbol. */ + g_type_class_add_private (klass, sizeof (LdLuaSymbolPrivate)); } diff --git a/src/ld-lua.c b/src/ld-lua.c index e5b6c78..4440356 100644 --- a/src/ld-lua.c +++ b/src/ld-lua.c @@ -17,6 +17,7 @@ #include "ld-library.h" #include "ld-symbol-category.h" +#include "ld-symbol.h" #include "ld-lua.h" @@ -27,13 +28,11 @@ * * #LdLua is a symbol engine that uses Lua scripts to manage symbols. */ -/* Lua state belongs to the library. - * One Lua file should be able to register multiple symbols. - */ /* How does the application call the function for rendering? * logdiag.symbols -- readonly table (from lua) -- this can be probably * accomplished using a custom metatable that errors out on newindex, * items will be added to this table only in C. + * It can also be placed into the Lua registry. * logdiag.symbols[ident].render(cr) -- here "ident" is the full path * to this symbol * logdiag.symbols[ident].names[lang, area, terminals] -- these @@ -59,6 +58,31 @@ static void ld_lua_finalize (GObject *gobject); static void *ld_lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize); +/* + * LdLuaData: + * @self: A reference to self. + * @category: A reference to parent category of the currently processed file. + * + * Full user data to be stored in Lua registry. + */ +typedef struct +{ + LdLua *self; + LdSymbolCategory *category; +} +LdLuaData; + +#define LD_LUA_LIBRARY_NAME "logdiag" +#define LD_LUA_DATA_INDEX LD_LUA_LIBRARY_NAME "_data" + +#define LD_LUA_RETRIEVE_DATA(L) \ +( \ + lua_pushliteral ((L), LD_LUA_DATA_INDEX), \ + lua_gettable ((L), LUA_REGISTRYINDEX), \ + lua_touserdata ((L), -1) \ +) + + static int ld_lua_logdiag_register (lua_State *L); static luaL_Reg ld_lua_logdiag_lib[] = @@ -104,6 +128,7 @@ static void ld_lua_init (LdLua *self) { lua_State *L; + LdLuaData *ud; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, LD_TYPE_LUA, LdLuaPrivate); @@ -124,7 +149,16 @@ ld_lua_init (LdLua *self) lua_call (L, 0, 0); /* Load the application library. */ - luaL_register (L, "logdiag", ld_lua_logdiag_lib); + luaL_register (L, LD_LUA_LIBRARY_NAME, ld_lua_logdiag_lib); + + /* Store user data to the registry. */ + lua_pushliteral (L, LD_LUA_DATA_INDEX); + + ud = lua_newuserdata (L, sizeof (LdLuaData)); + ud->self = self; + ud->category = NULL; + + lua_settable (L, LUA_REGISTRYINDEX); } static void @@ -141,10 +175,8 @@ ld_lua_finalize (GObject *gobject) /** * ld_lua_new: - * @library: A library object. - * @filename: The file from which the symbol will be loaded. * - * Load a symbol from a file into the library. + * Create an instance of #LdLua. */ LdLua * ld_lua_new (void) @@ -164,22 +196,83 @@ ld_lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize) return g_try_realloc (ptr, nsize); } +/** + * ld_lua_check_file: + * @self: An #LdLua object. + * @filename: The file to be checked. + * + * Check if the given filename can be loaded by #LdLua. + */ +gboolean ld_lua_check_file (LdLua *self, const gchar *filename) +{ + g_return_val_if_fail (LD_IS_LUA (self), FALSE); + return g_str_has_suffix (filename, ".lua"); +} + +/** + * ld_lua_load_file_to_category: + * @self: An #LdLua object. + * @filename: The file to be loaded. + * @category: An #LdSymbolCategory object. + * + * Loads a file and appends contained symbols into the category. + * + * Returns: TRUE if no error has occured, FALSE otherwise. + */ +gboolean ld_lua_load_file_to_category (LdLua *self, const gchar *filename, + LdSymbolCategory *category) +{ + gint retval; + LdLuaData *ud; + + g_return_val_if_fail (LD_IS_LUA (self), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (LD_IS_SYMBOL_CATEGORY (category), FALSE); + + /* TODO: Error reporting. */ + + ud = LD_LUA_RETRIEVE_DATA (self->priv->L); + g_return_val_if_fail (ud != NULL, FALSE); + + ud->category = category; + + retval = luaL_loadfile (self->priv->L, filename); + if (retval) + goto ld_lua_lftc_fail; + + retval = lua_pcall (self->priv->L, 0, 0, 0); + if (retval) + goto ld_lua_lftc_fail; + + ud->category = NULL; + return TRUE; + +ld_lua_lftc_fail: + ud->category = NULL; + return FALSE; +} + /* ===== Application library =============================================== */ static int ld_lua_logdiag_register (lua_State *L) { + LdLuaData *ud; + LdSymbol *symbol; + + ud = LD_LUA_RETRIEVE_DATA (L); + g_return_val_if_fail (ud != NULL, 0); + /* TODO: Create a symbol. */ - /* XXX: Shouldn't this function be a closure with LdLibrary userdata? - * It is also possible to have the userdata in the "logdiag" table. + /* XXX: Does ld_lua_symbol_new really need to be passed the category here? + * The symbol can have just a weak reference to the category. */ -#if 0 - lua_newtable (L); - - /* TODO: Push a function. */ - lua_call (L, 1, 0); -#endif /* 0 */ +/* + symbol = ld_lua_symbol_new (ud->category, ud->self); + ld_symbol_category_insert (ud->category, symbol, -1); + g_object_unref (symbol); +*/ return 0; } @@ -207,40 +300,74 @@ push_cairo_object (lua_State *L, cairo_t *cr) } } -/* TODO: Implement the functions. */ +/* TODO: More functions. Possibly put it into another file + * and generate it automatically. + */ static int ld_lua_cairo_move_to (lua_State *L) { + cairo_t *cr; + lua_Number x, y; + + cr = lua_touserdata (L, lua_upvalueindex (1)); + + x = luaL_checknumber (L, 1); + y = luaL_checknumber (L, 2); + + cairo_move_to (cr, x, y); return 0; } static int ld_lua_cairo_line_to (lua_State *L) { + cairo_t *cr; + lua_Number x, y; + + cr = lua_touserdata (L, lua_upvalueindex (1)); + x = luaL_checknumber (L, 1); + y = luaL_checknumber (L, 2); + cairo_line_to (cr, x, y); return 0; } static int ld_lua_cairo_stroke (lua_State *L) { + cairo_t *cr; + + cr = lua_touserdata (L, lua_upvalueindex (1)); + cairo_stroke (cr); return 0; } static int ld_lua_cairo_stroke_preserve (lua_State *L) { + cairo_t *cr; + + cr = lua_touserdata (L, lua_upvalueindex (1)); + cairo_stroke_preserve (cr); return 0; } static int ld_lua_cairo_fill (lua_State *L) { + cairo_t *cr; + + cr = lua_touserdata (L, lua_upvalueindex (1)); + cairo_fill (cr); return 0; } static int ld_lua_cairo_fill_preserve (lua_State *L) { + cairo_t *cr; + + cr = lua_touserdata (L, lua_upvalueindex (1)); + cairo_fill_preserve (cr); return 0; } diff --git a/src/ld-lua.h b/src/ld-lua.h index 512143e..c7f45d0 100644 --- a/src/ld-lua.h +++ b/src/ld-lua.h @@ -51,9 +51,8 @@ struct _LdLuaClass GType ld_lua_get_type (void) G_GNUC_CONST; LdLua *ld_lua_new (void); -/* TODO: Implement the following: */ -gboolean ld_lua_check_file (LdLua *lua, const gchar *filename); -gboolean ld_lua_load_file_to_category (LdLua *lua, const gchar *filename, +gboolean ld_lua_check_file (LdLua *self, const gchar *filename); +gboolean ld_lua_load_file_to_category (LdLua *self, const gchar *filename, LdSymbolCategory *category); -- cgit v1.2.3-70-g09d2