author | fr4nko <francesco.bbt@gmail.com> | 2010年06月29日 11:48:05 +0200 |
---|---|---|
committer | fr4nko <francesco.bbt@gmail.com> | 2010年06月29日 11:48:05 +0200 |
commit | 1beceb467757384bd5695f5e7ed9acfba590bd4a (patch) | |
tree | 009f1a0df1484ebf721a93a6e3f2b1d135e4f4ba | |
parent | b5f50727239483643508795750262bc3ab6723ca (diff) | |
download | gsl-shell-1beceb467757384bd5695f5e7ed9acfba590bd4a.tar.gz |
diff --git a/DIST-FILES b/DIST-FILES deleted file mode 100644 index ade3e742..00000000 --- a/DIST-FILES +++ /dev/null @@ -1,221 +0,0 @@ -DIST-FILES -integ.h -code.h -cnlinfit.h -lua-utils.c -solver-impl.c -template_matrix_oper_off.h -nlinfit_helper.c -integ.lua -nlinfit_helper.h -math-types.h -matrix_op_source.c -template_matrix_oper_on.h -README -gsl-shell.c -matrix.h -cmpl.c -matrix_source.c -ode.h -LICENSE -template_matrix_off.h -lua-utils.h -ode_source.c -fdfsolver.c -matrix_decls_source.c -linalg.c -INSTALL -linalg.h -errors.c -math-types.c -nlinfit.c -matrix.c -matrix_headers_source.h -cmatrix.c -cmpl.h -nlinfit_source.c -nlinfit_decls_source.c -common.c -nlinfit.h -lua-gsl.c -Makefile -cmatrix.h -fft.c -ode_decls_source.c -integ.c -ode.c -fft.h -igsl.lua -solver-impl.h -lua-gsl.h -template_matrix_on.h -ode_solver.c -makeconfig -cnlinfit.c -ode_solver.h -fdfsolver.h -matrix_helper_source.c -defs.h -errors.h -common.h -code.c -random.c -random.h -randist.c -randist.h -pdf.c -pdf.h -cdf.c -cdf.h -distributions-list.c -randist-source.c -lua-cplot.h -lua/etc/min.c -lua/etc/all.c -lua/etc/README -lua/etc/Makefile -lua/etc/noparser.c -lua/etc/lua.ico -lua/etc/lua.hpp -lua/etc/strict.lua -lua/etc/lua.pc -lua/src/linit.c -lua/src/print.c -lua/src/lvm.h -lua/src/lmem.c -lua/src/lcode.h -lua/src/loslib.c -lua/src/lstring.h -lua/src/lua.c -lua/src/lopcodes.h -lua/src/llex.c -lua/src/lapi.h -lua/src/liolib.c -lua/src/ltm.h -lua/src/lnum.h -lua/src/lapi.c -lua/src/lzio.h -lua/src/luaconf.h -lua/src/lundump.c -lua/src/lstring.c -lua/src/llex.h -lua/src/lstate.c -lua/src/lualib.h -lua/src/ldebug.c -lua/src/luaconf_internal.h -lua/src/lstate.h -lua/src/lua.h -lua/src/ldblib.c -lua/src/lbaselib.c -lua/src/lparser.h -lua/src/lundump.h -lua/src/ltable.c -lua/src/ltm.c -lua/src/lzio.c -lua/src/Makefile -lua/src/luac.c -lua/src/lobject.c -lua/src/lgc.c -lua/src/lcode.c -lua/src/lauxlib.h -lua/src/ldo.c -lua/src/lfunc.c -lua/src/lvm.c -lua/src/lstrlib.c -lua/src/loadlib.c -lua/src/lobject.h -lua/src/ltablib.c -lua/src/lfunc.h -lua/src/ldo.h -lua/src/llimits.h -lua/src/lmem.h -lua/src/lopcodes.c -lua/src/lparser.c -lua/src/lauxlib.c -lua/src/lmathlib.c -lua/src/ldump.c -lua/src/ldebug.h -lua/src/lnum.c -lua/src/lgc.h -lua/src/ltable.h -lua/README -lua/COPYRIGHT -lua/HISTORY -lua/INSTALL -lua/doc/lua.1 -lua/doc/manual.css -lua/doc/cover.png -lua/doc/readme.html -lua/doc/luac.1 -lua/doc/amazon.gif -lua/doc/manual.html -lua/doc/lua.css -lua/doc/logo.gif -lua/doc/lua.html -lua/doc/contents.html -lua/doc/luac.html -lua/Makefile -lua/test/echo.lua -lua/test/sort.lua -lua/test/fibfor.lua -lua/test/globals.lua -lua/test/trace-globals.lua -lua/test/printf.lua -lua/test/table.lua -lua/test/luac.lua -lua/test/README -lua/test/bisect.lua -lua/test/factorial.lua -lua/test/trace-calls.lua -lua/test/xd.lua -lua/test/sieve.lua -lua/test/cf.lua -lua/test/fib.lua -lua/test/hello.lua -lua/test/life.lua -lua/test/env.lua -lua/test/readonly.lua -tests/matrix-op.lua -tests/mexp.lua -tests/ode-example-qdho.lua -tests/ode-test.lua -tests/nlinfit-test.lua -tests/ex-linalg.lua -examples/ode-example.lua -examples/nlinfit.lua -examples/legendre-pol.lua -doc/source/news.rst -doc/source/email-gslshell.png -doc/source/intro.rst -doc/source/ode.rst -doc/source/acknowledgments.rst -doc/source/index.rst -doc/source/linalg.rst -doc/source/fft.rst -doc/source/nlinfit.rst -doc/source/conf.py -doc/source/integ.rst -doc/source/matrices.rst -doc/source/random.rst -doc/source/randist.rst -doc/source/pdf.rst -doc/source/cdf.rst -doc/source/examples.rst -scripts/project-diff.sh -scripts/makedist.sh -scripts/www-cvs-sync.sh -scripts/makedist.sh -agg-plot/Makefile -agg-plot/canvas.h -agg-plot/trans.h -agg-plot/drawables.h -agg-plot/plot.h -agg-plot/lua-plot-priv.h -agg-plot/c-drawables.cpp -agg-plot/c-drawables.h -agg-plot/units.h -agg-plot/units-plot.h -agg-plot/utils.cpp -agg-plot/utils.h -agg-plot/xwin-show.cpp -agg-plot/xwin-show.h @@ -76,7 +76,7 @@ else endif ifeq ($(strip $(ENABLE_AGG_PLOT)), yes) - C_SRC_FILES += lua-plot.c +# C_SRC_FILES += lua-plot.c INCLUDES += $(PTHREADS_CFLAGS) -Iagg-plot SUBDIRS += agg-plot DEFS += -DAGG_PLOT_ENABLED diff --git a/agg-plot/Makefile b/agg-plot/Makefile index eb7f3e16..7f5c9b0c 100644 --- a/agg-plot/Makefile +++ b/agg-plot/Makefile @@ -22,6 +22,7 @@ GSH_BASE_DIR = .. include $(GSH_BASE_DIR)/makeconfig
include $(GSH_BASE_DIR)/makeflags
+include $(GSH_BASE_DIR)/make-packages
LUADIR = $(GSH_BASE_DIR)/lua
AR= ar rcu
@@ -36,18 +37,14 @@ ifeq ($(strip $(PLATFORM)), mingw) # Option for Windows Platform
DEFS += -DWIN32
INCLUDES += -I/usr/include -I/usr/pthreads-w32/include
- AGG_HOME = /c/fra/src/agg-2.5
- AGG_CFLAGS = -I$(AGG_HOME)/include
- AGG_LIBS = -L$(AGG_HOME)/src -lagg -lgdi32 -lsupc++
PLATSUP_SRC_FILES = agg_platform_support_win32.cpp agg_win32_bmp.cpp
else
- AGG_CFLAGS = -I/usr/include/agg2
PLATSUP_SRC_FILES = agg_platform_support_x11.cpp
endif
-INCLUDES += -I$(GSH_BASE_DIR) -I$(LUADIR)/src -I$(LUADIR)/etc
+INCLUDES += $(AGG_INCLUDES) -I$(GSH_BASE_DIR) -I$(LUADIR)/src
-AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp c-drawables.cpp colors.cpp xwin-show.cpp
+AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp colors.cpp lua-draw.cpp lua-plot.cpp xwin-show.cpp
AGGPLOT_OBJ_FILES := $(AGGPLOT_SRC_FILES:%.cpp=%.o)
@@ -55,10 +52,9 @@ DEP_FILES := $(AGGPLOT_SRC_FILES:%.cpp=.deps/%.P) DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
-CXXCOMPILE = $(CXX) $(CXXFLAGS) $(DEFS) $(INCLUDES) $(AGG_CFLAGS)
+CXXCOMPILE = $(CXX) $(CXXFLAGS) $(DEFS) $(INCLUDES)
TARGETS = libaggplot.a
-#TARGETS = test.exe
all: $(TARGETS)
diff --git a/agg-plot/colors.cpp b/agg-plot/colors.cpp index 5a1c268e..c1ea0ea6 100644 --- a/agg-plot/colors.cpp +++ b/agg-plot/colors.cpp @@ -1,32 +1,26 @@ #include <string.h>
+#include "lua-cpp-utils.h"
#include "colors.h"
-#include "agg_color_rgba.h"
-void
-set_color_default (struct color *c)
+agg::rgba8 *
+rgba8_push_default (lua_State *L)
{
- c->r = 180;
- c->g = c->b = 0;
- c->a = 255;
+ return new(L, GS_RGBA_COLOR) agg::rgba8(180, 0, 0, 255);
}
-void
-color_lookup (struct color *c, const char *color_str)
+agg::rgba8 *
+rgba8_push_lookup (lua_State *L, const char *color_str)
{
const char *p = color_str;
- int val = 180;
-
- c->a = 255;
+ const int a = 255;
if (strcmp (p, "white") == 0)
- {
- c->r = c->g = c->b = 255;
- return;
- }
-
- c->r = c->g = c->b = 0;
+ return new(L, GS_RGBA_COLOR) agg::rgba8(255, 255, 255, a);
+
+ int val = 180;
+ int r = 0, g = 0, b = 0;
if (strncmp (p, "light", 5) == 0)
{
@@ -40,17 +34,19 @@ color_lookup (struct color *c, const char *color_str) }
if (strcmp (p, "red") == 0)
- c->r = val;
+ r = val;
else if (strcmp (p, "green") == 0)
- c->g = val;
+ g = val;
else if (strcmp (p, "blue") == 0)
- c->b = val;
+ b = val;
else if (strcmp (p, "cyan") == 0)
- c->g = c->b = val;
+ g = b = val;
else if (strcmp (p, "magenta") == 0)
- c->r = c->b = val;
+ r = b = val;
else if (strcmp (p, "yellow") == 0)
- c->r = c->g = val;
+ r = g = val;
else if (strcmp (p, "gray") == 0)
- c->r = c->g = c->b = val;
+ r = g = b = val;
+
+ return new(L, GS_RGBA_COLOR) agg::rgba8(r, g, b, a);
}
diff --git a/agg-plot/colors.h b/agg-plot/colors.h index c2aa923b..560b6a5c 100644 --- a/agg-plot/colors.h +++ b/agg-plot/colors.h @@ -1,17 +1,14 @@ #ifndef AGGPLOT_COLORS_H
#define AGGPLOT_COLORS_H
-#include "defs.h"
-
-__BEGIN_DECLS
+extern "C" {
+#include "lua.h"
+}
-struct color {
- unsigned int r, g, b, a;
-};
-
-extern void color_lookup (struct color *c, const char *color_str);
-extern void set_color_default (struct color *c);
+#include "defs.h"
+#include "agg_color_rgba.h"
-__END_DECLS
+extern agg::rgba8 * rgba8_push_lookup(lua_State *L, const char *color_str);
+extern agg::rgba8 * rgba8_push_default(lua_State *L);
#endif
diff --git a/agg-plot/drawables.h b/agg-plot/drawables.h index aac888d3..471876ee 100644 --- a/agg-plot/drawables.h +++ b/agg-plot/drawables.h @@ -38,6 +38,7 @@ namespace my { agg::bounding_rect_single(*m_source, 0, x1, y1, x2, y2); }; + /* virtual void ref() { ref_count++; }; virtual unsigned unref() { @@ -45,6 +46,7 @@ namespace my { ref_count--; return ref_count; }; + */ }; class path : public vs_proxy<agg::path_storage> { @@ -55,40 +57,12 @@ namespace my { public: path(): vs_base(), m_path() { -#ifdef DEBUG_PLOT - fprintf(stderr, "creating path: %p\n", this); -#endif set_source(&m_path); }; -#ifdef DEBUG_PLOT - ~path() { fprintf(stderr, "freeing path: %p\n", this); }; -#endif - - agg::path_storage& get_path() { return m_path; }; }; - /* ellipse drawable */ - class ellipse : public vs_proxy<agg::ellipse> { - typedef vs_proxy<agg::ellipse> vs_base; - - agg::ellipse m_ellipse; - - public: - ellipse(double x, double y, double rx, double ry, - unsigned num_steps=0, bool cw=false): - vs_base(), m_ellipse(x, y, rx, ry, num_steps, cw) - { - set_source(&m_ellipse); - }; - - virtual void apply_transform(agg::trans_affine& m, double as) - { - m_ellipse.approximation_scale(as); - }; - }; - typedef vs_proxy<agg::conv_stroke<agg::conv_transform<agg::gsv_text> > > vs_text; /* text drawable */ diff --git a/agg-plot/lua-cpp-utils.cpp b/agg-plot/lua-cpp-utils.cpp new file mode 100644 index 00000000..2fce32bc --- /dev/null +++ b/agg-plot/lua-cpp-utils.cpp @@ -0,0 +1,2 @@ +
+#include "lua-cpp-utils.h"
diff --git a/agg-plot/lua-cpp-utils.h b/agg-plot/lua-cpp-utils.h new file mode 100644 index 00000000..df0c97bd --- /dev/null +++ b/agg-plot/lua-cpp-utils.h @@ -0,0 +1,20 @@ +#ifndef LUA_CPP_UTILS_H
+#define LUA_CPP_UTILS_H
+
+#include <new>
+
+#include "defs.h"
+__BEGIN_DECLS
+#include "lua.h"
+__END_DECLS
+
+#include "gs-types.h"
+
+inline void* operator new(size_t nbytes, lua_State *L, enum gs_type_e tp)
+{
+ void* p = lua_newuserdata(L, nbytes);
+ gs_set_metatable (L, tp);
+ return p;
+}
+
+#endif
diff --git a/agg-plot/lua-draw.cpp b/agg-plot/lua-draw.cpp new file mode 100644 index 00000000..94ff5ec5 --- /dev/null +++ b/agg-plot/lua-draw.cpp @@ -0,0 +1,415 @@ + +#include <pthread.h> + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +} + +#include "lua-draw.h" +#include "gsl-shell.h" +#include "lua-cpp-utils.h" +#include "gs-types.h" +#include "trans.h" +#include "colors.h" + +pthread_mutex_t agg_mutex[1]; + +enum path_cmd_e { + CMD_ERROR = -1, + CMD_MOVE_TO = 0, + CMD_LINE_TO, + CMD_CLOSE, + CMD_ARC_TO, + CMD_CURVE3, + CMD_CURVE4, +}; + +struct cmd_call_stack { + double f[6]; + int b[2]; +}; + +struct path_cmd_reg { + enum path_cmd_e id; + const char *cmd; + const char *signature; +}; + +static int agg_obj_index (lua_State *L); +static int agg_obj_free (lua_State *L); + +static int agg_path_free (lua_State *L); +static int agg_path_index (lua_State *L); + +static int agg_text_free (lua_State *L); +static int agg_text_set_text (lua_State *L); +static int agg_text_set_point (lua_State *L); +static int agg_text_rotate (lua_State *L); + +static int agg_rgba_free (lua_State *L); + +static void path_cmd (my::path *p, int cmd, struct cmd_call_stack *stack); + +static struct path_cmd_reg cmd_table[] = { + {CMD_MOVE_TO, "move_to", "ff"}, + {CMD_LINE_TO, "line_to", "ff"}, + {CMD_CLOSE, "close", ""}, + {CMD_ARC_TO, "arc_to", "fffbbff"}, + {CMD_CURVE3, "curve3", "ffff"}, + {CMD_CURVE4, "curve4", "ffffff"}, + {CMD_ERROR, NULL, NULL} +}; + +static const struct luaL_Reg plot_functions[] = { + {"path", agg_path_new}, + {"text", agg_text_new}, + {"rgba", agg_rgba_new}, + {"rgb", agg_rgb_new}, + {NULL, NULL} +}; + +static const struct luaL_Reg agg_obj_methods[] = { + {"__index", agg_obj_index}, + {"__gc", agg_obj_free}, + {NULL, NULL} +}; + +static const struct luaL_Reg agg_path_methods[] = { + {"__index", agg_path_index}, + {"__gc", agg_path_free}, + {NULL, NULL} +}; + +static const struct luaL_Reg rgba_methods[] = { + {"__gc", agg_rgba_free}, + {NULL, NULL} +}; + +static const struct luaL_Reg agg_text_methods[] = { + {"__gc", agg_text_free}, + {"set_point", agg_text_set_point}, + {"set_text", agg_text_set_text}, + {"rotate", agg_text_rotate}, + {NULL, NULL} +}; + +int +agg_path_new (lua_State *L) +{ + my::path *vs = new(L, GS_DRAW_PATH) my::path(); + + if (lua_gettop (L) >= 2) + { + double x = gs_check_number (L, 1, FP_CHECK_NORMAL); + double y = gs_check_number (L, 2, FP_CHECK_NORMAL); + struct cmd_call_stack s[1]; + + s->f[0] = x; + s->f[1] = y; + + path_cmd (vs, CMD_MOVE_TO, s); + } + + return 1; +} + +my::path * +check_agg_path (lua_State *L, int index) +{ + return (my::path *) gs_check_userdata (L, index, GS_DRAW_PATH); +} + +int +agg_path_free (lua_State *L) +{ + typedef my::path path_type; + path_type *path = check_agg_path (L, 1); + printf("freeing PATH %p\n", (void *) path); + path->~path_type(); + return 0; +} + +void +path_cmd (my::path *p, int _cmd, struct cmd_call_stack *s) +{ + agg::path_storage& ps = p->get_path(); + path_cmd_e cmd = (path_cmd_e) _cmd; + + switch (cmd) + { + case CMD_MOVE_TO: + ps.move_to (s->f[0], s->f[1]); + break; + case CMD_LINE_TO: + ps.line_to (s->f[0], s->f[1]); + break; + case CMD_CLOSE: + ps.close_polygon (); + break; + case CMD_ARC_TO: + ps.arc_to (s->f[0], s->f[1], s->f[2], s->b[0], s->b[1], s->f[3], s->f[4]); + break; + case CMD_CURVE3: + ps.curve3 (s->f[0], s->f[1], s->f[2], s->f[3]); + break; + case CMD_CURVE4: + ps.curve4 (s->f[0], s->f[1], s->f[2], s->f[3], s->f[4], s->f[5]); + break; + case CMD_ERROR: + ; + } +} + +static int +agg_path_cmd (lua_State *L) +{ + my::path *p = check_agg_path (L, 1); + int id = lua_tointeger (L, lua_upvalueindex(1)); + const char *signature = lua_tostring (L, lua_upvalueindex(2)); + int argc = 2, f_count = 0, b_count = 0; + struct cmd_call_stack s[1]; + const char *fc; + + for (fc = signature; fc[0]; fc++) + { + switch (fc[0]) + { + case 'f': + s->f[f_count++] = gs_check_number (L, argc++, FP_CHECK_NORMAL); + break; + case 'b': + if (lua_isboolean (L, argc)) + s->b[b_count++] = lua_toboolean (L, argc++); + else + return luaL_error (L, "expected boolean for argument #%i", argc); + } + } + + pthread_mutex_lock (agg_mutex); + path_cmd (p, id, s); + pthread_mutex_unlock (agg_mutex); + return 0; +} + +int +agg_path_index (lua_State *L) +{ + struct path_cmd_reg *r; + const char *key; + + if (! lua_isstring (L, 2)) + return 0; + + key = lua_tostring (L, 2); + for (r = cmd_table; r->cmd; r++) + { + if (strcmp (key, r->cmd) == 0) + break; + } + + if (r->cmd) + { + lua_pushinteger (L, (int) r->id); + lua_pushstring (L, r->signature); + lua_pushcclosure (L, agg_path_cmd, 2); + return 1; + } + + return 0; +} + +vertex_source * +check_agg_obj (lua_State *L, int index) +{ + int tplist[] = {GS_DRAW_OBJ, GS_DRAW_PATH, GS_DRAW_TEXT, GS_INVALID_TYPE}; + void *p = NULL; + int j; + + for (j = 0; tplist[j] != GS_INVALID_TYPE; j++) + { + p = gs_is_userdata (L, index, tplist[j]); + if (p) + break; + } + + if (p == NULL) + gs_type_error (L, index, "drawing object"); + + return (vertex_source *) p; +} + +int +agg_obj_free (lua_State *L) +{ + vertex_source *vs = check_agg_obj (L, 1); + printf("freeing OBJECT %p\n", (void *) vs); + vs->~vertex_source(); + return 0; +} + +static int +agg_obj_pcall (lua_State *L) +{ + int narg_out, narg_in = lua_gettop (L); + int status; + + pthread_mutex_lock (agg_mutex); + lua_pushvalue (L, lua_upvalueindex(1)); + lua_insert (L, 1); + status = lua_pcall (L, narg_in, LUA_MULTRET, 0); + pthread_mutex_unlock (agg_mutex); + if (status != 0) + { +#ifndef LUA_MODULE + error_report (L, status); +#else + luaL_error (L, "error in graphical object method"); +#endif + return 0; + } + narg_out = lua_gettop (L); + return narg_out; +} + +int +agg_obj_index (lua_State *L) +{ + vertex_source *vs = check_agg_obj (L, 1); + + lua_getmetatable (L, 1); + lua_insert (L, 2); + lua_gettable (L, 2); + + if (! lua_isnil (L, -1)) + { + lua_pushcclosure (L, agg_obj_pcall, 1); + return 1; + } + + return 0; +} + +my::text * +check_agg_text (lua_State *L, int index) +{ + return (my::text *) gs_check_userdata (L, index, GS_DRAW_TEXT); +} + +int +agg_text_new (lua_State *L) +{ + double size = luaL_optnumber (L, 1, 10.0); + double width = luaL_optnumber (L, 2, 1.0); + my::text *txt = new(L, GS_DRAW_TEXT) my::text(size, width); + return 1; +} + +int +agg_text_free (lua_State *L) +{ + typedef my::text text_type; + text_type *t = check_agg_text (L, 1); + t->~text_type(); + return 0; +} + +int +agg_text_set_text (lua_State *L) +{ + my::text *t = check_agg_text (L, 1); + const char *text = luaL_checkstring (L, 2); + t->set_text(text); + return 0; +} + +int +agg_text_set_point (lua_State *L) +{ + my::text *t = check_agg_text (L, 1); + double x = luaL_checknumber (L, 2); + double y = luaL_checknumber (L, 3); + t->start_point(x, y); + return 0; +} + +int +agg_text_rotate (lua_State *L) +{ + my::text *t = check_agg_text (L, 1); + double a = luaL_checknumber (L, 2); + t->rotate(a); + return 0; +}; + +static unsigned int double2uint8 (double x) +{ + int u = x * 255.0; + if (u > 255) + u = 255; + else if (u < 0) + u = 0; + return (unsigned int) u; +} + +agg::rgba8 * +check_agg_rgba8 (lua_State *L, int index) +{ + return (agg::rgba8 *) gs_check_userdata (L, index, GS_RGBA_COLOR); +} + +int +agg_rgba_new (lua_State *L) +{ + unsigned int r = double2uint8 (luaL_checknumber (L, 1)); + unsigned int g = double2uint8 (luaL_checknumber (L, 2)); + unsigned int b = double2uint8 (luaL_checknumber (L, 3)); + unsigned int a = double2uint8 (luaL_checknumber (L, 4)); + + new(L, GS_RGBA_COLOR) agg::rgba8(r, g, b, a); + return 1; +} + +int +agg_rgb_new (lua_State *L) +{ + unsigned int r = double2uint8 (luaL_checknumber (L, 1)); + unsigned int g = double2uint8 (luaL_checknumber (L, 2)); + unsigned int b = double2uint8 (luaL_checknumber (L, 3)); + + new(L, GS_RGBA_COLOR) agg::rgba8(r, g, b, 255); + return 1; +} + +int +agg_rgba_free (lua_State *L) +{ + typedef agg::rgba8 rgba_t; + rgba_t *c = check_agg_rgba8 (L, 1); + c->~rgba_t(); + return 0; +} + +void +draw_register (lua_State *L) +{ + pthread_mutex_init (agg_mutex, NULL); + + luaL_newmetatable (L, GS_METATABLE(GS_DRAW_PATH)); + luaL_register (L, NULL, agg_path_methods); + lua_pop (L, 1); + + luaL_newmetatable (L, GS_METATABLE(GS_DRAW_TEXT)); + lua_pushvalue (L, -1); + lua_setfield (L, -2, "__index"); + luaL_register (L, NULL, agg_text_methods); + lua_pop (L, 1); + + luaL_newmetatable (L, GS_METATABLE(GS_DRAW_OBJ)); + luaL_register (L, NULL, agg_obj_methods); + lua_pop (L, 1); + + luaL_newmetatable (L, GS_METATABLE(GS_RGBA_COLOR)); + luaL_register (L, NULL, rgba_methods); + lua_pop (L, 1); +} diff --git a/agg-plot/lua-draw.h b/agg-plot/lua-draw.h new file mode 100644 index 00000000..d7f94550 --- /dev/null +++ b/agg-plot/lua-draw.h @@ -0,0 +1,48 @@ +#ifndef LUA_DRAW_H
+#define LUA_DRAW_H
+
+
+#include "defs.h"
+
+#include <pthread.h>
+
+__BEGIN_DECLS
+#include "lua.h"
+__END_DECLS
+
+#ifdef __cplusplus
+
+#include "vertex-source.h"
+#include "drawables.h"
+#include "trans.h"
+
+extern int agg_text_new (lua_State *L);
+extern int agg_path_new (lua_State *L);
+extern int agg_rgb_new (lua_State *L);
+extern int agg_rgba_new (lua_State *L);
+
+extern vertex_source* check_agg_obj (lua_State *L, int index);
+extern my::path* check_agg_path (lua_State *L, int index);
+extern my::text* check_agg_text (lua_State *L, int index);
+extern agg::rgba8* check_agg_rgba8 (lua_State *L, int index);
+
+#endif
+
+__BEGIN_DECLS
+
+extern pthread_mutex_t agg_mutex[1];
+
+#define AGG_LOCK() pthread_mutex_lock (agg_mutex);
+#define AGG_UNLOCK() pthread_mutex_unlock (agg_mutex);
+
+#define AGG_PROTECT(op) { \
+ pthread_mutex_lock (agg_mutex); \
+ op; \
+ pthread_mutex_unlock (agg_mutex); \
+ }
+
+extern void draw_register (lua_State *L);
+
+__END_DECLS
+
+#endif
diff --git a/agg-plot/lua-plot-priv.h b/agg-plot/lua-plot-priv.h deleted file mode 100644 index 37d55c1c..00000000 --- a/agg-plot/lua-plot-priv.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef LUA_CPLOT_PRIV_H -#define LUA_CPLOT_PRIV_H - -#include <pthread.h> - -#include "defs.h" -#include "c-drawables.h" - -__BEGIN_DECLS - -enum path_cmd_e { - CMD_ERROR = -1, - CMD_MOVE_TO = 0, - CMD_LINE_TO, - CMD_CLOSE, - CMD_ARC_TO, - CMD_CURVE3, - CMD_CURVE4, -}; - -struct cmd_call_stack { - double f[6]; - int b[2]; -}; - -struct agg_plot { - CPLOT *plot; - int lua_is_owner; - int is_shown; - void *window; -}; - -enum trans_type { - trans_end = -1, - trans_stroke = 0, - trans_curve, - trans_dash, - trans_marker, - trans_rotate, - trans_translate, -}; - -struct property_reg { - int id; - const char *name; -}; - -struct stroke_spec { - double width; - int line_cap; - int line_join; -}; - -struct dash_spec { - double len[2]; -}; - -struct marker_spec { - double size; -}; - -struct rotate_spec { - double angle; -}; - - -struct translate_spec { - double x, y; -}; - -struct trans_spec { - enum trans_type tag; - union { - struct stroke_spec stroke; - struct dash_spec dash; - struct marker_spec marker; - struct translate_spec translate; - struct rotate_spec rotate; - } content; -}; - -extern struct property_reg line_cap_properties[]; -extern struct property_reg line_join_properties[]; - -extern void agg_plot_destroy (struct agg_plot *cp); -extern int update_callback (void *_app); - -extern pthread_mutex_t agg_mutex[1]; - -__END_DECLS - -#endif diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp new file mode 100644 index 00000000..d1600d30 --- /dev/null +++ b/agg-plot/lua-plot.cpp @@ -0,0 +1,535 @@ + +#include <pthread.h> + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +} + +#include "agg_color_rgba.h" + +#include "lua-plot.h" +#include "lua-draw.h" +#include "lua-cpp-utils.h" +#include "lua-utils.h" +#include "gs-types.h" +#include "vertex-source.h" +#include "trans.h" +#include "colors.h" +#include "xwin-show.h" + +__BEGIN_DECLS + +static int agg_plot_new (lua_State *L); +static int agg_plot_show (lua_State *L); +static int agg_plot_add (lua_State *L); +static int agg_plot_update (lua_State *L); +static int agg_plot_add_line (lua_State *L); +static int agg_plot_index (lua_State *L); +static int agg_plot_newindex (lua_State *L); +static int agg_plot_free (lua_State *L); +static int agg_plot_title_set (lua_State *L); +static int agg_plot_title_get (lua_State *L); +static int agg_plot_units_set (lua_State *L); +static int agg_plot_units_get (lua_State *L); + +static int build_stroke (lua_State *L); +static int build_dash (lua_State *L); +static int build_curve (lua_State *L); +static int build_marker (lua_State *L); +static int build_rotate (lua_State *L); +static int build_translate (lua_State *L); + +/* DEBUG DEBUG DEBUG */ +static int window_debug_list (lua_State *L); +static int obj_getfenv (lua_State *L); + +static const struct luaL_Reg plot_functions[] = { + {"path", agg_path_new}, + {"text", agg_text_new}, + {"rgba", agg_rgba_new}, + {"rgb", agg_rgb_new}, + {"plot", agg_plot_new}, + {"windows", window_debug_list}, + {"objgetfenv", obj_getfenv}, + {NULL, NULL} +}; + +static const struct luaL_Reg agg_plot_methods[] = { + {"show", agg_plot_show }, + {"add", agg_plot_add }, + {"addline", agg_plot_add_line }, + {"update", agg_plot_update }, + {"__index", agg_plot_index }, + {"__newindex", agg_plot_newindex }, + {"__gc", agg_plot_free }, + {NULL, NULL} +}; + +static const struct luaL_Reg agg_plot_properties_get[] = { + {"title", agg_plot_title_get }, + {"units", agg_plot_units_get }, + {NULL, NULL} +}; + +static const struct luaL_Reg agg_plot_properties_set[] = { + {"title", agg_plot_title_set }, + {"units", agg_plot_units_set }, + {NULL, NULL} +}; + +struct property_reg { + int id; + const char *name; +}; + +__END_DECLS + + +struct property_reg line_cap_properties[] = { + {(int) agg::butt_cap, "butt" }, + {(int) agg::square_cap, "square"}, + {(int) agg::round_cap, "round" }, + {0, NULL} +}; + +struct property_reg line_join_properties[] = { + {(int) agg::miter_join, "miter" }, + {(int) agg::miter_join_revert, "miter.rev" }, + {(int) agg::round_join, "round" }, + {(int) agg::bevel_join, "bevel" }, + {(int) agg::miter_join_round, "miter.round"}, + {0, NULL} +}; + +const struct luaL_Reg trans_builder[] = { + {"stroke", build_stroke }, + {"dash", build_dash}, + {"curve", build_curve}, + {"marker", build_marker}, + {"translate", build_translate}, + {"rotate", build_rotate}, + {NULL, NULL} +}; + +static int +property_lookup (struct property_reg *prop, const char *key) +{ + int default_value = prop->id; + + if (key == NULL) + return default_value; + + for ( ; prop->name; prop++) + { + if (strcmp (prop->name, key) == 0) + return prop->id; + } + + return default_value; +} + +void agg_plot::wait_update() +{ + if (this->window) + update_callback (this->window); +}; + +agg_plot* agg_plot::arg_check(lua_State *L, int index) +{ + return (agg_plot *) gs_check_userdata (L, index, GS_DRAW_PLOT); +} + +int +agg_plot_new (lua_State *L) +{ + agg_plot *p = new(L, GS_DRAW_PLOT) agg_plot(); + + lua_newtable (L); + lua_setfenv (L, -2); + + if (lua_isstring (L, 1)) + { + const char *title = lua_tostring (L, 1); + if (title) + p->set_title(title); + } + + return 1; +} + +int +agg_plot_free (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + printf("freeing plot\n"); + p->~agg_plot(); + return 0; +} + +int +agg_plot_index (lua_State *L) +{ + return mlua_index_with_properties (L, agg_plot_properties_get, false); +} + +int +agg_plot_title_set (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + const char *title = lua_tostring (L, 2); + + if (title == NULL) + return gs_type_error (L, 2, "string"); + + AGG_LOCK(); + + p->set_title(title); + p->wait_update(); + + AGG_UNLOCK(); + + return 0; +} + +int +agg_plot_title_get (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + const char *title = p->get_title(); + lua_pushstring (L, title); + return 1; +} + +int +agg_plot_units_set (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + bool request = (bool) lua_toboolean (L, 2); + bool current = p->use_units(); + + if (current != request) + { + AGG_LOCK(); + p->set_units(request); + p->wait_update(); + AGG_UNLOCK(); + } + + return 0; +} + +int +agg_plot_units_get (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + lua_pushboolean (L, p->use_units()); + return 1; +} + +int +agg_plot_newindex (lua_State *L) +{ + return mlua_newindex_with_properties (L, agg_plot_properties_set); +} + +int +build_stroke (lua_State *L) +{ + const int specindex = 3, objindex = 2; + double width = mlua_named_optnumber (L, specindex, "width", 1.0); + const char *scap = mlua_named_optstring (L, specindex, "cap", NULL); + const char *sjoin = mlua_named_optstring (L, specindex, "join", NULL); + vertex_source *obj = check_agg_obj (L, objindex); + + trans::stroke *stroke = new(L, GS_DRAW_OBJ) trans::stroke(obj, width); + mlua_set_fenv_ref (L, objindex); + + if (scap) + { + int cap = property_lookup (line_cap_properties, scap); + stroke->line_cap((agg::line_cap_e) cap); + } + + if (sjoin) + { + int join = property_lookup (line_join_properties, sjoin); + stroke->line_join((agg::line_join_e) join); + } + + return 1; +} + +int +build_curve (lua_State *L) +{ + const int specindex = 3, objindex = 2; + vertex_source *obj = check_agg_obj (L, objindex); + + trans::curve *c = new(L, GS_DRAW_OBJ) trans::curve(obj); + mlua_set_fenv_ref (L, objindex); + + return 1; +} + +int +build_marker (lua_State *L) +{ + const int specindex = 3, objindex = 2; + double size = mlua_named_optnumber (L, specindex, "size", 3.0); + vertex_source *obj = check_agg_obj (L, objindex); + + new(L, GS_DRAW_OBJ) trans::marker(obj, size); + mlua_set_fenv_ref (L, objindex); + + return 1; +} + +int +build_dash (lua_State *L) +{ + const int specindex = 3, objindex = 2; + double a = mlua_named_optnumber (L, specindex, "a", 10.0); + double b = mlua_named_optnumber (L, specindex, "b", a); + vertex_source *obj = check_agg_obj (L, objindex); + + trans::dash *dash = new(L, GS_DRAW_OBJ) trans::dash(obj); + mlua_set_fenv_ref (L, objindex); + + dash->add_dash(a, b); + + return 1; +} + +int +build_translate (lua_State *L) +{ + const int specindex = 3, objindex = 2; + double x = mlua_named_number (L, specindex, "x"); + double y = mlua_named_number (L, specindex, "y"); + vertex_source *obj = check_agg_obj (L, objindex); + + trans::affine *t = new(L, GS_DRAW_OBJ) trans::affine(obj); + mlua_set_fenv_ref (L, objindex); + + t->translate(x, y); + + return 1; +} + +int +build_rotate (lua_State *L) +{ + const int specindex = 3, objindex = 2; + double a = mlua_named_number (L, specindex, "angle"); + vertex_source *obj = check_agg_obj (L, objindex); + + trans::affine *t = new(L, GS_DRAW_OBJ) trans::affine(obj); + mlua_set_fenv_ref (L, objindex); + + t->rotate(a); + + return 1; +} + +void +parse_spec (lua_State *L) +{ + const int specindex = 3, objindex = 2; + const char *tag; + const struct luaL_Reg *builder; + + lua_rawgeti (L, specindex, 1); + if (! lua_isstring (L, -1)) + { + luaL_error (L, "the tag of the transformation is invalid"); + return; + } + + tag = lua_tostring (L, -1); + lua_pop (L, 1); + + builder = mlua_find_method (trans_builder, tag); + + if (builder) + builder->func (L); + else + luaL_error (L, "error in definition of pre or post transforms"); + + lua_replace (L, objindex); + lua_pop (L, 1); +} + +int +lparse_spec_pipeline (lua_State *L) +{ + size_t k, nb; + + if (lua_type (L, 1) == LUA_TTABLE) + nb = lua_objlen (L, 1); + else + return luaL_error (L, "post transform argument should be a table"); + + for (k = nb; k > 0; k--) + { + lua_rawgeti (L, 1, k); + parse_spec (L); + } + + return 1; +} + +static agg::rgba8 * +color_arg_lookup (lua_State *L, int index) +{ + agg::rgba8 *c; + + if (lua_isnil (L, index)) + { + c = rgba8_push_default (L); + lua_replace (L, index); + } + else if (lua_isstring (L, index)) + { + const char *cstr = lua_tostring (L, index); + c = rgba8_push_lookup (L, cstr); + lua_replace (L, index); + } + else + { + c = check_agg_rgba8 (L, index); + } + + return c; +} + +static int +agg_plot_add_gener (lua_State *L, bool as_line) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + int narg = lua_gettop (L); + agg::rgba8 *color; + + if (narg <= 2) + color = rgba8_push_default (L); + else + color = color_arg_lookup (L, 3); + + if (narg > 4) + { + lua_pushcfunction (L, lparse_spec_pipeline); + lua_pushvalue (L, 5); + lua_pushvalue (L, 2); + lua_call (L, 2, 1); + lua_replace (L, 2); + } + + vertex_source *curr = check_agg_obj (L, 2); + if (curr->need_resize()) + { + new(L, GS_DRAW_OBJ) trans::resize(curr); + mlua_set_fenv_ref (L, 2); + lua_replace (L, 2); + } + + if (narg > 3) + { + lua_pushcfunction (L, lparse_spec_pipeline); + lua_pushvalue (L, 4); + lua_pushvalue (L, 2); + lua_call (L, 2, 1); + lua_replace (L, 2); + } + + curr = check_agg_obj (L, 2); + + lua_pushvalue (L, 1); + mlua_fenv_addref (L, 2); + lua_pop (L, 1); + + AGG_LOCK(); + p->add(curr, color, as_line); + p->wait_update(); + AGG_UNLOCK(); + + return 0; +} + +int +agg_plot_add (lua_State *L) +{ + return agg_plot_add_gener (L, false); +} + +int +agg_plot_add_line (lua_State *L) +{ + return agg_plot_add_gener (L, true); +} + +int +agg_plot_update (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + AGG_PROTECT(p->wait_update()); + return 0; +} + +int +agg_plot_show (lua_State *L) +{ + agg_plot *p = agg_plot::arg_check(L, 1); + pthread_t xwin_thread[1]; + pthread_attr_t attr[1]; + + AGG_LOCK(); + + if (! p->is_shown) + { + p->id = mlua_window_ref(L, 1); + + pthread_attr_init (attr); + pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED); + + if (pthread_create(xwin_thread, attr, xwin_thread_function, (void*) p)) + { + pthread_attr_destroy (attr); + mlua_window_unref(L, p->id); + p->id = -1; + return luaL_error(L, "error creating thread."); + } + + p->is_shown = 1; + pthread_attr_destroy (attr); + } + + AGG_UNLOCK(); + + return 0; +} + +int +window_debug_list(lua_State *L) +{ + lua_getfield (L, LUA_REGISTRYINDEX, "GSL.windows"); + return 1; +} + +int +obj_getfenv(lua_State *L) +{ + lua_getfenv (L, 1); + return 1; +} + +void +plot_register (lua_State *L) +{ + /* plot declaration */ + luaL_newmetatable (L, GS_METATABLE(GS_DRAW_PLOT)); + luaL_register (L, NULL, agg_plot_methods); + lua_pop (L, 1); + + /* gsl module registration */ + luaL_register (L, NULL, plot_functions); +} diff --git a/agg-plot/lua-plot.h b/agg-plot/lua-plot.h new file mode 100644 index 00000000..ffc06393 --- /dev/null +++ b/agg-plot/lua-plot.h @@ -0,0 +1,37 @@ +#ifndef LUA_CPLOT_H
+#define LUA_CPLOT_H
+
+#include "defs.h"
+
+__BEGIN_DECLS
+#include "lua.h"
+__END_DECLS
+
+#ifdef __cplusplus
+
+#include "plot.h"
+#include "resource-manager.h"
+
+typedef plot<vertex_source, no_management> plot_type;
+
+struct agg_plot : public plot_type {
+ bool is_shown;
+ void *window;
+ int id;
+
+ agg_plot() : plot_type(), is_shown(false), window(NULL), id(0) {};
+
+ void wait_update();
+
+ static agg_plot* arg_check(lua_State *L, int index);
+};
+
+#endif
+
+__BEGIN_DECLS
+
+extern void plot_register (lua_State *L);
+
+__END_DECLS
+
+#endif
diff --git a/agg-plot/plot.h b/agg-plot/plot.h index e2b6467b..95430d20 100644 --- a/agg-plot/plot.h +++ b/agg-plot/plot.h @@ -34,8 +34,8 @@ class plot { container(): vs(NULL), color(), outline(false) {}; - container(VertexSource* vs, agg::rgba8 c, bool as_outline): - vs(vs), color(c), outline(as_outline) + container(VertexSource* vs, agg::rgba8 *c, bool as_outline): + vs(vs), color(*c), outline(as_outline) {}; ~container() {}; @@ -85,7 +85,7 @@ public: bool use_units() const { return m_use_units; }; void set_units(bool use_units); - void add(VertexSource* vs, agg::rgba8 color, bool outline = false) + void add(VertexSource* vs, agg::rgba8 *color, bool outline = false) { container d(vs, color, outline); m_elements.add(d); diff --git a/agg-plot/resource-manager.h b/agg-plot/resource-manager.h index c59782a3..c965a49c 100644 --- a/agg-plot/resource-manager.h +++ b/agg-plot/resource-manager.h @@ -11,7 +11,7 @@ class no_management { static void dispose(T* p) {};
};
-
+/*
class ref_manager {
public:
template <class T>
@@ -25,5 +25,6 @@ public: delete p;
};
};
+*/
#endif
diff --git a/agg-plot/trans.h b/agg-plot/trans.h index 6bcaae59..0cdacee2 100644 --- a/agg-plot/trans.h +++ b/agg-plot/trans.h @@ -8,6 +8,8 @@ #include "agg_conv_transform.h"
#include "agg_vcgen_markers_term.h"
#include "agg_arrowhead.h"
+#include "agg_bounding_rect.h"
+#include "agg_ellipse.h"
#include "my_conv_simple_marker.h"
@@ -23,15 +25,7 @@ protected: public:
vs_trans_proxy(vertex_source* src): m_output(*src), m_source(src)
{
-#ifdef DEBUG_PLOT
- fprintf(stderr, "creating trans: %p\n", this);
-#endif
};
-#ifdef DEBUG_PLOT
- ~vs_trans_proxy() { fprintf(stderr, "freeing trans: %p\n", this); };
-#endif
-
-
template <class init_type>
vs_trans_proxy(vertex_source* src, init_type& val):
@@ -41,6 +35,7 @@ public: virtual void rewind(unsigned path_id) { m_output.rewind(path_id); };
virtual unsigned vertex(double* x, double* y) { return m_output.vertex(x, y); };
+ /*
virtual void ref() { m_source->ref(); };
virtual unsigned unref()
{
@@ -49,6 +44,7 @@ public: delete m_source;
return 0;
};
+ */
virtual void apply_transform(agg::trans_affine& m, double as)
{
diff --git a/agg-plot/vertex-source.h b/agg-plot/vertex-source.h index 21e561d3..dad545dc 100644 --- a/agg-plot/vertex-source.h +++ b/agg-plot/vertex-source.h @@ -11,13 +11,16 @@ public: virtual ~vertex_source_base() {}; }; + class vertex_source : public vertex_source_base { public: virtual void apply_transform(agg::trans_affine& m, double as) = 0; virtual void bounding_box(double *x1, double *y1, double *x2, double *y2) = 0; + /* virtual void ref() = 0; virtual unsigned unref() = 0; + */ virtual bool need_resize() { return true; }; }; diff --git a/agg-plot/xwin-show.cpp b/agg-plot/xwin-show.cpp index 20a1b079..05692340 100644 --- a/agg-plot/xwin-show.cpp +++ b/agg-plot/xwin-show.cpp @@ -5,9 +5,11 @@ #include "platform/agg_platform_support.h" #include "xwin-show.h" +#include "gsl-shell.h" #include "canvas.h" -#include "plot.h" -#include "lua-plot-priv.h" +#include "lua-plot.h" +#include "lua-cpp-utils.h" +#include "lua-draw.h" extern void platform_support_prepare (); @@ -20,7 +22,7 @@ enum flip_y_e { flip_y = true }; class the_application : public agg::platform_support { public: - the_application(agg::pix_format_e format, bool flip_y, struct agg_plot *p) : + the_application(agg::pix_format_e format, bool flip_y, agg_plot *p) : agg::platform_support(format, flip_y), m_plot(p) { }; @@ -33,19 +35,16 @@ public: { canvas can(rbuf_window(), width(), height(), agg::rgba(1.0, 1.0, 1.0)); can.clear(); - plot_type* plot = (plot_type*) m_plot->plot; - plot->draw(can); + this->m_plot->draw(can); } virtual void on_draw() { - pthread_mutex_lock (agg_mutex); - on_draw_unprotected(); - pthread_mutex_unlock (agg_mutex); + AGG_PROTECT(on_draw_unprotected()); } private: - struct agg_plot *m_plot; + agg_plot *m_plot; }; int update_callback (void *_app) @@ -69,11 +68,11 @@ int update_callback (void *_app) void * xwin_thread_function (void *_plot) { - struct agg_plot *p = (struct agg_plot *) _plot; + agg_plot *p = (agg_plot *) _plot; platform_support_prepare(); - pthread_mutex_lock (agg_mutex); + AGG_LOCK(); the_application app(agg::pix_format_bgr24, flip_y, p); app.caption("GSL shell plot"); @@ -81,21 +80,20 @@ xwin_thread_function (void *_plot) if(app.init(780, 400, agg::window_resize)) { p->window = (void *) &app; - pthread_mutex_unlock (agg_mutex); + AGG_UNLOCK(); + + /* start main loop for the plot window */ app.run(); - pthread_mutex_lock (agg_mutex); - } - p->window = NULL; - if (p->lua_is_owner) - { + AGG_LOCK(); + p->window = NULL; p->is_shown = 0; - pthread_mutex_unlock (agg_mutex); - } - else - { - pthread_mutex_unlock (agg_mutex); - agg_plot_destroy (p); + AGG_UNLOCK(); + + GSL_SHELL_LOCK(); + printf("unref plot\n"); + gsl_shell_unref_plot (p->id); + GSL_SHELL_UNLOCK(); } return NULL; diff --git a/agg-plot/xwin-show.h b/agg-plot/xwin-show.h index 95dc7ed7..62b47b75 100644 --- a/agg-plot/xwin-show.h +++ b/agg-plot/xwin-show.h @@ -3,6 +3,7 @@ __BEGIN_DECLS +extern int update_callback (void *_app); extern void * xwin_thread_function (void *_cplot); __END_DECLS diff --git a/contour.lua b/contour.lua index 0cd8ba35..eb26b50d 100644 --- a/contour.lua +++ b/contour.lua @@ -740,12 +740,12 @@ function contour(f, a, b, ngridx, ngridy, nlevels) g.find_curves() - pl = plot() - g.draw_regions(pl) - g.draw_lines(pl, rgba(0,0,0,0.6)) - pl:show() + local p = plot() + g.draw_regions(p) + g.draw_lines(p, rgba(0,0,0,0.6)) + p:show() - return pl + return p end return M @@ -215,6 +215,21 @@ fft_hc_mixed_radix_transform (lua_State *L, gsl_matrix *hc) gsl_matrix * fft_hc_check (lua_State *L, int index, struct fft_hc_sel ** selptr) { + int sel; + gsl_matrix *p = gs_check_userdata_w_alt (L, index, + GS_HALFCMPL_R2, + GS_HALFCMPL_MR, &sel); + + *selptr = (sel == GS_HALFCMPL_R2 ? fft_hc_radix2_sel : \ + fft_hc_mixed_radix_sel); + + return p; +} + + /* +gsl_matrix * +fft_hc_check (lua_State *L, int index, struct fft_hc_sel ** selptr) +{ const char * const user_name = "half-complex vector"; void *p = lua_touserdata (L, index); const char *msg; @@ -251,6 +266,7 @@ fft_hc_check (lua_State *L, int index, struct fft_hc_sel ** selptr) gs_type_error (L, index, msg); return NULL; } + */ int fft_hc_length (lua_State *L) diff --git a/gs-types.c b/gs-types.c index 1716534b..1455dab6 100644 --- a/gs-types.c +++ b/gs-types.c @@ -1,7 +1,8 @@ +#include <assert.h> + #include <lua.h> #include <lauxlib.h> -#include <assert.h> #include "gs-types.h" #include <gsl/gsl_errno.h> #include <math.h> @@ -20,8 +21,10 @@ static int gs_type_string (lua_State *L); #define GS_FDFMULTIMIN_NAME_DEF "GSL.fdfmmin" #define GS_FMULTIMIN_NAME_DEF "GSL.fmmin" #define GS_BSPLINE_NAME_DEF "GSL.bspline" -#define GS_PLOT_NAME_DEF "GSL.plot" -#define GS_DRAW_OBJ_NAME_DEF "GSL.path" +#define GS_DRAW_PLOT_NAME_DEF "GSL.plot" +#define GS_DRAW_PATH_NAME_DEF "GSL.path" +#define GS_DRAW_TEXT_NAME_DEF "GSL.text" +#define GS_DRAW_OBJ_NAME_DEF "GSL.drawobj" #define GS_RGBA_COLOR_NAME_DEF "GSL.rgba" const struct gs_type gs_type_table[] = { @@ -37,7 +40,9 @@ const struct gs_type gs_type_table[] = { {GS_FDFMULTIMIN, GS_FDFMULTIMIN_NAME_DEF, "fdf multimin solver"}, {GS_FMULTIMIN, GS_FMULTIMIN_NAME_DEF, "f multimin solver"}, {GS_BSPLINE, GS_BSPLINE_NAME_DEF, "B-spline"}, - {GS_PLOT, GS_PLOT_NAME_DEF, "plot"}, + {GS_DRAW_PLOT, GS_DRAW_PLOT_NAME_DEF, "plot"}, + {GS_DRAW_PATH, GS_DRAW_PATH_NAME_DEF, "geometric line"}, + {GS_DRAW_TEXT, GS_DRAW_TEXT_NAME_DEF, "graphical text"}, {GS_DRAW_OBJ, GS_DRAW_OBJ_NAME_DEF, "drawing element"}, {GS_RGBA_COLOR, GS_RGBA_COLOR_NAME_DEF, "color"}, }; @@ -118,12 +123,12 @@ gs_type_error (lua_State *L, int narg, const char *req_type) } void * -gs_check_userdata (lua_State *L, int index, int typeid) +gs_is_userdata (lua_State *L, int index, int typeid) { void *p = lua_touserdata (L, index); if (p == NULL) - gs_type_error (L, index, type_qualified_name (typeid)); + return NULL; if (lua_getmetatable(L, index)) { @@ -137,10 +142,50 @@ gs_check_userdata (lua_State *L, int index, int typeid) } } - gs_type_error (L, index, type_qualified_name (typeid)); + lua_pop (L, 2); + return NULL; } +void * +gs_check_userdata (lua_State *L, int index, int typeid) +{ + void *p = gs_is_userdata (L, index, typeid); + + if (p == NULL) + gs_type_error (L, index, type_qualified_name (typeid)); + + return p; +} + +void * +gs_check_userdata_w_alt (lua_State *L, int index, int typeid1, int typeid2, + int *sel) +{ + void *p; + + p = gs_is_userdata (L, index, typeid1); + if (p == NULL) + { + p = gs_is_userdata (L, index, typeid2); + if (p == NULL) + { + const char *msg = lua_pushfstring(L, "%s or %s", + type_qualified_name (typeid1), + type_qualified_name (typeid2)); + gs_type_error (L, index, msg); + } + + if (sel) + *sel = typeid2; + } + + if (sel) + *sel = typeid1; + + return p; +} + int gs_gsl_errorcheck (lua_State *L, const char *routine, int status) { diff --git a/gs-types.h b/gs-types.h index f9aef195..3378b637 100644 --- a/gs-types.h +++ b/gs-types.h @@ -1,6 +1,10 @@ #ifndef GS_TYPES_H #define GS_TYPES_H +#include "defs.h" + +__BEGIN_DECLS + #include <lua.h> #include <lauxlib.h> @@ -17,7 +21,9 @@ enum gs_type_e { GS_FDFMULTIMIN, GS_FMULTIMIN, GS_BSPLINE, - GS_PLOT, + GS_DRAW_PLOT, + GS_DRAW_PATH, + GS_DRAW_TEXT, GS_DRAW_OBJ, GS_RGBA_COLOR, GS_INVALID_TYPE, @@ -37,7 +43,11 @@ struct gs_type { extern const char * full_type_name (lua_State *L, int narg); extern const char * type_qualified_name (int type_id); extern int gs_type_error (lua_State *L, int narg, const char *req_type); +extern void * gs_is_userdata (lua_State *L, int index, int type_id); extern void * gs_check_userdata (lua_State *L, int index, int type_id); +extern void * gs_check_userdata_w_alt (lua_State *L, int index, + int typeid1, int typeid2, + int *sel); extern int gs_gsl_errorcheck (lua_State *L, const char *routine, int status); extern void gs_set_metatable (lua_State *L, int type_id); extern double gs_check_number (lua_State *L, int index, int check_normal); @@ -48,4 +58,6 @@ extern const struct gs_type gs_type_table[]; extern const struct luaL_Reg gs_type_functions[]; +__END_DECLS + #endif diff --git a/gsl-shell.c b/gsl-shell.c index c03cacb5..efbaa18b 100644 --- a/gsl-shell.c +++ b/gsl-shell.c @@ -50,6 +50,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <pthread.h> #define lua_c @@ -58,11 +59,18 @@ #include <lauxlib.h> #include <lualib.h> #include "llimits.h" +#include "gsl-shell.h" #include "lua-gsl.h" #include "lua-utils.h" #define report error_report +struct window_unref_cell { + int id; + struct window_unref_cell *next; +}; + +static struct window_unref_cell *window_unref_list = NULL; static lua_State *globalL = NULL; static const char *progname = LUA_PROGNAME; @@ -84,6 +92,8 @@ static const luaL_Reg gshlibs[] = { {NULL, NULL} }; +pthread_mutex_t gsl_shell_mutex[1]; + static void lstop (lua_State *L, lua_Debug *ar) { (void)ar; /* unused arg. */ lua_sethook(L, NULL, 0, 0); @@ -113,7 +123,6 @@ static void print_usage (void) { fflush(stderr); } - void gsl_shell_openlibs (lua_State *L) { @@ -266,8 +275,12 @@ static int pushline (lua_State *L, int firstline) { char *b = buffer; size_t l; const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) - return 0; /* no input */ + { + return 0; /* no input */ + } + l = strlen(b); if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ b[l-1] = '0円'; /* remove it */ @@ -310,9 +323,40 @@ static int loadline (lua_State *L) { static void dotty (lua_State *L) { - int status; const char *oldprogname = progname; progname = NULL; + for (;;) + { + struct window_unref_cell *wu; + int status = loadline(L); + if (status == -1) + break; + if (status == 0) + status = docall(L, 0, 0); + report(L, status); + if (status == 0 && lua_gettop(L) > 0) + { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + { + const char *fstr = "error calling " LUA_QL("print") " (%s)"; + const char *emsg = lua_pushfstring(L, fstr, lua_tostring(L, -1)); + l_message(progname, emsg); + } + } + GSL_SHELL_LOCK(); + for (wu = window_unref_list; wu != NULL; /* */) + { + struct window_unref_cell *nxt = wu->next; + mlua_window_unref (L, wu->id); + free (wu); + wu = nxt; + } + window_unref_list = NULL; + GSL_SHELL_UNLOCK(); + } +#if 0 while ((status = loadline(L)) != -1) { if (status == 0) status = docall(L, 0, 0); report(L, status); @@ -325,6 +369,7 @@ static void dotty (lua_State *L) { lua_tostring(L, -1))); } } +#endif lua_settop(L, 0); /* clear stack */ fputs("\n", stdout); fflush(stdout); @@ -481,6 +526,8 @@ int main (int argc, char **argv) { int status; struct Smain s; + pthread_mutex_init (gsl_shell_mutex, NULL); + lua_State *L = lua_open(); /* create state */ if (L == NULL) { l_message(argv[0], "cannot create state: not enough memory"); @@ -500,3 +547,14 @@ int main (int argc, char **argv) { lua_close(L); return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; } + +void +gsl_shell_unref_plot (int id) +{ + struct window_unref_cell *cell = malloc(sizeof(struct window_unref_cell)); + + cell->id = id; + cell->next = window_unref_list; + + window_unref_list = cell; +} diff --git a/gsl-shell.h b/gsl-shell.h index af7088b5..3b575e98 100644 --- a/gsl-shell.h +++ b/gsl-shell.h @@ -1,6 +1,21 @@ #ifndef GSL_SHELL_INCLUDED #define GSL_SHELL_INCLUDED -extern int error_report (lua_State *L, int status); +#include "defs.h" +#include <pthread.h> + +__BEGIN_DECLS + +#include "lua.h" + +extern int error_report (lua_State *L, int status); +extern void gsl_shell_unref_plot (int id); + +extern pthread_mutex_t gsl_shell_mutex[1]; + +__END_DECLS + +#define GSL_SHELL_LOCK() pthread_mutex_lock (gsl_shell_mutex) +#define GSL_SHELL_UNLOCK() pthread_mutex_unlock (gsl_shell_mutex) #endif @@ -46,6 +46,7 @@ #ifdef AGG_PLOT_ENABLED #include "lua-plot.h" +#include "lua-draw.h" #endif static const struct luaL_Reg gsl_methods_dummy[] = {{NULL, NULL}}; @@ -55,6 +56,8 @@ luaopen_gsl (lua_State *L) { gsl_set_error_handler_off (); + prepare_window_ref_table (L); + #ifdef USE_SEPARATE_NAMESPACE luaL_register (L, MLUA_GSLLIBNAME, gsl_methods_dummy); #else @@ -79,6 +82,7 @@ luaopen_gsl (lua_State *L) bspline_register (L); #ifdef AGG_PLOT_ENABLED plot_register (L); + draw_register (L); #endif #ifdef LNUM_COMPLEX diff --git a/lua-plot.c b/lua-plot.c deleted file mode 100644 index a4908c12..00000000 --- a/lua-plot.c +++ /dev/null @@ -1,832 +0,0 @@ - -#include <assert.h> -#include <string.h> -#include <pthread.h> - -#include "lua.h" -#include "lauxlib.h" - -#include "gs-types.h" -#include "common.h" -#include "gsl-shell.h" -#include "lua-utils.h" -#include "lua-plot-priv.h" -#include "xwin-show.h" -#include "colors.h" - -extern void plot_register (lua_State *L); - -pthread_mutex_t agg_mutex[1]; - -enum agg_type { - AGG_PATH = 1, - AGG_TEXT, -}; - -struct agg_obj { - enum agg_type tag; - CVERTSRC *vs; -}; - -struct path_cmd_reg { - enum path_cmd_e id; - const char *cmd; - const char *signature; -}; - -extern int push_new_agg_obj (lua_State *L, enum agg_type tag, CVERTSRC *vs); - -static int agg_obj_free (lua_State *L); -static int agg_obj_index (lua_State *L); - -static int agg_path_new (lua_State *L); -static int agg_path_index (lua_State *L); - -static int agg_text_new (lua_State *L); -static int agg_text_index (lua_State *L); -static int agg_text_set_text (lua_State *L); -static int agg_text_set_point (lua_State *L); -static int agg_text_rotate (lua_State *L); - -static int agg_plot_new (lua_State *L); -static int agg_plot_show (lua_State *L); -static int agg_plot_add (lua_State *L); -static int agg_plot_update (lua_State *L); -static int agg_plot_add_line (lua_State *L); -static int agg_plot_index (lua_State *L); -static int agg_plot_newindex (lua_State *L); -static int agg_plot_free (lua_State *L); -static int agg_plot_title_set (lua_State *L); -static int agg_plot_title_get (lua_State *L); -static int agg_plot_units_set (lua_State *L); -static int agg_plot_units_get (lua_State *L); - -static int agg_rgb_new (lua_State *L); -static int agg_rgba_new (lua_State *L); - -struct agg_obj* check_agg_obj (lua_State *L, int index); -path * check_agg_path (lua_State *L, int index); -CTEXT * check_agg_text (lua_State *L, int index); -struct agg_plot* check_agg_plot (lua_State *L, int index); - -static struct path_cmd_reg cmd_table[] = { - {CMD_MOVE_TO, "move_to", "ff"}, - {CMD_LINE_TO, "line_to", "ff"}, - {CMD_CLOSE, "close", ""}, - {CMD_ARC_TO, "arc_to", "fffbbff"}, - {CMD_CURVE3, "curve3", "ffff"}, - {CMD_CURVE4, "curve4", "ffffff"}, - {CMD_ERROR, NULL, NULL} -}; - -static const struct luaL_Reg plot_functions[] = { - {"path", agg_path_new}, - {"text", agg_text_new}, - {"rgba", agg_rgba_new}, - {"rgb", agg_rgb_new}, - {"plot", agg_plot_new}, - {NULL, NULL} -}; - -static const struct luaL_Reg agg_vertex_source_methods[] = { - {"__index", agg_obj_index}, - {"__gc", agg_obj_free}, - {NULL, NULL} -}; - -static const struct luaL_Reg agg_plot_methods[] = { - {"show", agg_plot_show }, - {"add", agg_plot_add }, - {"addline", agg_plot_add_line }, - {"update", agg_plot_update }, - {"__index", agg_plot_index }, - {"__newindex", agg_plot_newindex }, - {"__gc", agg_plot_free }, - {NULL, NULL} -}; - -static const struct luaL_Reg agg_plot_properties_get[] = { - {"title", agg_plot_title_get }, - {"units", agg_plot_units_get }, - {NULL, NULL} -}; - -static const struct luaL_Reg agg_plot_properties_set[] = { - {"title", agg_plot_title_set }, - {"units", agg_plot_units_set }, - {NULL, NULL} -}; - -static const struct luaL_Reg rgba_methods[] = { - {NULL, NULL} -}; - -static const struct luaL_Reg agg_text_methods[] = { - {"set_point", agg_text_set_point}, - {"set_text", agg_text_set_text}, - {"rotate", agg_text_rotate}, - {NULL, NULL} -}; - -static void -update_plot_wait (struct agg_plot *p) -{ - if (p->window) - update_callback (p->window); -} - -int -push_new_agg_obj (lua_State *L, enum agg_type tag, CVERTSRC *vs) -{ - struct agg_obj *d = lua_newuserdata (L, sizeof (struct agg_obj)); - - d->vs = vs; - d->tag = tag; - - vertex_source_ref (d->vs); - - gs_set_metatable (L, GS_DRAW_OBJ); - - return 1; -} - -int -agg_path_new (lua_State *L) -{ - CPATH *vs = path_new (); - push_new_agg_obj (L, AGG_PATH, (CVERTSRC *) vs); - - if (lua_gettop (L) >= 2) - { - double x = gs_check_number (L, 1, FP_CHECK_NORMAL); - double y = gs_check_number (L, 2, FP_CHECK_NORMAL); - struct cmd_call_stack s[1]; - - s->f[0] = x; - s->f[1] = y; - - path_cmd (vs, CMD_MOVE_TO, s); - } - - return 1; -} - -struct agg_obj * -check_agg_obj (lua_State *L, int index) -{ - return gs_check_userdata (L, index, GS_DRAW_OBJ); -} - -path * -check_agg_path (lua_State *L, int index) -{ - struct agg_obj *d = gs_check_userdata (L, index, GS_DRAW_OBJ); - if (d->tag == AGG_PATH) - return (path *) d->vs; - luaL_error (L, "expected object of type 'path' as argument #%i", index); - return NULL; -} - -int -agg_obj_free (lua_State *L) -{ - struct agg_obj *d = check_agg_obj (L, 1); -#ifdef DEBUG_PLOT - fprintf(stderr, "lua dispose drawable %p\n", d->vs); -#endif - vertex_source_unref (d->vs); - return 0; -} - -static int -agg_path_cmd (lua_State *L) -{ - path *p = check_agg_path (L, 1); - int id = lua_tointeger (L, lua_upvalueindex(1)); - const char *signature = lua_tostring (L, lua_upvalueindex(2)); - int argc = 2, f_count = 0, b_count = 0; - struct cmd_call_stack s[1]; - const char *fc; - - for (fc = signature; fc[0]; fc++) - { - switch (fc[0]) - { - case 'f': - s->f[f_count++] = gs_check_number (L, argc++, FP_CHECK_NORMAL); - break; - case 'b': - if (lua_isboolean (L, argc)) - s->b[b_count++] = lua_toboolean (L, argc++); - else - return luaL_error (L, "expected boolean for argument #%i", argc); - } - } - - pthread_mutex_lock (agg_mutex); - path_cmd (p, id, s); - pthread_mutex_unlock (agg_mutex); - return 0; -} - -static int -agg_obj_pcall (lua_State *L) -{ - int narg_out, narg_in = lua_gettop (L); - int status; - - pthread_mutex_lock (agg_mutex); - lua_pushvalue (L, lua_upvalueindex(1)); - lua_insert (L, 1); - status = lua_pcall (L, narg_in, LUA_MULTRET, 0); - pthread_mutex_unlock (agg_mutex); - if (status != 0) - { -#ifndef LUA_MODULE - error_report (L, status); -#else - luaL_error (L, "error in graphical object method"); -#endif - return 0; - } - narg_out = lua_gettop (L); - return narg_out; -} - - -int -agg_obj_index (lua_State *L) -{ - struct agg_obj *d = check_agg_obj (L, 1); - - lua_getmetatable (L, 1); - lua_rawgeti (L, -1, (int) d->tag); - lua_remove (L, -2); - lua_insert (L, 1); - - lua_call (L, 2, 1); - - if (d->tag == AGG_PATH) - return 1; - - if (! lua_isnil (L, -1)) - { - lua_pushcclosure (L, agg_obj_pcall, 1); - return 1; - } - - return 0; -} - -int -agg_path_index (lua_State *L) -{ - struct path_cmd_reg *r; - const char *key; - - if (! lua_isstring (L, 2)) - return 0; - - key = lua_tostring (L, 2); - for (r = cmd_table; r->cmd; r++) - { - if (strcmp (key, r->cmd) == 0) - break; - } - - if (r->cmd) - { - lua_pushinteger (L, (int) r->id); - lua_pushstring (L, r->signature); - lua_pushcclosure (L, agg_path_cmd, 2); - return 1; - } - - return 0; -} - -CTEXT * -check_agg_text (lua_State *L, int index) -{ - struct agg_obj *d = gs_check_userdata (L, index, GS_DRAW_OBJ); - if (d->tag == AGG_TEXT) - return (CTEXT *) d->vs; - luaL_error (L, "expected object of type 'text' as argument #%i", index); - return NULL; -} - -int -agg_text_new (lua_State *L) -{ - double size = luaL_optnumber (L, 1, 10.0); - double width = luaL_optnumber (L, 2, 1.0); - CVERTSRC *vs = (CVERTSRC *) text_new (size, width); - push_new_agg_obj (L, AGG_TEXT, vs); - return 1; -} - -int -agg_text_set_text (lua_State *L) -{ - CTEXT *t = check_agg_text (L, 1); - const char *text = luaL_checkstring (L, 2); - text_set_text (t, text); - return 0; -} - -int -agg_text_set_point (lua_State *L) -{ - CTEXT *t = check_agg_text (L, 1); - double x = luaL_checknumber (L, 2); - double y = luaL_checknumber (L, 3); - text_set_point (t, x, y); - return 0; -} - -int -agg_text_rotate (lua_State *L) -{ - CTEXT *t = check_agg_text (L, 1); - double a = luaL_checknumber (L, 2); - text_rotate (t, a); - return 0; -}; - -int -agg_text_index (lua_State *L) -{ - const struct luaL_Reg *reg; - const char *key; - - if (! lua_isstring (L, 2)) - return 0; - - key = lua_tostring (L, 2); - reg = mlua_find_method (agg_text_methods, key); - if (reg) - { - lua_pushcfunction (L, reg->func); - return 1; - } - - return 0; -} - -struct agg_plot * -check_agg_plot (lua_State *L, int index) -{ - struct agg_plot **ptr = gs_check_userdata (L, index, GS_PLOT); - return *ptr; -} - -int -agg_plot_new (lua_State *L) -{ - struct agg_plot **pptr = lua_newuserdata (L, sizeof(void *)); - struct agg_plot *p; - const char *title = NULL; - - if (lua_isstring (L, 1)) - title = lua_tostring (L, 1); - - p = emalloc (sizeof(struct agg_plot)); - *pptr = p; - - p->plot = plot_new (title); - - p->lua_is_owner = 1; - p->is_shown = 0; - p->window = NULL; - - gs_set_metatable (L, GS_PLOT); - - return 1; -} - -void -agg_plot_destroy (struct agg_plot *p) -{ - plot_free (p->plot); - free (p); -} - -int -agg_plot_free (lua_State *L) -{ - struct agg_plot *p = check_agg_plot (L, 1); - -#ifdef DEBUG_PLOT - fprintf(stderr, "lua dispose plot %p", p->plot); -#endif - - pthread_mutex_lock (agg_mutex); - - assert (p->lua_is_owner); - p->lua_is_owner = 0; - - if (! p->is_shown) - { -#ifdef DEBUG_PLOT - fprintf(stderr, ": destroying\n"); -#endif - agg_plot_destroy (p); - } -#ifdef DEBUG_PLOT - else - { - fprintf(stderr, ": plot is shown\n"); - } -#endif - - pthread_mutex_unlock (agg_mutex); - return 0; -} - -int -agg_plot_index (lua_State *L) -{ - return mlua_index_with_properties (L, agg_plot_properties_get, false); -} - -int -agg_plot_title_set (lua_State *L) -{ - struct agg_plot *p = check_agg_plot (L, 1); - const char *title = lua_tostring (L, 2); - - if (title == NULL) - return gs_type_error (L, 2, "string"); - - pthread_mutex_lock (agg_mutex); - plot_set_title (p->plot, title); - update_plot_wait (p); - pthread_mutex_unlock (agg_mutex); - - return 0; -} - -int -agg_plot_title_get (lua_State *L) -{ - struct agg_plot *p = check_agg_plot (L, 1); - const char *title = plot_get_title (p->plot); - lua_pushstring (L, title); - return 1; -} - -int -agg_plot_units_set (lua_State *L) -{ - struct agg_plot *p = check_agg_plot (L, 1); - bool request = lua_toboolean (L, 2); - bool current = plot_use_units (p->plot); - - if (current != request) - { - pthread_mutex_lock (agg_mutex); - plot_set_units (p->plot, request); - update_plot_wait (p); - pthread_mutex_unlock (agg_mutex); - } - - return 0; -} - -int -agg_plot_units_get (lua_State *L) -{ - struct agg_plot *p = check_agg_plot (L, 1); - lua_pushboolean (L, plot_use_units (p->plot)); - return 1; -} - -int -agg_plot_newindex (lua_State *L) -{ - return mlua_newindex_with_properties (L, agg_plot_properties_set); -} - -static int -property_lookup (struct property_reg *prop, const char *key) -{ - int default_value = prop->id; - - if (key == NULL) - return default_value; - - for ( ; prop->name; prop++) - { - if (strcmp (prop->name, key) == 0) - return prop->id; - } - - return default_value; -} - -struct trans_spec * -parse_spec (lua_State *L, int index, struct trans_spec *spec) -{ - const char *tag; - - lua_rawgeti (L, index, 1); - if (! lua_isstring (L, -1)) - { - lua_pop (L, 1); - return NULL; - } - - tag = lua_tostring (L, -1); - lua_pop (L, 1); - - if (strcmp (tag, "stroke") == 0) - { - struct stroke_spec *prop = &spec->content.stroke; - const char *prop_key; - prop->width = mlua_named_optnumber (L, index, "width", 1.0); - - prop_key = mlua_named_optstring (L, index, "cap", NULL); - prop->line_cap = property_lookup (line_cap_properties, prop_key); - - prop_key = mlua_named_optstring (L, index, "join", NULL); - prop->line_join = property_lookup (line_join_properties, prop_key); - - spec->tag = trans_stroke; - return spec; - } - else if (strcmp (tag, "marker") == 0) - { - struct marker_spec *prop = &spec->content.marker; - prop->size = mlua_named_optnumber (L, index, "size", 3.0); - spec->tag = trans_marker; - return spec; - } - else if (strcmp (tag, "dash") == 0) - { - struct dash_spec *prop = &spec->content.dash; - prop->len[0] = mlua_named_optnumber (L, index, "a", 10.0); - prop->len[1] = mlua_named_optnumber (L, index, "b", prop->len[0]); - spec->tag = trans_dash; - return spec; - } - else if (strcmp (tag, "curve") == 0) - { - spec->tag = trans_curve; - return spec; - } - else if (strcmp (tag, "rotate") == 0) - { - double a = mlua_named_number (L, index, "angle"); - spec->tag = trans_rotate; - spec->content.rotate.angle = a; - return spec; - } - else if (strcmp (tag, "translate") == 0) - { - double x = mlua_named_number (L, index, "x"); - double y = mlua_named_number (L, index, "y"); - spec->tag = trans_translate; - spec->content.translate.x = x; - spec->content.translate.y = y; - return spec; - } - return NULL; -} - -int -lparse_spec_pipeline (lua_State *L) -{ - struct trans_spec *spec; - size_t k, nb; - - if (lua_type (L, 1) == LUA_TTABLE) - nb = lua_objlen (L, 1); - else - return luaL_error (L, "post transform argument should be an array"); - - spec = lua_newuserdata (L, (nb+1) * sizeof(struct trans_spec)); - for (k = 0; k < nb; k++) - { - lua_rawgeti (L, 1, k+1); - if (parse_spec (L, lua_gettop (L), spec + k) == NULL) - return luaL_error (L, "error in definition of post transforms"); - lua_pop (L, 1); - } - - spec[k].tag = trans_end; - - return 1; -} - -static struct trans_spec * -push_empty_pipeline (lua_State *L) -{ - struct trans_spec *spec; - spec = lua_newuserdata (L, sizeof(struct trans_spec)); - spec->tag = trans_end; - return spec; -} - -static void -check_color (lua_State *L, int index, struct color *c) -{ - if (lua_isnil (L, index)) - { - set_color_default (c); - } - else if (lua_isstring (L, index)) - { - const char *cstr = lua_tostring (L, index); - color_lookup (c, cstr); - } - else - { - struct color *userc = gs_check_userdata (L, index, GS_RGBA_COLOR); - *c = *userc; /* struct assignement is ok in ANSI C */ - } -} - -static int -agg_plot_add_gener (lua_State *L, bool as_line) -{ - struct agg_plot *p = check_agg_plot (L, 1); - struct agg_obj *d = check_agg_obj (L, 2); - struct trans_spec *post, *pre; - int narg = lua_gettop (L); - struct color color[1]; - - if (narg <= 2) - set_color_default (color); - else - check_color (L, 3, color); - - if (narg > 3) - { - lua_pushcfunction (L, lparse_spec_pipeline); - lua_pushvalue (L, 4); - lua_call (L, 1, 1); - post = lua_touserdata (L, -1); - } - else - { - post = push_empty_pipeline (L); - } - - assert (post != NULL); - - if (narg > 4) - { - lua_pushcfunction (L, lparse_spec_pipeline); - lua_pushvalue (L, 5); - lua_call (L, 1, 1); - pre = lua_touserdata (L, -1); - } - else - { - pre = push_empty_pipeline (L); - } - - assert (pre != NULL); - - pthread_mutex_lock (agg_mutex); -#ifdef DEBUG_PLOT - printf("acquired mutex\n"); -#endif - plot_add (p->plot, d->vs, color, post, pre, as_line); - -#ifdef DEBUG_PLOT - printf("drawing\n"); -#endif - update_plot_wait (p); - pthread_mutex_unlock (agg_mutex); -#ifdef DEBUG_PLOT - printf("unlocked mutex\n"); -#endif - - return 0; -} - -int -agg_plot_add (lua_State *L) -{ - return agg_plot_add_gener (L, false); -} - -int -agg_plot_update (lua_State *L) -{ - struct agg_plot *p = check_agg_plot (L, 1); - pthread_mutex_lock (agg_mutex); - update_plot_wait (p); - pthread_mutex_unlock (agg_mutex); - return 0; -} - -int -agg_plot_add_line (lua_State *L) -{ - return agg_plot_add_gener (L, true); -} - -int -agg_plot_show (lua_State *L) -{ - struct agg_plot *cp = check_agg_plot (L, 1); - pthread_t xwin_thread[1]; - pthread_attr_t attr[1]; - - pthread_mutex_lock (agg_mutex); - - if (! cp->is_shown) - { - pthread_attr_init (attr); - pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED); - - if (pthread_create(xwin_thread, attr, xwin_thread_function, (void*) cp)) - { - pthread_attr_destroy (attr); - return luaL_error(L, "error creating thread."); - } - - cp->is_shown = 1; - pthread_attr_destroy (attr); - } - - pthread_mutex_unlock (agg_mutex); - - return 0; -} - -static unsigned int double2uint8 (double x) -{ - int u = x * 255.0; - if (u > 255) - u = 255; - else if (u < 0) - u = 0; - return (unsigned int) u; -} - -int -agg_rgba_new (lua_State *L) -{ - double r = luaL_checknumber (L, 1); - double g = luaL_checknumber (L, 2); - double b = luaL_checknumber (L, 3); - double a = luaL_checknumber (L, 4); - struct color *c = lua_newuserdata (L, sizeof(struct color)); - c->r = double2uint8 (r); - c->g = double2uint8 (g); - c->b = double2uint8 (b); - c->a = double2uint8 (a); - - gs_set_metatable (L, GS_RGBA_COLOR); - - return 1; -} - -int -agg_rgb_new (lua_State *L) -{ - double r = luaL_checknumber (L, 1); - double g = luaL_checknumber (L, 2); - double b = luaL_checknumber (L, 3); - struct color *c = lua_newuserdata (L, sizeof(struct color)); - c->r = double2uint8 (r); - c->g = double2uint8 (g); - c->b = double2uint8 (b); - c->a = 255; - - gs_set_metatable (L, GS_RGBA_COLOR); - - return 1; -} - -void -plot_register (lua_State *L) -{ - pthread_mutex_init (agg_mutex, NULL); - - /* plot declaration */ - luaL_newmetatable (L, GS_METATABLE(GS_PLOT)); - luaL_register (L, NULL, agg_plot_methods); - lua_pop (L, 1); - - /* line declaration */ - luaL_newmetatable (L, GS_METATABLE(GS_DRAW_OBJ)); - lua_pushinteger (L, (int) AGG_PATH); - lua_pushcfunction (L, agg_path_index); - lua_settable (L, -3); - lua_pushinteger (L, (int) AGG_TEXT); - lua_pushcfunction (L, agg_text_index); - lua_settable (L, -3); - luaL_register (L, NULL, agg_vertex_source_methods); - lua_pop (L, 1); - - luaL_newmetatable (L, GS_METATABLE(GS_RGBA_COLOR)); - luaL_register (L, NULL, rgba_methods); - lua_pop (L, 1); - - /* gsl module registration */ - luaL_register (L, NULL, plot_functions); -} diff --git a/lua-plot.h b/lua-plot.h deleted file mode 100644 index 6a71093c..00000000 --- a/lua-plot.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef LUA_CPLOT_H
-#define LUA_CPLOT_H
-
-#include <pthread.h>
-
-#include "lua.h"
-
-#include "defs.h"
-
-__BEGIN_DECLS
-
-extern void plot_register (lua_State *L);
-
-__END_DECLS
-
-#endif
diff --git a/lua-utils.c b/lua-utils.c index 7f0e465a..24a065c5 100644 --- a/lua-utils.c +++ b/lua-utils.c @@ -206,3 +206,62 @@ mlua_fenv_get (lua_State *L, int index, int fenv_index) lua_rawgeti (L, -1, fenv_index);
lua_remove (L, -2);
}
+
+void
+mlua_fenv_addref (lua_State *L, int refindex)
+{
+ int n;
+ lua_getfenv (L, -1);
+ n = lua_objlen (L, -1);
+ lua_pushvalue (L, refindex);
+ lua_rawseti (L, -2, n+1);
+ lua_pop (L, 1);
+}
+
+void
+mlua_set_fenv_ref (lua_State *L, int refindex)
+{
+ int n;
+ lua_newtable (L);
+ lua_pushvalue (L, refindex);
+ lua_rawseti (L, -2, 1);
+ lua_setfenv (L, -2);
+}
+
+void
+prepare_window_ref_table (lua_State *L)
+{
+ lua_newtable (L);
+ lua_pushinteger (L, 0);
+ lua_setfield (L, -2, "N");
+ lua_setfield (L, LUA_REGISTRYINDEX, "GSL.windows");
+}
+
+int
+mlua_window_ref(lua_State *L, int index)
+{
+ int n;
+
+ lua_getfield (L, LUA_REGISTRYINDEX, "GSL.windows");
+
+ lua_getfield (L, -1, "N");
+ n = lua_tointeger (L, -1);
+ lua_pushinteger (L, n+1);
+ lua_remove (L, -2);
+ lua_setfield (L, -2, "N");
+
+ lua_pushvalue (L, index);
+ lua_rawseti (L, -2, n+1);
+ lua_pop (L, 1);
+
+ return n+1;
+}
+
+void
+mlua_window_unref(lua_State *L, int id)
+{
+ lua_getfield (L, LUA_REGISTRYINDEX, "GSL.windows");
+ lua_pushnil (L);
+ lua_rawseti (L, -2, id);
+ lua_pop (L, 1);
+}
diff --git a/lua-utils.h b/lua-utils.h index e2a08fb6..780645f7 100644 --- a/lua-utils.h +++ b/lua-utils.h @@ -22,7 +22,10 @@ #define LUA_UTILS_H
#include "defs.h"
-#include <lua.h>
+
+__BEGIN_DECLS
+
+#include "lua.h"
extern void
mlua_openlibs (lua_State *L);
@@ -63,5 +66,14 @@ extern lua_Number mlua_named_number (lua_State *L, int index, extern void mlua_fenv_set (lua_State *L, int index, int fenv_index);
extern void mlua_fenv_get (lua_State *L, int index, int fenv_index);
+extern void mlua_fenv_addref (lua_State *L, int refindex);
+extern void mlua_set_fenv_ref (lua_State *L, int refidx);
+extern int mlua_window_ref (lua_State *L, int index);
+extern void mlua_window_unref (lua_State *L, int id);
+
+extern void prepare_window_ref_table (lua_State *L);
+
+__END_DECLS
+
#endif
diff --git a/lua/src/lua.h b/lua/src/lua.h index 7b277567..a0f0a20f 100644 --- a/lua/src/lua.h +++ b/lua/src/lua.h @@ -270,8 +270,16 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); * the module really wants to use them. */ #ifdef LNUM_COMPLEX +#ifdef __cplusplus + struct _double_complex { + double re; + double im; + }; + typedef struct _double_complex lua_Complex; +#else #include <complex.h> typedef LUA_NUMBER complex lua_Complex; +#endif LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx); LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v); #endif diff --git a/make-packages b/make-packages index 0c0df913..90a276a7 100644 --- a/make-packages +++ b/make-packages @@ -22,12 +22,13 @@ ifeq ($(strip $(PLATFORM)), mingw) AGG_HOME = /c/fra/src/agg-2.5
PTHREADS_HOME = /usr/pthreads-w32
- AGG_CFLAGS = -I$(AGG_HOME)/include
+ AGG_INCLUDES = -I$(AGG_HOME)/include
AGG_LIBS = -L$(AGG_HOME)/src -lagg -lgdi32 -lsupc++
PTHREADS_CFLAGS = -I$(PTHREADS_HOME)/include
PTHREADS_LIBS = -L$(PTHREADS_HOME)/lib -lpthreadGC2
else
+ AGG_INCLUDES = -I/usr/include/agg2
AGG_LIBS = -lagg -lX11 -lpthread -lsupc++
PTHREADS_LIBS = -lpthread
endif
diff --git a/scripts/project-diff.sh b/scripts/project-diff.sh deleted file mode 100644 index c6d8c5f7..00000000 --- a/scripts/project-diff.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -for LCFX in `find . -type f`; do - LCF=`echo $LCFX | awk '{ gsub(/^\.\//, ""); print 0ドル }'`; - RPF="$HOME/sviluppo/gsl-shell/$LCF"; - echo "Treating: $LCF"; - diff -U 4 $LCF $RPF; -done diff --git a/scripts/project-dir-compare.py b/scripts/project-dir-compare.py new file mode 100644 index 00000000..67f14943 --- /dev/null +++ b/scripts/project-dir-compare.py @@ -0,0 +1,101 @@ +import os +import re +import sys + +def differs(fna, fnb): + fa, fb = open(fna, 'r'), open(fnb, 'r') + for la, lb in zip(fa, fb): + if la != lb: return True + return False + +def exists(fn): + try: + os.stat(fn) + return True + except: + return False + +fulldira = sys.argv[1] +fulldirb = sys.argv[2] + +# basedir = '/home/francesco/sviluppo' + +# dira = 'gsl-shell' +# dirb = 'gsl-shell-win-branch' + +# fulldira = os.path.join(basedir, dira) +# fulldirb = os.path.join(basedir, dirb) + +dir_ignore = [r'\.(git|svn|deps|libs)$', r'^doc/html$', r'^www$'] +file_ignore = [r'~$', r'\.o$'] + +treated, absenta, absentb, differ = [], [], [], [] + +def sh_ignore(fn, ignore_list): + for patt in ignore_list: + if re.search(patt, fn): + return True + return False + +def sh_ignore_dir(fn): + return sh_ignore(fn, dir_ignore) + +def sh_ignore_file(fn): + return sh_ignore(fn, file_ignore) + +def get_rel_path(fn, rpath, base): + fullname = os.path.join(rpath, fn) + return os.path.relpath(fullname, start= base) + +def dir_filter(dirnames, rpath, basedir): + to_be_removed = [] + for dr in dirnames: + drrel = get_rel_path(dr, rpath, basedir) + if sh_ignore_dir(drrel): + to_be_removed.append(dr) + + for dr in to_be_removed: + dirnames.remove(dr) + +def project_scan(basedir): + for rpath, dirnames, filenames in os.walk(basedir): + for filename in filenames: + rel = get_rel_path(filename, rpath, basedir) + if not sh_ignore_file(rel): + yield rel + dir_filter(dirnames, rpath, basedir) + +for filename in project_scan(fulldira): + treated.append(filename) + + filenamea = os.path.join(fulldira, filename) + filenameb = os.path.join(fulldirb, filename) + + if not exists(filenameb): + absentb.append(filename) + else: + if differs(filenamea, filenameb): + differ.append(filename) + +for filename in project_scan(fulldirb): + if not filename in treated: + absenta.append(filename) + +print 'Absent A:' +for nm in absenta: + print '+ ', nm + +print 'Absent B:' +for nm in absentb: + print '- ', nm + +print 'Differ:' +for nm in differ: + print nm + +print '-'*25 + ' DIFF OUTPUT ' + '-'*25 +for nm in differ: + cmd = 'diff -U 4 %s %s' % (os.path.join(fulldira, nm), os.path.join(fulldirb, nm)) + diffout = os.popen(cmd) + for ln in diffout: + print ln, |