From dcecacbf52121d6f8adf076d2cebaeec1e141339 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 23 Aug 2012 20:23:19 +0200 Subject: Implement automatic reset/reload when script file changes on disc. --- src/luascript.cc | 154 ++++++++++++++++++++-------------------------------- src/luascript.h | 23 ++++---- src/mainwindow.cc | 26 ++++++++- src/mainwindow.h | 9 +++ src/outputwindow.cc | 30 +++++++--- src/outputwindow.h | 7 ++- 6 files changed, 129 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/luascript.cc b/src/luascript.cc index 1699cdf..fb6a7db 100644 --- a/src/luascript.cc +++ b/src/luascript.cc @@ -27,6 +27,8 @@ */ #include "luascript.h" +#include + // For atoi #include @@ -69,6 +71,12 @@ static int _forward(lua_State *L) return 1; } + if(lua->lua_stop) { + printf("stopping...\n"); + lua_pushstring(L, "stop"); + lua_error(L); + } + lua->out->forward(x * 5); return 0; @@ -93,7 +101,13 @@ static int _turn(lua_State *L) return 1; } - lua->out->turn(-x); + if(lua->lua_stop) { + printf("stopping...\n"); + lua_pushstring(L, "stop"); + lua_error(L); + } + + lua->out->turn(-x * 10); return 0; } @@ -106,7 +120,7 @@ static int _reset(lua_State *L) */ printf("reset\n"); - + lua_getglobal(L, GLOBAL_POINTER); LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); @@ -116,24 +130,31 @@ static int _reset(lua_State *L) return 1; } + if(lua->lua_stop) { + lua_pushstring(L, "stop"); + lua_error(L); + } + lua->out->reset(); return 0; } -LUAScript::LUAScript(OutputWindow *o) +LUAScript::LUAScript(OutputWindow *o, QString f) { DEBUG(luascript, "LUAScript()\n"); + file = f; L = NULL; out = o; + + // Don't call init from here, it need to be done in the thread. + + lua_stop = false; + lua_stopped = true; } LUAScript::~LUAScript() { - if(L) { - free(L); - L = NULL; - } DEBUG(luascript, "~LUAScript()\n"); } @@ -157,58 +178,45 @@ void LUAScript::init() lua_register(L, "fremad", _forward); lua_register(L, "drej", _turn); lua_register(L, "reset", _reset); - - connect(&watcher, SIGNAL(fileChanged(const QString &)), - this, SLOT(reload())); } -void LUAScript::addFile(std::string src) +void LUAScript::cleanup() { - file = src.c_str(); - FILE *fp = fopen(src.c_str(), "r"); - if(fp) { - char buf[64]; - size_t sz; - std::string inc; - while((sz = fread(buf, 1, sizeof(buf), fp)) != 0) { - inc.append(buf, sz); - } - fclose(fp); - addCode(inc, src); + if(L) { + lua_close(L); + L = NULL; } - - watcher.addPath(file); -} - -void LUAScript::reload() -{ - printf("Reload\n"); - // luaL_error(L, "Terminated due to reload."); - // runScript(); -} - -void LUAScript::addCode(std::string c, std::string name) -{ - scripts.push_back(std::make_pair(c, name)); } void LUAScript::run() { - /* - while(true) { - printf("."); fflush(stdout); - } - */ + lua_stopped = false; try { + init(); runScript(); } catch(Exception &e) { printf("LUA Error: %s\n", e.msg.c_str()); } + cleanup(); + lua_stopped = true; + printf("LUA Thread Stopped!\n"); +} + +void LUAScript::stopScript() +{ + lua_stop = true; + while(!lua_stopped) { + wait(25); + qApp->processEvents(); + printf("!\n"); + } } void LUAScript::runScript() throw(Exception) { + lua_stop = false; + try { init(); } catch(Exception &e) { @@ -222,62 +230,16 @@ void LUAScript::runScript() top = lua_gettop(L); - std::vector >::iterator i = - scripts.begin(); - while(i != scripts.end()) { - std::string program = i->first; - std::string codename = name(); - if(i->second != "") codename += ": " + i->second; - - DEBUG(luascript, "Running %s: %s\n", codename.c_str(), program.c_str()); + // DEBUG(luascript, "Running %s\n", file); - if(luaL_loadbuffer(L, program.c_str(), program.size(), codename.c_str())) { - ERR(luascript, "loadbuffer: %s\n", lua_tostring(L, lua_gettop(L))); - throw Exception(lua_tostring(L, lua_gettop(L))); - } - - // Run the loaded code - if(lua_pcall(L, 0, LUA_MULTRET, 0)) { - ERR(luascript, "pcall: %s\n" , lua_tostring(L, lua_gettop(L))); - throw Exception(lua_tostring(L, lua_gettop(L))); - } - - i++; + if(luaL_loadfile(L, file.toStdString().c_str())) { + ERR(luascript, "loadbuffer: %s\n", lua_tostring(L, lua_gettop(L))); + throw Exception(lua_tostring(L, lua_gettop(L))); } -} - -std::string LUAScript::resultString() throw(Exception) -{ - if(top != lua_gettop(L) - 1) { - ERR(luascript, "Program did not return a single value.\n"); - throw Exception("Program did not return a single value."); - } - - if(lua_isstring(L, lua_gettop(L)) == false) { - ERR(luascript, "Program did not return a string value.\n"); - throw Exception("Program did not return a string value."); + + // Run the loaded code + if(lua_pcall(L, 0, LUA_MULTRET, 0)) { + ERR(luascript, "pcall: %s\n" , lua_tostring(L, lua_gettop(L))); + throw Exception(lua_tostring(L, lua_gettop(L))); } - - std::string res = lua_tostring(L, lua_gettop(L)); - lua_pop(L, 1); - - return res; } - -#ifdef TEST_LUASCRIPT -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: -#include "test.h" - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). -TEST_TRUE(false, "No tests yet!"); - -TEST_END; - -#endif/*TEST_LUASCRIPT*/ diff --git a/src/luascript.h b/src/luascript.h index 448fe5e..6516611 100644 --- a/src/luascript.h +++ b/src/luascript.h @@ -34,7 +34,6 @@ #include #include #include -#include #include "outputwindow.h" @@ -49,25 +48,24 @@ public: std::string msg; }; - LUAScript(OutputWindow *out); + LUAScript(OutputWindow *out, QString file); ~LUAScript(); - virtual const char *name() { return ""; } - void init() throw(Exception); - - void addFile(std::string file); - void addCode(std::string code, std::string codename = ""); + void cleanup(); void run(); void runScript() throw(Exception); - std::string resultString() throw(Exception); - OutputWindow *out; -public slots: - void reload(); + void stopScript(); + + volatile bool lua_stop; + volatile bool lua_stopped; + +signals: + void reset(); protected: lua_State *L; @@ -78,8 +76,9 @@ private: int top; - QFileSystemWatcher watcher; QString file; + + bool running; }; diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 784bfbb..c8036ca 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -29,11 +29,31 @@ #include "outputwindow.h" -MainWindow::MainWindow(QString program) +#include + +MainWindow::MainWindow(QString p) { + program = p; + + connect(&watcher, SIGNAL(fileChanged(const QString &)), + this, SLOT(reset())); + + watcher.addPath(program); + out = new OutputWindow(); out->show(); - l = new LUAScript(out); - l->addFile(program.toStdString()); + + l = new LUAScript(out, program); + + reset(); +} + +void MainWindow::reset() +{ + printf("Resetting...\n"); + out->stopScript(); + l->stopScript(); + out->reset(); l->start(); + printf("Reset done\n"); } diff --git a/src/mainwindow.h b/src/mainwindow.h index eeaaa1a..1376a84 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -29,14 +29,23 @@ #define __KAIMAN_MAINWINDOW_H__ #include + +#include + #include "outputwindow.h" #include "luascript.h" class MainWindow : public QWidget { +Q_OBJECT public: MainWindow(QString program); +private slots: + void reset(); + private: + QFileSystemWatcher watcher; + QString program; OutputWindow *out; LUAScript *l; }; diff --git a/src/outputwindow.cc b/src/outputwindow.cc index 0f66a0b..faa4432 100644 --- a/src/outputwindow.cc +++ b/src/outputwindow.cc @@ -32,8 +32,12 @@ #include +#define SCALE 2 + OutputWindow::OutputWindow() { + resize(1000, 1000); + QPixmap img("gfx/kaiman.png"); //QPixmap img("gfx/arrow.png"); kaiman = img.toImage(); @@ -49,6 +53,11 @@ OutputWindow::OutputWindow() reset(); } +void OutputWindow::stopScript() +{ + stop = true; +} + void OutputWindow::timeout() { /* @@ -64,12 +73,15 @@ void OutputWindow::paintEvent(QPaintEvent *) { // sem.acquire(); QPainter p(this); + // QTransform tp; tp.scale(3, 3); p.setTransform(tp); QTransform t; t.rotate(-r + 90); - t.scale(100.0 / kaiman.width(), 100.0 / kaiman.width()); + t.scale((100.0 / kaiman.width()) * SCALE, + (100.0 / kaiman.width()) * SCALE); QImage img = kaiman.transformed(t, Qt::SmoothTransformation); - p.drawImage(x - img.width()/2, y - img.height()/2, img); + p.drawImage((x * SCALE) - img.width()/2 , + (y * SCALE)- img.height()/2, img); QPen pen(QColor(255,0,0,100)); pen.setWidth(4); @@ -82,9 +94,11 @@ void OutputWindow::paintEvent(QPaintEvent *) void OutputWindow::reset() { points.clear(); - x = width() / 2; - y = height() / 2; + x = (width() / 2) / SCALE; + y = (height() / 2) / SCALE; r = 0; + stop = false; + while(sem.tryAcquire()) {} } static inline int sign(int x) @@ -103,10 +117,11 @@ void OutputWindow::forward(int x) float source_y = this->y; for(int i = 0; i < abs(x); i++) { + if(stop) return; float d = (float)i / (float)x * sign(x); this->x = source_x + target_x * d; this->y = source_y + target_y * d; - points.append(QPointF(this->x, this->y)); + points.append(QPointF(this->x * SCALE, this->y * SCALE)); sem.acquire(); } } @@ -114,8 +129,9 @@ void OutputWindow::forward(int x) void OutputWindow::turn(int x) { sem.acquire(); - for(int i = 0; i < abs(x) * 2; i++) { - this->r += sign(x) * 0.5; + for(int i = 0; i < abs(x)/2; i++) { + if(stop) return; + this->r += sign(x)*2; sem.acquire(); } } diff --git a/src/outputwindow.h b/src/outputwindow.h index 88b94c8..5f14099 100644 --- a/src/outputwindow.h +++ b/src/outputwindow.h @@ -40,13 +40,14 @@ Q_OBJECT public: OutputWindow(); - void reset(); - void forward(int x); void turn(int x); + void stopScript(); + public slots: void timeout(); + void reset(); protected: void paintEvent(QPaintEvent * event); @@ -57,6 +58,8 @@ private: QTimer timer; QSemaphore sem; QVector points; + + volatile bool stop; }; #endif/*__KAIMAN_OUTPUTWINDOW_H__*/ -- cgit v1.2.3