From 2587cc935892613cdda261252d859ac8d5be2218 Mon Sep 17 00:00:00 2001 From: Paul Merrill Date: Thu, 4 Aug 2011 20:25:03 -0700 Subject: [PATCH] scripts load from world --- src/{ => babysfirst}/postMove.lua | 3 +-- src/entity.cpp | 2 +- src/resourcer.cpp | 33 +++++++++++++++++++++++++++++++++ src/resourcer.h | 4 ++++ src/script.cpp | 30 ++++++++++++++---------------- src/script.h | 3 ++- 6 files changed, 55 insertions(+), 20 deletions(-) rename src/{ => babysfirst}/postMove.lua (96%) diff --git a/src/postMove.lua b/src/babysfirst/postMove.lua similarity index 96% rename from src/postMove.lua rename to src/babysfirst/postMove.lua index 1961786..518659a 100644 --- a/src/postMove.lua +++ b/src/babysfirst/postMove.lua @@ -1,4 +1,3 @@ -#!/usr/bin/lua -- -- This script is executed every time an Entity finishes walking onto a tile. -- @@ -32,7 +31,7 @@ local redPortalLocations = { -- The red portals teleport us! *gasp* Excitement! if onAny(redPortalLocations) then - print("Teleported!") + print("Lua says: Teleported!") entity:gotoRandomTile() end diff --git a/src/entity.cpp b/src/entity.cpp index 3f8a3ee..a4056b5 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -303,7 +303,7 @@ void Entity::postMoveHook() script.bindObjFn("entity", "gotoRandomTile", lua_Entity_gotoRandomTile); script.bindInt("x", tile.x); script.bindInt("y", tile.y); - script.run("postMove.lua"); + script.run(rc, "postMove.lua"); } /** diff --git a/src/resourcer.cpp b/src/resourcer.cpp index 0e00e6f..7a25ebb 100644 --- a/src/resourcer.cpp +++ b/src/resourcer.cpp @@ -228,6 +228,39 @@ XMLDocRef Resourcer::getXMLDoc(const std::string& name, return result; } +static void parseError(const std::string& name, lua_State* L) +{ + const char* err = lua_tostring(L, -1); + const char* afterFile = strchr(err, ':') + 1; // +1 for ':' + const char* afterLine = strchr(afterFile, ':') + 2; // +2 for ': ' + char line[512]; + memcpy(line, afterFile, afterLine - afterFile - 2); + Log::err(name + ":" + line, std::string("parsing error: ") + afterLine); +} + +bool Resourcer::getLuaScript(const std::string& name, lua_State* L) +{ + const std::string script = readStringFromDisk(name); + if (script.empty()) // error logged + return false; + + int status = luaL_loadbuffer(L, script.data(), script.size(), + name.c_str()); + + + switch (status) { + case LUA_ERRSYNTAX: + parseError(name, L); + return false; + case LUA_ERRMEM: + // Should we even bother with this? + Log::err(name, "out of memory while parsing"); + return false; + } + + return true; +} + // use RAII to ensure doc is freed // boost::shared_ptr alwaysFreeTheDoc(doc, xmlFreeDoc); xmlDoc* Resourcer::readXMLDocFromDisk(const std::string& name, diff --git a/src/resourcer.h b/src/resourcer.h index b997bca..5e1c710 100644 --- a/src/resourcer.h +++ b/src/resourcer.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "common.h" @@ -64,6 +65,9 @@ public: XMLDocRef getXMLDoc(const std::string& name, const std::string& dtdFile); + //! Requests a Lua script from cache. Lua state L will parse the script. + bool getLuaScript(const std::string& name, lua_State* L); + private: template struct CachedItem diff --git a/src/script.cpp b/src/script.cpp index 8d9cbbc..c92ce12 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -6,6 +6,7 @@ #include "common.h" #include "log.h" +#include "resourcer.h" #include "script.h" enum ObjType { @@ -97,29 +98,26 @@ Entity* Script::getEntity(int pos) return obj->entity; } -void Script::run(const char* fn) +void Script::run(Resourcer* rc, const char* fn) { - if (luaL_loadfile(L, fn)) { - Log::err("Script::run", std::string("couldn't load file: ") + - lua_tostring(L, -1)); + if (!rc->getLuaScript(fn, L)) // error logged return; - } // TODO: make fourth parameter to lua_call an error handler so we can // gather stack trace through Lua state... we can't do it after the // call switch (lua_pcall(L, 0, 0, 0)) { - case LUA_ERRRUN: - Log::err("Script::run", lua_tostring(L, -1)); - break; - case LUA_ERRMEM: - // Should we even bother with this? - Log::err("Script::run", "Lua: out of memory"); - break; - case LUA_ERRERR: - Log::err("Script::run", "error in Lua error facility" - "... what did you do!?"); - break; + case LUA_ERRRUN: + Log::err("Script::run", lua_tostring(L, -1)); + break; + case LUA_ERRMEM: + // Should we even bother with this? + Log::err("Script::run", "Lua: out of memory"); + break; + case LUA_ERRERR: + Log::err("Script::run", "error in Lua error facility" + "... what did you do!?"); + break; } } diff --git a/src/script.h b/src/script.h index 295b0f9..2054e16 100644 --- a/src/script.h +++ b/src/script.h @@ -12,6 +12,7 @@ #include class Entity; +class Resourcer; //! Compile and execute Lua code at runtime. /*! @@ -62,7 +63,7 @@ public: //! Compile and run a script, keeping all existing bindings intact. - void run(const char* fn); + void run(Resourcer* rc, const char* fn); private: //! Did we create our state, or are we borrowing it from another Script -- 2.11.4.GIT