diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2012-08-04 20:41:18 +0200 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2012-08-04 20:41:18 +0200 |
commit | b8195d45820378e3d09225d9a291c4951816276d (patch) | |
tree | 87a2e2f1b9a0ed93672d2e5e98214d0d2d05f4e2 /src/luascript.cc |
Initial import.
Diffstat (limited to 'src/luascript.cc')
-rw-r--r-- | src/luascript.cc | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/src/luascript.cc b/src/luascript.cc new file mode 100644 index 0000000..1699cdf --- /dev/null +++ b/src/luascript.cc @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * luascript.cc + * + * Tue Jan 10 14:43:39 CET 2012 + * Copyright 2012 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "luascript.h" + +// For atoi +#include <stdlib.h> + +//#include "luautil.h" + +#define GLOBAL_POINTER "_pracroGlobalLUAObjectPointerThisShouldBeANameThatIsNotAccidentallyOverwritten" + +#define DEBUG(x, fmt...) printf(fmt) +#define ERR(x, fmt...) printf(fmt) + +static int _debug(lua_State *L) +{/* + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + */ + std::string msg = lua_tostring(L, lua_gettop(L)); + + printf("%s\n", msg.c_str()); + + return 0; +} + +static int _forward(lua_State *L) +{/* + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + */ + int x = lua_tonumber(L, lua_gettop(L)); + + printf("forward %d\n", x); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua->out->forward(x * 5); + + return 0; +} + +static int _turn(lua_State *L) +{/* + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + */ + int x = lua_tonumber(L, lua_gettop(L)); + + printf("turn %d\n", x); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua->out->turn(-x); + + return 0; +} + +static int _reset(lua_State *L) +{/* + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + */ + + printf("reset\n"); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua->out->reset(); + + return 0; +} + +LUAScript::LUAScript(OutputWindow *o) +{ + DEBUG(luascript, "LUAScript()\n"); + L = NULL; + out = o; +} + +LUAScript::~LUAScript() +{ + if(L) { + free(L); + L = NULL; + } + DEBUG(luascript, "~LUAScript()\n"); +} + +void LUAScript::init() + throw(Exception) +{ + if(L) return; + + L = luaL_newstate(); + if(L == NULL) { + ERR(luascript, "Could not create LUA state.\n"); + throw Exception("Could not create LUA state."); + } + + luaL_openlibs(L); + + lua_pushlightuserdata(L, this); // Push the pointer to 'this' instance + lua_setglobal(L, GLOBAL_POINTER); // Assign it to a global lua var. + + lua_register(L, "debug", _debug); + 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) +{ + 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); + } + + 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); + } + */ + try { + runScript(); + } catch(Exception &e) { + printf("LUA Error: %s\n", e.msg.c_str()); + } +} + +void LUAScript::runScript() + throw(Exception) +{ + try { + init(); + } catch(Exception &e) { + throw Exception(e.msg); + } + + if(L == NULL) { + ERR(luascript, "LUA state not initialized!"); + return; + } + + top = lua_gettop(L); + + std::vector<std::pair<std::string, std::string> >::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()); + + 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++; + } +} + +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."); + } + + 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*/ |