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