author | Francesco Abbate <francesco.bbt@gmail.com> | 2012年08月12日 19:10:04 +0200 |
---|---|---|
committer | Francesco Abbate <francesco.bbt@gmail.com> | 2012年08月12日 19:10:04 +0200 |
commit | 89ea79b27cf99ce3d3ec703ca53f6fac2c1c683b (patch) | |
tree | 1e9819900b5086e72ba803ddbe8532533c245cb8 | |
parent | 427d762746455aaf88b2935de122e7201634d8f8 (diff) | |
download | gsl-shell-89ea79b27cf99ce3d3ec703ca53f6fac2c1c683b.tar.gz |
-rw-r--r-- | agg-plot/lua-graph.cpp | 2 | ||||
-rw-r--r-- | agg-plot/window_hooks.h | 1 | ||||
-rw-r--r-- | fox-gui/fox_gsl_shell.cpp | 7 | ||||
-rw-r--r-- | fox-gui/fox_gsl_shell.h | 3 | ||||
-rw-r--r-- | fox-gui/gsl-shell-fox.cpp | 1 | ||||
-rw-r--r-- | fox-gui/gsl_shell_app.cpp | 60 | ||||
-rw-r--r-- | fox-gui/gsl_shell_app.h | 26 | ||||
-rw-r--r-- | fox-gui/gsl_shell_thread.cpp | 33 | ||||
-rw-r--r-- | fox-gui/gsl_shell_thread.h | 7 | ||||
-rw-r--r-- | fox-gui/gsl_shell_window.cpp | 1 | ||||
-rw-r--r-- | fox-gui/lua_plot_window.cpp | 17 | ||||
-rw-r--r-- | fox-gui/lua_plot_window.h | 1 | ||||
-rw-r--r-- | gsl-shell-jit.c | 1 |
diff --git a/agg-plot/lua-graph.cpp b/agg-plot/lua-graph.cpp index c056a10b..34f3cace 100644 --- a/agg-plot/lua-graph.cpp +++ b/agg-plot/lua-graph.cpp @@ -43,7 +43,7 @@ pthread_mutex_t agg_mutex[1]; void graph_close_windows (lua_State *L) { - window_index_apply_all (L, window_close_wait); + window_index_apply_all (L, app_window_hooks->close); } void diff --git a/agg-plot/window_hooks.h b/agg-plot/window_hooks.h index e39350eb..d91ddcd6 100644 --- a/agg-plot/window_hooks.h +++ b/agg-plot/window_hooks.h @@ -12,6 +12,7 @@ struct window_hooks { int (*attach)(lua_State* L); int (*update)(lua_State* L); int (*refresh)(lua_State* L); + int (*close)(lua_State* L); int (*save_image)(lua_State* L); int (*restore_image)(lua_State* L); diff --git a/fox-gui/fox_gsl_shell.cpp b/fox-gui/fox_gsl_shell.cpp index 46a985df..019c3a7e 100644 --- a/fox-gui/fox_gsl_shell.cpp +++ b/fox-gui/fox_gsl_shell.cpp @@ -2,12 +2,19 @@ #include "fox_gsl_shell.h" #include "lua_plot_window.h" #include "window_registry.h" +#include "lua-graph.h" void fox_gsl_shell::init() { gsl_shell_thread::init(); } +void fox_gsl_shell::close() +{ + graph_close_windows(L); + gsl_shell_thread::close(); +} + void fox_gsl_shell::before_eval() { diff --git a/fox-gui/fox_gsl_shell.h b/fox-gui/fox_gsl_shell.h index 66379665..406bb8fb 100644 --- a/fox-gui/fox_gsl_shell.h +++ b/fox-gui/fox_gsl_shell.h @@ -14,7 +14,10 @@ public: ~fox_gsl_shell() { delete m_close; } virtual void init(); + virtual void close(); + virtual void before_eval(); + // virtual void restart_callback(); virtual void quit_callback(); void set_closing_signal(FXGUISignal* s) { m_close = s; } diff --git a/fox-gui/gsl-shell-fox.cpp b/fox-gui/gsl-shell-fox.cpp index 1064819c..c70abb32 100644 --- a/fox-gui/gsl-shell-fox.cpp +++ b/fox-gui/gsl-shell-fox.cpp @@ -7,6 +7,7 @@ struct window_hooks app_window_hooks[1] = {{ fox_window_new, fox_window_attach, fox_window_slot_update, fox_window_slot_refresh, + fox_window_close, fox_window_save_slot_image, fox_window_restore_slot_image, fox_window_register, } diff --git a/fox-gui/gsl_shell_app.cpp b/fox-gui/gsl_shell_app.cpp index b32d2878..057abef2 100644 --- a/fox-gui/gsl_shell_app.cpp +++ b/fox-gui/gsl_shell_app.cpp @@ -12,6 +12,7 @@ FXDEFMAP(gsl_shell_app) gsl_shell_app_map[]= FXMAPFUNC(SEL_IO_READ, gsl_shell_app::ID_LUA_REQUEST, gsl_shell_app::on_lua_request), FXMAPFUNC(SEL_IO_READ, gsl_shell_app::ID_LUA_QUIT, gsl_shell_app::on_lua_quit), FXMAPFUNC(SEL_COMMAND, gsl_shell_app::ID_CONSOLE_CLOSE, gsl_shell_app::on_console_close), + FXMAPFUNC(SEL_COMMAND, gsl_shell_app::ID_LUA_RESTART, gsl_shell_app::on_restart_lua_request), FXMAPFUNC(SEL_CLOSE, 0, gsl_shell_app::on_window_close), }; @@ -22,7 +23,7 @@ gsl_shell_app* global_app; gsl_shell_app::gsl_shell_app() : FXApp("GSL Shell", "GSL Shell"), m_engine(this) { - m_lua_request = new FXGUISignal(this, this, ID_LUA_REQUEST); + m_signal_request = new FXGUISignal(this, this, ID_LUA_REQUEST); FXGUISignal* quit = new FXGUISignal(this, this, ID_LUA_QUIT); m_engine.set_closing_signal(quit); @@ -35,41 +36,58 @@ gsl_shell_app::gsl_shell_app() : FXApp("GSL Shell", "GSL Shell"), gsl_shell_app::~gsl_shell_app() { - delete m_lua_request; + delete m_signal_request; +} + +void gsl_shell_app::window_create_request(FXMainWindow* win) +{ + m_request.cmd = create_window_rq; + m_request.win = win; + + m_signal_request->signal(); +} + +// this is called when Lua ask to close a window +void gsl_shell_app::window_close_request(FXMainWindow* win) +{ + m_request.cmd = close_window_rq; + m_request.win = win; + + m_signal_request->signal(); } long gsl_shell_app::on_lua_request(FXObject*, FXSelector, void*) { - for (unsigned k = 0; k < m_win_queue.size(); k++) + if (m_request.cmd == create_window_rq) { - FXMainWindow* win = m_win_queue[k]; + FXMainWindow* win = m_request.win; win->create(); win->show(PLACEMENT_SCREEN); + m_request.signal_done(); + } + else if (m_request.cmd == close_window_rq) + { + FXMainWindow* win = m_request.win; + win->close(TRUE); + m_request.signal_done(); } - m_win_queue.clear(); - m_window_mapping.signal(); + m_request.cmd = no_rq; return 1; } long gsl_shell_app::on_lua_quit(FXObject*, FXSelector, void*) { - m_engine.close(); exit(0); return 1; } -void gsl_shell_app::window_create_request(FXMainWindow* win) -{ - m_win_queue.add(win); - m_lua_request->signal(); -} - long gsl_shell_app::on_console_close(FXObject* sender, FXSelector, void*) { - m_engine.stop(); + m_engine.set_request(gsl_shell_thread::exit_request); return 1; } +// this is called when the user press the button to close the window. long gsl_shell_app::on_window_close(FXObject* sender, FXSelector, void*) { fx_plot_window* win = (fx_plot_window*) sender; @@ -77,8 +95,18 @@ long gsl_shell_app::on_window_close(FXObject* sender, FXSelector, void*) return 0; } -void gsl_shell_app::wait_window_mapping() +void gsl_shell_app::wait_action() { FXMutex& app_mutex = mutex(); - m_window_mapping.wait(app_mutex); + do + { + m_request.wait(app_mutex); + } + while (m_request.cmd != no_rq); +} + +long gsl_shell_app::on_restart_lua_request(FXObject*, FXSelector, void*) +{ + m_engine.set_request(gsl_shell_thread::restart_request); + return 0; } diff --git a/fox-gui/gsl_shell_app.h b/fox-gui/gsl_shell_app.h index f33e9a77..059e506e 100644 --- a/fox-gui/gsl_shell_app.h +++ b/fox-gui/gsl_shell_app.h @@ -9,6 +9,22 @@ class gsl_shell_app : public FXApp { FXDECLARE(gsl_shell_app) + + enum lua_request_e { no_rq = 0, create_window_rq, close_window_rq }; + + struct lua_request { + lua_request_e cmd; + FXMainWindow* win; + + lua_request(): cmd(no_rq) { } + + void signal_done() { m_term_cond.signal(); } + void wait(FXMutex& m) { m_term_cond.wait(m); } + + private: + FXCondition m_term_cond; + }; + public: gsl_shell_app(); ~gsl_shell_app(); @@ -23,26 +39,28 @@ public: } void window_create_request(FXMainWindow* win); - void wait_window_mapping(); + void window_close_request(FXMainWindow* win); + void wait_action(); long on_lua_request(FXObject*,FXSelector,void*); long on_window_close(FXObject*,FXSelector,void*); long on_console_close(FXObject*,FXSelector,void*); long on_lua_quit(FXObject*,FXSelector,void*); + long on_restart_lua_request(FXObject*,FXSelector,void*); enum { ID_LUA_REQUEST = FXApp::ID_LAST, ID_CONSOLE_CLOSE, + ID_LUA_RESTART, ID_LUA_QUIT, ID_LAST }; private: fox_gsl_shell m_engine; - FXGUISignal* m_lua_request; - agg::pod_bvector<FXMainWindow*> m_win_queue; - FXCondition m_window_mapping; + FXGUISignal* m_signal_request; + lua_request m_request; }; extern gsl_shell_app* global_app; diff --git a/fox-gui/gsl_shell_thread.cpp b/fox-gui/gsl_shell_thread.cpp index 1d2a452d..58d40a30 100644 --- a/fox-gui/gsl_shell_thread.cpp +++ b/fox-gui/gsl_shell_thread.cpp @@ -17,7 +17,7 @@ luajit_eval_thread (void *userdata) } gsl_shell_thread::gsl_shell_thread(): - m_status(starting), m_redirect(4096), m_exit_request(false) + m_status(starting), m_redirect(4096), m_request(no_request) { } @@ -44,7 +44,7 @@ void gsl_shell_thread::start() void gsl_shell_thread::run() { - while (!m_exit_request) + while (m_request != gsl_shell_thread::exit_request) { m_eval.lock(); m_status = ready; @@ -55,7 +55,7 @@ gsl_shell_thread::run() before_eval(); - if (m_exit_request) + if (m_request == gsl_shell_thread::exit_request) { m_eval.unlock(); break; @@ -64,24 +64,35 @@ gsl_shell_thread::run() m_status = busy; m_eval.unlock(); - // here m_line_pending cannot be modified by the other thread - // because we declared above m_status to "busy" befor unlocking m_eval - const char* line = m_line_pending.cstr(); - m_eval_status = this->exec(line); + if (m_request == gsl_shell_thread::restart_request) + { + this->close(); + this->init(); + restart_callback(); + m_request = gsl_shell_thread::no_request; + } + else + { + // here m_line_pending cannot be modified by the other thread + // because we declared above m_status to "busy" befor unlocking m_eval + const char* line = m_line_pending.cstr(); + m_eval_status = this->exec(line); - fputc(eot_character, stdout); - fflush(stdout); + fputc(eot_character, stdout); + fflush(stdout); + } } + this->close(); this->unlock(); quit_callback(); } void -gsl_shell_thread::stop() +gsl_shell_thread::set_request(gsl_shell_thread::request_e req) { m_eval.lock(); - m_exit_request = true; + m_request = req; m_eval.signal(); m_eval.unlock(); sched_yield(); diff --git a/fox-gui/gsl_shell_thread.h b/fox-gui/gsl_shell_thread.h index 06678183..81b254fc 100644 --- a/fox-gui/gsl_shell_thread.h +++ b/fox-gui/gsl_shell_thread.h @@ -14,17 +14,20 @@ class gsl_shell_thread : public gsl_shell { public: enum engine_status_e { starting, ready, busy, terminated }; + enum request_e { no_request = 0, exit_request, restart_request }; enum { eot_character = 0x04 }; gsl_shell_thread(); ~gsl_shell_thread(); + void set_request(request_e req); + void input(const char* line); void start(); void run(); - void stop(); virtual void before_eval() { } + virtual void restart_callback() { } virtual void quit_callback() { } void lock() @@ -54,7 +57,7 @@ private: pthread::cond m_eval; str m_line_pending; int m_eval_status; - bool m_exit_request; + request_e m_request; }; #endif diff --git a/fox-gui/gsl_shell_window.cpp b/fox-gui/gsl_shell_window.cpp index 49e69db1..62bf07fb 100644 --- a/fox-gui/gsl_shell_window.cpp +++ b/fox-gui/gsl_shell_window.cpp @@ -22,6 +22,7 @@ gsl_shell_window::gsl_shell_window(gsl_shell_thread* gs, FXApp* app, const FXStr m_status_bar = new FXStatusBar(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|FRAME_RAISED|STATUSBAR_WITH_DRAGCORNER); m_file_menu = new FXMenuPane(this); + new FXMenuCommand(m_file_menu, "&Restart\tCtl-R", NULL, app, gsl_shell_app::ID_LUA_RESTART); new FXMenuCommand(m_file_menu, "&Quit\tCtl-Q", NULL, this, FXTopWindow::ID_CLOSE); new FXMenuTitle(m_menu_bar, "&File", NULL, m_file_menu); diff --git a/fox-gui/lua_plot_window.cpp b/fox-gui/lua_plot_window.cpp index 9a3d3230..d609b8e3 100644 --- a/fox-gui/lua_plot_window.cpp +++ b/fox-gui/lua_plot_window.cpp @@ -15,8 +15,6 @@ extern "C" { __BEGIN_DECLS -static int fox_window_close (lua_State *L); - static const struct luaL_Reg fox_window_functions[] = { {"window", fox_window_new}, @@ -53,13 +51,10 @@ fox_window_new (lua_State *L) bwin->window = win; win->setTarget(app); - app->window_create_request(win); + app->window_create_request(win); win->lua_id = window_index_add (L, -1); - - do - app->wait_window_mapping(); - while (!win->shown()); + app->wait_action(); app->unlock(); return 1; @@ -82,6 +77,14 @@ fox_window_attach (lua_State *L) int fox_window_close (lua_State *L) { + fx_plot_window *win = object_check<lua_fox_window>(L, 1, GS_FOX_WINDOW)->window; + gsl_shell_app* app = win->get_app(); + + app->lock(); + app->window_close_request(win); + app->wait_action(); + app->unlock(); + return 0; } diff --git a/fox-gui/lua_plot_window.h b/fox-gui/lua_plot_window.h index 3ae8d18c..fb2aadac 100644 --- a/fox-gui/lua_plot_window.h +++ b/fox-gui/lua_plot_window.h @@ -11,6 +11,7 @@ extern void fox_window_register (lua_State *L); extern int fox_window_new (lua_State *L); extern int fox_window_attach (lua_State *L); +extern int fox_window_close (lua_State *L); extern int fox_window_slot_refresh (lua_State *L); extern int fox_window_slot_update (lua_State *L); extern int fox_window_save_slot_image (lua_State *L); diff --git a/gsl-shell-jit.c b/gsl-shell-jit.c index 7def3915..af943ebd 100644 --- a/gsl-shell-jit.c +++ b/gsl-shell-jit.c @@ -106,6 +106,7 @@ static const char *progname = LUA_PROGNAME; struct window_hooks app_window_hooks[1] = {{ window_new, window_attach, window_slot_update, window_slot_refresh, + window_close_wait, window_save_slot_image, window_restore_slot_image, window_register, } |