-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | agg-plot/canvas-window.cpp | 6 | ||||
-rw-r--r-- | agg-plot/lua-plot-cpp.h | 3 | ||||
-rw-r--r-- | agg-plot/lua-plot.cpp | 6 | ||||
-rw-r--r-- | agg-plot/split-spec-parser.h | 35 | ||||
-rw-r--r-- | agg-plot/window-cpp.h | 14 | ||||
-rw-r--r-- | agg-plot/window.cpp | 103 | ||||
-rw-r--r-- | gsl-shell.c | 11 | ||||
-rw-r--r-- | lua-gsl.c | 4 | ||||
-rw-r--r-- | object-index.c | 94 | ||||
-rw-r--r-- | object-index.h | 24 | ||||
-rw-r--r-- | object-refs.c | 62 | ||||
-rw-r--r-- | object-refs.h | 3 | ||||
-rw-r--r-- | window-refs.c | 83 | ||||
-rw-r--r-- | window-refs.h | 19 |
@@ -76,7 +76,7 @@ else endif ifeq ($(strip $(ENABLE_AGG_PLOT)), yes) - C_SRC_FILES += window-refs.c object-refs.c + C_SRC_FILES += object-index.c object-refs.c INCLUDES += $(PTHREADS_CFLAGS) -Iagg-plot SUBDIRS += agg-plot DEFS += -DAGG_PLOT_ENABLED diff --git a/agg-plot/canvas-window.cpp b/agg-plot/canvas-window.cpp index 9302b46e..a997c4b7 100644 --- a/agg-plot/canvas-window.cpp +++ b/agg-plot/canvas-window.cpp @@ -31,7 +31,7 @@ extern "C" { #include "agg-parse-trans.h" #include "lua-cpp-utils.h" #include "lua-utils.h" -#include "window-refs.h" +#include "object-index.h" #include "lua-draw.h" #include "gs-types.h" #include "colors.h" @@ -109,7 +109,7 @@ canvas_window::start_new_thread (lua_State *L) if (status != not_ready && status != closed) return; - this->id = window_ref_add (L, lua_gettop (L)); + this->id = object_index_add (L, OBJECT_WINDOW, -1); pthread_attr_t attr[1]; pthread_t win_thread[1]; @@ -121,7 +121,7 @@ canvas_window::start_new_thread (lua_State *L) if (pthread_create(win_thread, attr, canvas_thread_function, (void*) this)) { - window_ref_remove (L, this->id); + object_index_remove (L, OBJECT_WINDOW, this->id); pthread_attr_destroy (attr); this->status = canvas_window::error; diff --git a/agg-plot/lua-plot-cpp.h b/agg-plot/lua-plot-cpp.h index 5e318dd0..6bfbe751 100644 --- a/agg-plot/lua-plot-cpp.h +++ b/agg-plot/lua-plot-cpp.h @@ -19,7 +19,7 @@ private: plot_type m_plot; public: - lua_plot() : m_plot(), id(-1) { }; + lua_plot() : m_plot(), window_id(-1), id(-1) { }; void update_window(lua_State *L); @@ -27,6 +27,7 @@ public: static lua_plot *check(lua_State *L, int index); + int window_id; int id; }; diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp index 5f780f88..ae046e38 100644 --- a/agg-plot/lua-plot.cpp +++ b/agg-plot/lua-plot.cpp @@ -25,7 +25,7 @@ extern "C" { #include "lua-plot.h" #include "lua-plot-cpp.h" -#include "window-refs.h" +#include "object-index.h" #include "window.h" #include "gs-types.h" #include "lua-utils.h" @@ -94,7 +94,7 @@ lua_plot::check(lua_State *L, int index) void lua_plot::update_window(lua_State *L) { - window_ref_get (L, this->id); + object_index_get (L, OBJECT_WINDOW, this->window_id); if (gs_is_userdata (L, lua_gettop (L), GS_WINDOW)) { @@ -120,6 +120,8 @@ plot_new (lua_State *L) p->self().set_title(title); } + p->id = object_index_add (L, OBJECT_PLOT, -1); + return 1; } diff --git a/agg-plot/split-spec-parser.h b/agg-plot/split-spec-parser.h index 1ccae7c6..dd2aee75 100644 --- a/agg-plot/split-spec-parser.h +++ b/agg-plot/split-spec-parser.h @@ -12,27 +12,36 @@ enum direction_e { along_x, along_y }; namespace split { template <class base_type> - class node { - public: + struct node { typedef pod_list<node*> list; + virtual void transform(matrix& m) = 0; + virtual list* tree() { return 0; }; virtual base_type* content() { return 0; }; virtual void content(const base_type& src) { }; - virtual void transform(matrix& m) = 0; virtual matrix* get_matrix() { return 0; }; virtual ~node() {}; + + static void init(node* tree); }; template <class base_type> + void node<base_type>::init(node<base_type>* tree) + { + matrix m; + tree->transform(m); + } + + template <class base_type> class node_leaf : public node<base_type> { base_type m_content; matrix m_matrix; public: - node_leaf(const base_type& src) : m_content(src), m_matrix() {}; + node_leaf() : m_content(), m_matrix() {}; virtual base_type* content() { return &m_content; }; virtual void content(const base_type& src) { m_content = src; }; @@ -116,17 +125,17 @@ namespace split { }; template <class base_type, class lexer> - extern node<base_type>* parse (lexer& lex, const base_type& seed); + extern node<base_type>* parse (lexer& lex); template <class base_type, class lexer> - node<base_type>* subtree (lexer& lex, const base_type& seed, direction_e dir) + node<base_type>* subtree (lexer& lex, direction_e dir) { node_tree<base_type> * ls = new node_tree<base_type>(dir); int c; for (c = 0; ; c++) { - node<base_type>* child = parse<base_type, lexer>(lex, seed); + node<base_type>* child = parse<base_type, lexer>(lex); if (! child) break; ls->add(child); @@ -138,25 +147,23 @@ namespace split { } template <class base_type, class lexer> - node<base_type>* parse (lexer& lex, const base_type& seed) + node<base_type>* parse (lexer& lex) { char t = lex.next(); switch (t) { case '.': - return new node_leaf<base_type>(seed); + return new node_leaf<base_type>(); case 'h': - return subtree<base_type, lexer>(lex, seed, along_x); + return subtree<base_type, lexer>(lex, along_x); case 'v': - return subtree<base_type, lexer>(lex, seed, along_y); + return subtree<base_type, lexer>(lex, along_y); case '(': { - node<base_type> *nd = parse<base_type, lexer>(lex, seed); - + node<base_type> *nd = parse<base_type, lexer>(lex); if (! lex.checknext(')')) return NULL; - return nd; } case ')': diff --git a/agg-plot/window-cpp.h b/agg-plot/window-cpp.h index 44beaa30..e5d6292e 100644 --- a/agg-plot/window-cpp.h +++ b/agg-plot/window-cpp.h @@ -19,9 +19,17 @@ extern "C" { class window : public canvas_window { typedef plot<drawable, lua_management> plot_type; - split::node<plot_type*>* m_tree; + struct ref { + plot_type *plot; + int id; - void draw_rec(split::node<plot_type*> *n); + ref() : plot(0), id(-1) {}; + ref(plot_type *p, int _id) : plot(p), id(_id) {}; + }; + + split::node<ref>* m_tree; + + void draw_rec(split::node<ref> *n); public: window(agg::rgba& bgcol) : canvas_window(bgcol), m_tree(0) {}; @@ -31,7 +39,7 @@ public: static window *check (lua_State *L, int index); void split(const char *spec); - bool attach(lua_plot *plot, const char *spec); + int attach(lua_plot *plot, const char *spec, int id); void on_draw_unprotected(); virtual void on_draw(); diff --git a/agg-plot/window.cpp b/agg-plot/window.cpp index ba9cd088..f5864eca 100644 --- a/agg-plot/window.cpp +++ b/agg-plot/window.cpp @@ -9,6 +9,7 @@ extern "C" { #include "lua-cpp-utils.h" #include "gs-types.h" #include "object-refs.h" +#include "object-index.h" #include "colors.h" #include "lua-plot-cpp.h" #include "split-spec-parser.h" @@ -36,21 +37,21 @@ static const struct luaL_Reg window_methods[] = { __END_DECLS void -window::draw_rec(split::node<plot_type*> *n) +window::draw_rec(split::node<ref> *n) { - split::node<plot_type*>::list *ls; + split::node<ref>::list *ls; for (ls = n->tree(); ls != NULL; ls = ls->next()) draw_rec(ls->content()); - plot_type **p = n->content(); + ref *ref = n->content(); matrix* m = n->get_matrix(); - if (p && m) + if (ref && m) { - if (*p) + if (ref->plot) { agg::trans_affine mtx(*m); m_canvas->premultiply(mtx); - (*p)->draw(*m_canvas, mtx); + ref->plot->draw(*m_canvas, mtx); } } } @@ -61,11 +62,9 @@ window::on_draw_unprotected() if (! m_canvas) return; + m_canvas->clear(); if (m_tree) - { - m_canvas->clear(); - draw_rec(m_tree); - } + draw_rec(m_tree); } void @@ -82,48 +81,12 @@ window::check (lua_State *L, int index) return (window *) gs_check_userdata (L, index, GS_WINDOW); } -/* -static void -set_matrix(agg::trans_affine& m, double x, double y, double sx, double sy) -{ - m.tx = x; - m.ty = y; - m.sx = sx; - m.sy = sy; -} - -typedef pod_list<plot_matrix> pm_list; - -pm_list * build_list(node *tree) -{ - pm_list *ls = NULL; - - node_list *childs = tree->get_tree(); - for ( ; childs != NULL; childs = childs->next()) - { - pm_list *sub = build_list(childs->content()); - ls = pm_list::push_back(ls, sub); - } - - matrix *m = tree->get_matrix(); - if (m) - { - plot_matrix pm(NULL, *m); - ls = new pm_list(pm, ls); - } - - return ls; -} -*/ - void window::split(const char *spec) { split::string_lexer lexbuf(spec); - m_tree = split::parse<plot_type*, split::string_lexer>(lexbuf, (plot_type*) 0); - - agg::trans_affine m; - m_tree->transform(m); + m_tree = split::parse<ref, split::string_lexer>(lexbuf); + split::node<ref>::init(m_tree); } static const char * @@ -147,28 +110,40 @@ next_int (const char *str, int& val) return eptr; } -bool -window::attach(lua_plot *plot, const char *spec) +/* Returns the existing plot ref id, 0 if there isn't any. + It does return -1 in case of error.*/ +int window::attach(lua_plot *plot, const char *spec, int id) { - split::node<plot_type*> *n = m_tree; + split::node<ref> *n = m_tree; const char *ptr; int k; for (ptr = next_int (spec, k); ptr; ptr = next_int (ptr, k)) { - split::node<plot_type*>::list* list = n->tree(); + split::node<ref>::list* list = n->tree(); if (! list) - break; + return -1; - for (int j = 1; j < k && list; j++) - list = list->next(); + for (int j = 1; j < k; j++) + { + list = list->next(); + if (! list) + return -1; + } n = list->content(); } - n->content(& plot->self()); - return true; + ref* ex_ref = n->content(); + if (! ex_ref) + return -1; + int ex_id = ex_ref->id; + + ref new_ref(& plot->self(), id); + n->content(new_ref); + + return (ex_id > 0 ? ex_id : 0); } int @@ -208,9 +183,11 @@ window_attach (lua_State *L) win->lock(); - if (win->attach (plot, spec)) + int ex_plot_id = win->attach (plot, spec, plot->id); + + if (ex_plot_id >= 0) { - plot->id = win->id; + plot->window_id = win->id; win->on_draw(); win->update_window(); @@ -218,6 +195,14 @@ window_attach (lua_State *L) win->unlock(); object_ref_add (L, 1, 2); + + if (ex_plot_id > 0) + { + object_index_get (L, OBJECT_PLOT, ex_plot_id); + int plot_index = lua_gettop (L); + if (gs_is_userdata (L, plot_index, GS_PLOT)) + object_ref_remove (L, 1, plot_index); + } } else { diff --git a/gsl-shell.c b/gsl-shell.c index 774f5838..a271d0ae 100644 --- a/gsl-shell.c +++ b/gsl-shell.c @@ -62,7 +62,8 @@ #include "gsl-shell.h" #include "lua-gsl.h" #include "lua-utils.h" -#include "window-refs.h" +#include "object-index.h" +#include "canvas-window.h" #define report error_report @@ -338,14 +339,14 @@ static void do_windows_unref (lua_State *L) GSL_SHELL_LOCK(); for (j = 0; j < unref_fixed_count; j++) - window_ref_remove (L, unref_fixed_list[j]); + object_index_remove (L, OBJECT_WINDOW, unref_fixed_list[j]); unref_fixed_count = 0; for (wu = window_unref_list; wu != NULL; /* */) { struct window_unref_cell *nxt = wu->next; - window_ref_remove (L, wu->id); + object_index_remove (L, OBJECT_WINDOW, wu->id); free (wu); wu = nxt; } @@ -381,11 +382,11 @@ static void dotty (lua_State *L) { do_windows_unref (L); } - window_ref_close_all (L); + object_index_apply_all (L, OBJECT_WINDOW, canvas_window_close_protected); do { do_windows_unref (L); - } while (window_ref_count (L) > 0); + } while (object_index_count (L, OBJECT_WINDOW) > 0); lua_settop(L, 0); /* clear stack */ @@ -45,7 +45,7 @@ #include "bspline.h" #ifdef AGG_PLOT_ENABLED -#include "window-refs.h" +#include "object-index.h" #include "object-refs.h" #include "lua-draw.h" #include "lua-text.h" @@ -61,7 +61,7 @@ luaopen_gsl (lua_State *L) gsl_set_error_handler_off (); #ifdef AGG_PLOT_ENABLED - window_ref_prepare (L); + object_index_prepare (L); object_ref_prepare (L); #endif diff --git a/object-index.c b/object-index.c new file mode 100644 index 00000000..8dd8c839 --- /dev/null +++ b/object-index.c @@ -0,0 +1,94 @@ + +#include <lua.h> +#include <lauxlib.h> + +#include "object-index.h" + +static const char *table_name[] = {"GSL.reg.wins", "GSL.reg.plts"}; + +void +object_index_prepare (lua_State *L) +{ + lua_newtable (L); + lua_setfield (L, LUA_REGISTRYINDEX, table_name[OBJECT_WINDOW]); + + lua_newtable (L); + /* the metatable to define it as a weak table */ + lua_newtable (L); + lua_pushstring (L, "v"); + lua_setfield (L, -2, "__mode"); + lua_setmetatable (L, -2); + lua_setfield (L, LUA_REGISTRYINDEX, table_name[OBJECT_PLOT]); +} + +int +object_index_add(lua_State *L, int obj_class, int index) +{ + int n; + + if (index < 0) + index = lua_gettop (L) - (index+1); + + lua_getfield (L, LUA_REGISTRYINDEX, table_name[obj_class]); + + n = lua_objlen (L, -1); + + lua_pushvalue (L, index); + lua_rawseti (L, -2, n+1); + lua_pop (L, 1); + + return n+1; +} + +void +object_index_get (lua_State *L, int obj_class, int id) +{ + lua_getfield (L, LUA_REGISTRYINDEX, table_name[obj_class]); + lua_rawgeti (L, -1, id); + lua_remove (L, -2); +} + +void +object_index_remove (lua_State *L, int obj_class, int id) +{ + lua_getfield (L, LUA_REGISTRYINDEX, table_name[obj_class]); + lua_pushnil (L); + lua_rawseti (L, -2, id); + lua_pop (L, 1); +} + +void +object_index_apply_all (lua_State *L, int obj_class, lua_CFunction f) +{ + lua_getfield (L, LUA_REGISTRYINDEX, table_name[obj_class]); + + lua_pushnil (L); /* first key */ + while (lua_next(L, -2) != 0) + { + /* lua_pushcfunction (L, canvas_window_close_protected); */ + lua_pushcfunction (L, f); + lua_insert (L, -2); + lua_call (L, 1, 0); + } + + lua_pop (L, 1); +} + +int +object_index_count (lua_State *L, int obj_class) +{ + int count = 0; + + lua_getfield (L, LUA_REGISTRYINDEX, table_name[obj_class]); + + lua_pushnil (L); /* first key */ + while (lua_next(L, -2) != 0) + { + lua_pop (L, 1); + count ++; + } + + lua_pop (L, 1); + + return count; +} diff --git a/object-index.h b/object-index.h new file mode 100644 index 00000000..db1db84f --- /dev/null +++ b/object-index.h @@ -0,0 +1,24 @@ +#ifndef OBJECT_INDEX_H +#define OBJECT_INDEX_H + +#include "defs.h" + +__BEGIN_DECLS + +#include "lua.h" + +enum object_class_e { + OBJECT_WINDOW = 0, + OBJECT_PLOT, +}; + +extern void object_index_prepare (lua_State *L); +extern int object_index_add (lua_State *L, int obj_class, int index); +extern void object_index_get (lua_State *L, int obj_class, int id); +extern void object_index_remove (lua_State *L, int obj_class, int id); +extern void object_index_apply_all (lua_State *L, int obj_class, lua_CFunction f); +extern int object_index_count (lua_State *L, int obj_class); + +__END_DECLS + +#endif diff --git a/object-refs.c b/object-refs.c index bb340a2e..f0965eee 100644 --- a/object-refs.c +++ b/object-refs.c @@ -23,24 +23,72 @@ object_ref_prepare (lua_State *L) void object_ref_add (lua_State *L, int key_index, int val_index) { - size_t n; + int ref; + bool add_table = false; lua_getfield (L, LUA_REGISTRYINDEX, object_ref_table_name); lua_pushvalue (L, key_index); - lua_pushvalue (L, key_index); - lua_rawget (L, -3); + lua_rawget (L, -2); if (lua_isnil (L, -1)) { lua_pop (L, 1); lua_newtable (L); + + lua_pushvalue (L, val_index); + ref = 1; + add_table = true; } + else + { + lua_pushvalue (L, val_index); + lua_pushvalue (L, val_index); + lua_rawget (L, -3); - n = lua_objlen (L, -1); + ref = lua_tointeger (L, -1) + 1; - lua_pushvalue (L, val_index); - lua_rawseti (L, -2, n + 1); + lua_pop (L, 1); + } + lua_pushinteger (L, ref); lua_rawset (L, -3); - lua_pop (L, 1); + + if (add_table) + { + lua_pushvalue (L, key_index); + lua_insert (L, -2); + lua_rawset (L, -3); + lua_pop (L, 1); + } + else + lua_pop (L, 2); +} + +void +object_ref_remove (lua_State *L, int key_index, int val_index) +{ + lua_getfield (L, LUA_REGISTRYINDEX, object_ref_table_name); + lua_pushvalue (L, key_index); + lua_rawget (L, -2); + + if (! lua_isnil (L, -1)) + { + int ref; + + lua_pushvalue (L, val_index); + lua_pushvalue (L, val_index); + lua_rawget (L, -3); + + ref = lua_tointeger (L, -1); + lua_pop (L, 1); + + if (ref <= 1) + lua_pushnil (L); + else + lua_pushinteger (L, ref - 1); + + lua_rawset (L, -3); + } + + lua_pop (L, 2); } diff --git a/object-refs.h b/object-refs.h index 73960249..447553ed 100644 --- a/object-refs.h +++ b/object-refs.h @@ -8,7 +8,8 @@ __BEGIN_DECLS #include <lua.h> extern void object_ref_prepare (lua_State *L); -extern void object_ref_add (lua_State *L, int key_index, int val_index); +extern void object_ref_add (lua_State *L, int key_index, int val_index); +extern void object_ref_remove (lua_State *L, int key_index, int val_index); __END_DECLS diff --git a/window-refs.c b/window-refs.c deleted file mode 100644 index ad4d31b0..00000000 --- a/window-refs.c +++ /dev/null @@ -1,83 +0,0 @@ - -#include <lua.h> -#include <lauxlib.h> - -#include "window-refs.h" -#include "canvas-window.h" - -static char const * const window_ref_table_name = "GSL.windows"; - -void -window_ref_prepare (lua_State *L) -{ - lua_newtable (L); - lua_setfield (L, LUA_REGISTRYINDEX, window_ref_table_name); -} - -size_t -window_ref_add(lua_State *L, int index) -{ - size_t n; - - lua_getfield (L, LUA_REGISTRYINDEX, window_ref_table_name); - - n = lua_objlen (L, -1); - - lua_pushvalue (L, index); - lua_rawseti (L, -2, n+1); - lua_pop (L, 1); - - return n+1; -} - -void -window_ref_get (lua_State *L, int id) -{ - lua_getfield (L, LUA_REGISTRYINDEX, window_ref_table_name); - lua_rawgeti (L, -1, id); - lua_remove (L, -2); -} - -void -window_ref_remove (lua_State *L, int id) -{ - lua_getfield (L, LUA_REGISTRYINDEX, window_ref_table_name); - lua_pushnil (L); - lua_rawseti (L, -2, id); - lua_pop (L, 1); -} - -void -window_ref_close_all (lua_State *L) -{ - lua_getfield (L, LUA_REGISTRYINDEX, window_ref_table_name); - - lua_pushnil (L); /* first key */ - while (lua_next(L, -2) != 0) - { - lua_pushcfunction (L, canvas_window_close_protected); - lua_insert (L, -2); - lua_call (L, 1, 0); - } - - lua_pop (L, 1); -} - -int -window_ref_count (lua_State *L) -{ - int count = 0; - - lua_getfield (L, LUA_REGISTRYINDEX, window_ref_table_name); - - lua_pushnil (L); /* first key */ - while (lua_next(L, -2) != 0) - { - lua_pop (L, 1); - count ++; - } - - lua_pop (L, 1); - - return count; -} diff --git a/window-refs.h b/window-refs.h deleted file mode 100644 index 3cf26d5f..00000000 --- a/window-refs.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef WINDOW_REFS_H -#define WINDOW_REFS_H - -#include "defs.h" - -__BEGIN_DECLS - -#include "lua.h" - -extern void window_ref_prepare (lua_State *L); -extern size_t window_ref_add (lua_State *L, int index); -extern void window_ref_get (lua_State *L, int id); -extern void window_ref_remove (lua_State *L, int id); -extern void window_ref_close_all (lua_State *L); -extern int window_ref_count (lua_State *L); - -__END_DECLS - -#endif |