diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/clua.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.cc | 32 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.h | 12 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/maps.cc | 46 | ||||
-rw-r--r-- | crawl-ref/source/maps.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/util/levcomp.ypp | 21 |
8 files changed, 116 insertions, 39 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index 63f901f051..8ea71c26e4 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -532,18 +532,22 @@ bool CLua::callfn(const char *fn, int nargs, int nret) lua_State *ls = state(); if (!ls) return (false); - - lua_getglobal(ls, fn); - if (!lua_isfunction(ls, -1)) + + // If a function is not provided on the stack, get the named function. + if (fn) { - lua_settop(ls, -nargs - 2); - return (false); + lua_getglobal(ls, fn); + if (!lua_isfunction(ls, -1)) + { + lua_settop(ls, -nargs - 2); + return (false); + } + + // Slide the function in front of its args and call it. + if (nargs) + lua_insert(ls, -nargs - 1); } - // Slide the function in front of its args and call it. - if (nargs) - lua_insert(ls, -nargs - 1); - lua_call_throttle strangler(this); int err = lua_pcall(ls, nargs, nret, 0); set_error(err, ls); diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index bdc5494275..bce024b312 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -7,6 +7,7 @@ #include "AppHdr.h" #include "clua.h" +#include "files.h" #include "luadgn.h" #include "mapdef.h" @@ -44,6 +45,26 @@ dlua_chunk::dlua_chunk(const std::string &_context) clear(); } +void dlua_chunk::write(FILE *outf) const +{ + writeString(outf, chunk, LUA_CHUNK_MAX_SIZE); + if (!chunk.empty()) + { + writeString(outf, file); + writeLong(outf, first); + } +} + +void dlua_chunk::read(FILE *inf) +{ + chunk = readString(inf, LUA_CHUNK_MAX_SIZE); + if (!chunk.empty()) + { + file = readString(inf); + first = readLong(inf); + } +} + void dlua_chunk::clear() { file.clear(); @@ -82,15 +103,15 @@ int dlua_chunk::check_op(CLua *interp, int err) return (err); } -int dlua_chunk::load(CLua *interp) +int dlua_chunk::load(CLua &interp) { if (trimmed_string(chunk).empty()) return (-1000); - return check_op(interp, - interp->loadstring(chunk.c_str(), context.c_str())); + return check_op(&interp, + interp.loadstring(chunk.c_str(), context.c_str())); } -int dlua_chunk::load_call(CLua *interp, const char *fn) +int dlua_chunk::load_call(CLua &interp, const char *fn) { int err = load(interp); if (err == -1000) @@ -98,11 +119,12 @@ int dlua_chunk::load_call(CLua *interp, const char *fn) if (err) return (err); - return check_op(interp, interp->callfn(fn, 1, 0)); + return check_op(&interp, !interp.callfn(fn, fn? 1 : 0, 0)); } std::string dlua_chunk::orig_error() const { + rewrite_chunk_errors(error); return (error); } diff --git a/crawl-ref/source/luadgn.h b/crawl-ref/source/luadgn.h index f8b272f544..6c619af05e 100644 --- a/crawl-ref/source/luadgn.h +++ b/crawl-ref/source/luadgn.h @@ -13,6 +13,9 @@ extern CLua dlua; +// Lua chunks cannot exceed 512K. Which is plenty! +const int LUA_CHUNK_MAX_SIZE = 512 * 1024; + class dlua_chunk { private: @@ -27,7 +30,7 @@ private: std::string get_chunk_prefix(const std::string &s) const; public: - std::string error; + mutable std::string error; public: dlua_chunk(const std::string &_context = "dlua_chunk"); @@ -35,8 +38,8 @@ public: void add(int line, const std::string &line); void set_chunk(const std::string &s); - int load(CLua *interp); - int load_call(CLua *interp, const char *function); + int load(CLua &interp); + int load_call(CLua &interp, const char *function); void set_file(const std::string &s); const std::string &lua_string() const { return chunk; } @@ -44,6 +47,9 @@ public: bool rewrite_chunk_errors(std::string &err) const; bool empty() const; + + void write(FILE *) const; + void read(FILE *); }; void init_dungeon_lua(); diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 5323c421a0..edae6afa9f 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -849,8 +849,8 @@ void map_def::write_full(FILE *outf) cache_offset = ftell(outf); writeShort(outf, 0x1eaf); // Level indicator. writeString(outf, name); - writeString(outf, prelude.lua_string(), LUA_CHUNK_MAX_SIZE); - writeString(outf, main.lua_string(), LUA_CHUNK_MAX_SIZE); + prelude.write(outf); + main.write(outf); } void map_def::read_full(FILE *inf) @@ -869,8 +869,8 @@ void map_def::read_full(FILE *inf) "Please reload your game.", file.c_str()).c_str()); - prelude.set_chunk(readString(inf, LUA_CHUNK_MAX_SIZE)); - main.set_chunk(readString(inf, LUA_CHUNK_MAX_SIZE)); + prelude.read(inf); + main.read(inf); } void map_def::load() @@ -899,7 +899,7 @@ void map_def::write_index(FILE *outf) const writeString(outf, tags); writeString(outf, place); write_depth_ranges(outf); - writeString(outf, prelude.lua_string(), LUA_CHUNK_MAX_SIZE); + prelude.write(outf); } void map_def::read_index(FILE *inf) @@ -911,7 +911,7 @@ void map_def::read_index(FILE *inf) tags = readString(inf); place = readString(inf); read_depth_ranges(inf); - prelude.set_chunk(readString(inf, LUA_CHUNK_MAX_SIZE)); + prelude.read(inf); index_only = true; } @@ -940,7 +940,7 @@ void map_def::set_file(const std::string &s) std::string map_def::run_lua(bool run_main) { dlua.callfn("dgn_set_map", "m", this); - int err = prelude.load(&dlua); + int err = prelude.load(dlua); if (err == -1000) lua_pushnil(dlua); else if (err) @@ -950,7 +950,7 @@ std::string map_def::run_lua(bool run_main) lua_pushnil(dlua); else { - err = main.load(&dlua); + err = main.load(dlua); if (err == -1000) lua_pushnil(dlua); else if (err) diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index c2ef6e897d..8e1db25209 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -394,9 +394,6 @@ typedef std::map<int, keyed_mapspec> keyed_specs; typedef std::vector<level_range> depth_ranges; -// Lua chunks cannot exceed 512K. Which is plenty! -const int LUA_CHUNK_MAX_SIZE = 512 * 1024; - class map_def { public: diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc index 22e62c9df7..ccff83396e 100644 --- a/crawl-ref/source/maps.cc +++ b/crawl-ref/source/maps.cc @@ -355,11 +355,16 @@ const map_def *map_by_index(int index) ///////////////////////////////////////////////////////////////////////////// // Reading maps from .des files. -dlua_chunk lc_file_prelude; +// All global preludes. +std::vector<dlua_chunk> global_preludes; + +// Map-specific prelude. +dlua_chunk lc_global_prelude("global_prelude"); std::string lc_desfile; map_def lc_map; level_range lc_range; depth_ranges lc_default_depths; +bool lc_run_global_prelude = true; std::set<std::string> map_files_read; @@ -370,16 +375,17 @@ void reset_map_parser() lc_map.init(); lc_range.reset(); lc_default_depths.clear(); - lc_file_prelude.clear(); + lc_global_prelude.clear(); yylineno = 1; + lc_run_global_prelude = true; } //////////////////////////////////////////////////////////////////////////// static bool checked_des_index_dir = false; -#define DESCACHE_VER 1000 +#define DESCACHE_VER 1001 static void check_des_index_dir() { @@ -425,7 +431,19 @@ static bool verify_map_full(const std::string &base) static bool load_map_index(const std::string &base) { - FILE *inf = fopen((base + ".idx").c_str(), "rb"); + // If there's a global prelude, load that first. + FILE *inf = fopen((base + ".lux").c_str(), "rb"); + if (inf) + { + lc_global_prelude.read(inf); + fclose(inf); + + global_preludes.push_back( lc_global_prelude ); + } + + inf = fopen((base + ".idx").c_str(), "rb"); + if (!inf) + end(1, true, "Unable to read %s", (base + ".idx").c_str()); // Discard version (it's been checked by verify_map_index). readLong(inf); const int nmaps = readShort(inf); @@ -460,17 +478,15 @@ static bool load_map_cache(const std::string &filename) static void write_map_prelude(const std::string &filebase) { - const std::string luafile = filebase + ".lua"; - if (lc_file_prelude.empty()) + const std::string luafile = filebase + ".lux"; + if (lc_global_prelude.empty()) { unlink(luafile.c_str()); return; } - FILE *outf = fopen(luafile.c_str(), "w"); - if (!outf) - end(1, true, "Unable to open %s for writing", luafile.c_str()); - fprintf(outf, "%s", lc_file_prelude.lua_string().c_str()); + FILE *outf = fopen(luafile.c_str(), "wb"); + lc_global_prelude.write(outf); fclose(outf); } @@ -539,6 +555,7 @@ static void parse_maps(const std::string &s) yyparse(); fclose(dat); + global_preludes.push_back( lc_global_prelude ); write_map_cache(s, file_start, vdefs.size()); } @@ -572,6 +589,15 @@ void add_parsed_map( const map_def &md ) void run_map_preludes() { + for (int i = 0, size = global_preludes.size(); i < size; ++i) + { + dlua_chunk &chunk = global_preludes[i]; + if (!chunk.empty()) + { + if (chunk.load_call(dlua, NULL)) + mprf(MSGCH_WARN, "Lua error: %s", chunk.orig_error().c_str()); + } + } for (int i = 0, size = vdefs.size(); i < size; ++i) { if (!vdefs[i].prelude.empty()) diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h index 8274a957e9..91de437ffe 100644 --- a/crawl-ref/source/maps.h +++ b/crawl-ref/source/maps.h @@ -52,10 +52,11 @@ void reset_map_parser(); std::string get_descache_path(const std::string &file, const std::string &ext); -extern dlua_chunk map_file_prelude; extern std::string lc_desfile; extern map_def lc_map; extern level_range lc_range; extern depth_ranges lc_default_depths; +extern dlua_chunk lc_global_prelude; +extern bool lc_run_global_prelude; #endif diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp index fb82c36e00..0a3cb8ada1 100644 --- a/crawl-ref/source/util/levcomp.ypp +++ b/crawl-ref/source/util/levcomp.ypp @@ -89,6 +89,7 @@ definition : def {} ; def : defdepth {} + | global_lua {} ; defdepth : DEFAULT_DEPTH STRING @@ -104,6 +105,15 @@ defdepth : DEFAULT_DEPTH STRING level : name map_specs { lc_map.set_file(lc_desfile); + + if (lc_run_global_prelude && !lc_global_prelude.empty()) + { + lc_global_prelude.set_file(lc_desfile); + lc_run_global_prelude = false; + if (lc_global_prelude.load_call(dlua, NULL)) + yyerror( lc_global_prelude.orig_error().c_str() ); + } + std::string err = lc_map.validate(); if (!err.empty()) yyerror(err.c_str()); @@ -164,6 +174,17 @@ metaline : place | prelude_lua ; +global_lua : MAIN global_lua_lines { } + +global_lua_lines : /* empty */ { } + | global_lua_lines global_lua_line { } + ; + +global_lua_line : LUA_LINE + { + lc_global_prelude.add(yylineno, $1); + } + main_lua : MAIN main_lua_lines { } main_lua_lines : /* empty */ { } |