/* -*- 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" #include // For atoi #include //#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; } if(lua->lua_stop) { printf("stopping...\n"); lua_pushstring(L, "stop"); lua_error(L); } lua->out->forward(x * 5); return 0; } static int _loadpen(lua_State *L) {/* Pracro::checkParameters(L, Pracro::T_STRING, Pracro::T_END); */ const char *pen = lua_tostring(L, lua_gettop(L)); printf("load pen %s\n", pen); 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; } if(lua->lua_stop) { printf("stopping...\n"); lua_pushstring(L, "stop"); lua_error(L); } lua->out->loadPen(pen); return 0; } static int _speed(lua_State *L) {/* Pracro::checkParameters(L, Pracro::T_STRING, Pracro::T_END); */ int x = lua_tonumber(L, lua_gettop(L)); printf("speed %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; } if(lua->lua_stop) { printf("stopping...\n"); lua_pushstring(L, "stop"); lua_error(L); } lua->out->setSpeed(x); return 0; } static int _scale(lua_State *L) {/* Pracro::checkParameters(L, Pracro::T_STRING, Pracro::T_END); */ double x = lua_tonumber(L, lua_gettop(L)); printf("scale %f\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; } if(lua->lua_stop) { printf("stopping...\n"); lua_pushstring(L, "stop"); lua_error(L); } lua->out->setScale(x); return 0; } static int _colour(lua_State *L) {/* Pracro::checkParameters(L, Pracro::T_STRING, Pracro::T_END); */ int r = luaL_checknumber(L, 1); int g = luaL_checknumber(L, 2); int b = luaL_checknumber(L, 3); int a = luaL_checknumber(L, 4); printf("colour %d %d %d %d\n", r,b,g,a); 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; } if(lua->lua_stop) { printf("stopping...\n"); lua_pushstring(L, "stop"); lua_error(L); } lua->out->setColour(r,g,b,a); 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; } if(lua->lua_stop) { printf("stopping...\n"); lua_pushstring(L, "stop"); lua_error(L); } lua->out->turn(-x * 10); 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; } if(lua->lua_stop) { lua_pushstring(L, "stop"); lua_error(L); } lua->out->reset(); return 0; } 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() { 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, "speed", _speed); lua_register(L, "scale", _scale); lua_register(L, "reset", _reset); lua_register(L, "colour", _colour); lua_register(L, "loadpen", _loadpen); } void LUAScript::cleanup() { if(L) { lua_close(L); L = NULL; } } void LUAScript::run() { 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) { throw Exception(e.msg); } if(L == NULL) { ERR(luascript, "LUA state not initialized!"); return; } top = lua_gettop(L); // DEBUG(luascript, "Running %s\n", file); 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))); } // 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))); } }