diff options
-rw-r--r-- | crawl-ref/source/clua.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/clua.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 33 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.h | 24 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/util/levcomp.lpp | 17 | ||||
-rw-r--r-- | crawl-ref/source/util/levcomp.ypp | 50 |
9 files changed, 127 insertions, 52 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index 9fa1a79a9a..7fb7a310a7 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -131,10 +131,15 @@ void CLua::setregistry(const char *name) lua_settable(state(), LUA_REGISTRYINDEX); } +void CLua::_getregistry(lua_State *ls, const char *name) +{ + lua_pushstring(ls, name); + lua_gettable(ls, LUA_REGISTRYINDEX); +} + void CLua::getregistry(const char *name) { - lua_pushstring(state(), name); - lua_gettable(state(), LUA_REGISTRYINDEX); + _getregistry(state(), name); } void CLua::save(const char *file) @@ -639,6 +644,18 @@ void CLua::init_lua() lua_pushboolean(_state, managed_vm); setregistry("lua_vm_is_managed"); + + lua_pushlightuserdata(_state, this); + setregistry("__clua"); +} + +CLua &CLua::get_vm(lua_State *ls) +{ + _getregistry(ls, "__clua"); + CLua *vm = util_get_userdata<CLua>(ls, -1); + if (!vm) + end(1, false, "Failed to find CLua for lua state %p", ls); + return (*vm); } bool CLua::is_managed_vm(lua_State *ls) diff --git a/crawl-ref/source/clua.h b/crawl-ref/source/clua.h index ae465aa3a0..e6ae4ecde7 100644 --- a/crawl-ref/source/clua.h +++ b/crawl-ref/source/clua.h @@ -93,6 +93,8 @@ public: CLua(bool managed = true); ~CLua(); + static CLua &get_vm(lua_State *); + lua_State *state(); operator lua_State * () @@ -170,6 +172,8 @@ private: void load_chooks(); void init_throttle(); + static void _getregistry(lua_State *, const char *name); + void vfnreturns(const char *par, va_list va); bool proc_returns(const char *par) const; diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index 8ad3fc37ac..ca773b84d8 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -764,6 +764,23 @@ static int dgn_item(lua_State *ls) return (0); } +static int dgn_lua_marker(lua_State *ls) +{ + MAP(ls, 1, map); + if (lua_gettop(ls) != 3 || !lua_isstring(ls, 2) || !lua_isfunction(ls, 3)) + luaL_error(ls, "Expected marker key and marker function."); + + CLua &lvm(CLua::get_vm(ls)); + std::string key = lua_tostring(ls, 2); + lua_datum function(lvm, 3, false); + + const std::string err = map->map.add_lua_marker(key, function); + if (!err.empty()) + luaL_error(ls, err.c_str()); + + return (0); +} + static int dgn_marker(lua_State *ls) { MAP(ls, 1, map); @@ -2106,6 +2123,7 @@ static const struct luaL_reg dgn_lib[] = { "mons", dgn_mons }, { "item", dgn_item }, { "marker", dgn_marker }, + { "lua_marker", dgn_lua_marker }, { "kfeat", dgn_kfeat }, { "kitem", dgn_kitem }, { "kmons", dgn_kmons }, diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 0f9cb1f838..3eaea9b11f 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -63,11 +63,11 @@ static int find_weight(std::string &s, int defweight = TAG_UNFOUND) return (weight == TAG_UNFOUND? defweight : weight); } -static std::string split_key_item(const std::string &s, +std::string mapdef_split_key_item(const std::string &s, std::string *key, int *separator, std::string *arg, - int key_max_len = 1) + int key_max_len) { std::string::size_type norm = s.find("=", 1), @@ -383,7 +383,7 @@ std::string map_lines::add_feature_marker(const std::string &s) { std::string key, arg; int sep = 0; - std::string err = split_key_item(s, &key, &sep, &arg); + std::string err = mapdef_split_key_item(s, &key, &sep, &arg); if (!err.empty()) return (err); @@ -391,6 +391,13 @@ std::string map_lines::add_feature_marker(const std::string &s) return (""); } +std::string map_lines::add_lua_marker(const std::string &key, + const lua_datum &function) +{ + transforms.push_back(new map_marker_spec(key[0], function)); + return (""); +} + void map_lines::apply_markers(const coord_def &c) { for (int i = 0, size = markers.size(); i < size; ++i) @@ -546,7 +553,7 @@ std::string map_lines::add_colour(const std::string &sub) std::string key; std::string substitute; - std::string err = split_key_item(sub, &key, &sep, &substitute); + std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute); if (!err.empty()) return (err); @@ -570,7 +577,7 @@ std::string map_lines::add_subst(const std::string &sub) std::string key; std::string substitute; - std::string err = split_key_item(sub, &key, &sep, &substitute); + std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute); if (!err.empty()) return (err); @@ -589,7 +596,7 @@ std::string map_lines::parse_nsubst_spec(const std::string &s, { std::string key, arg; int sep; - std::string err = split_key_item(s, &key, &sep, &arg); + std::string err = mapdef_split_key_item(s, &key, &sep, &arg); if (!err.empty()) return err; const int keyval = key == "*"? -1 : atoi(key.c_str()); @@ -612,7 +619,7 @@ std::string map_lines::add_nsubst(const std::string &s) int sep; std::string key, arg; - std::string err = split_key_item(s, &key, &sep, &arg); + std::string err = mapdef_split_key_item(s, &key, &sep, &arg); if (!err.empty()) return (err); @@ -1769,7 +1776,7 @@ std::string map_def::add_key_field( int separator = 0; std::string key, arg; - std::string err = split_key_item(s, &key, &separator, &arg); + std::string err = mapdef_split_key_item(s, &key, &separator, &arg); if (!err.empty()) return (err); @@ -2810,8 +2817,7 @@ std::string map_marker_spec::apply_transform(map_lines &map) { try { - map_marker *mark = - map_marker::parse_marker(marker); + map_marker *mark = create_marker(); if (!mark) return make_stringf("Unable to parse marker from %s", marker.c_str()); @@ -2826,6 +2832,13 @@ std::string map_marker_spec::apply_transform(map_lines &map) return (""); } +map_marker *map_marker_spec::create_marker() +{ + return lua_fn.get() + ? new map_lua_marker(*lua_fn.get()) + : map_marker::parse_marker(marker); +} + map_transformer::transform_type map_marker_spec::type() const { return (TT_MARKER); diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index 775f2e82b2..83098d2b5a 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -15,6 +15,7 @@ #include <string> #include <vector> #include <cstdio> +#include <memory> #include "luadgn.h" #include "enum.h" @@ -202,15 +203,25 @@ class shuffle_spec : public map_transformer class map_marker_spec : public map_transformer { - public: +public: int key; std::string marker; + // Special handling for Lua markers: + std::auto_ptr<lua_datum> lua_fn; + map_marker_spec(int _key, const std::string &mark) - : key(_key), marker(mark) { } + : key(_key), marker(mark), lua_fn() { } + + map_marker_spec(int _key, const lua_datum &fn) + : key(_key), marker(), lua_fn(new lua_datum(fn)) { } + std::string apply_transform(map_lines &map); transform_type type() const; std::string describe() const; + +private: + map_marker *create_marker(); }; class map_def; @@ -266,6 +277,8 @@ public: void add_marker(map_marker *marker); std::string add_feature_marker(const std::string &desc); + std::string add_lua_marker(const std::string &key, + const lua_datum &fn); void apply_markers(const coord_def &pos); void apply_colours(const coord_def &pos); @@ -742,6 +755,13 @@ private: std::string escape_string(std::string in, const std::string &toesc, const std::string &escapewith); + +std::string mapdef_split_key_item(const std::string &s, + std::string *key, + int *separator, + std::string *arg, + int key_max_len = 1); + const char *map_section_name(int msect); #endif diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc index 7fadb6330e..ecbed091e3 100644 --- a/crawl-ref/source/mapmark.cc +++ b/crawl-ref/source/mapmark.cc @@ -165,6 +165,17 @@ map_lua_marker::map_lua_marker() { } +map_lua_marker::map_lua_marker(const lua_datum &fn) + : map_marker(MAT_LUA_MARKER, coord_def()) +{ + lua_stack_cleaner clean(dlua); + fn.push(); + if (!dlua.callfn("dgn_run_map", 1, 1)) + mprf(MSGCH_ERROR, "lua_marker exec error: %s", dlua.error.c_str()); + else + check_register_table(); +} + map_lua_marker::map_lua_marker(const std::string &s, const std::string &, bool mapdef_marker) : map_marker(MAT_LUA_MARKER, coord_def()), initialised(false) diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h index 07d89331be..eb7eb22ba4 100644 --- a/crawl-ref/source/mapmark.h +++ b/crawl-ref/source/mapmark.h @@ -98,6 +98,7 @@ class map_lua_marker : public map_marker, public dgn_event_listener { public: map_lua_marker(); + map_lua_marker(const lua_datum &function); map_lua_marker(const std::string &s, const std::string &ctx, bool mapdef_marker = true); ~map_lua_marker(); diff --git a/crawl-ref/source/util/levcomp.lpp b/crawl-ref/source/util/levcomp.lpp index 42297b5016..590cd59122 100644 --- a/crawl-ref/source/util/levcomp.lpp +++ b/crawl-ref/source/util/levcomp.lpp @@ -122,7 +122,6 @@ static void cattext(bool trim_right = false, int strip_trailing = 0) %s MNAME %s KEYWORDS %x ITEM_LIST -%x TOEOL %option yylineno %option never-interactive @@ -213,19 +212,9 @@ SPACE [\ \t\r] cattext(); } -<ARGUMENT>{SPACE}*$ { BEGIN(INITIAL); str_check(); return STRING; } - -<TOEOL>.*\\[ \t\r]*$ { - settext(true, 1); - return STRING; - } +<ARGUMENT>{NSPACE} cattext(); -<TOEOL>.+$ { - BEGIN(INITIAL); - settext(true); - return STRING; - } -<TOEOL>\r?\n ; +<ARGUMENT>{SPACE}*$ { BEGIN(INITIAL); str_check(); return STRING; } ^[ \t]*#.* ; @@ -259,7 +248,7 @@ FLOORCOL: { CBEGIN(ARGUMENT); return FLOORCOL; } ROCKCOL: { CBEGIN(ARGUMENT); return ROCKCOL; } MONS: { CBEGIN(MNAME); return MONS; } ITEM: { CBEGIN(ITEM_LIST); return ITEM; } -MARKER: { CBEGIN(TOEOL); return MARKER; } +MARKER: { CBEGIN(ARGUMENT); return MARKER; } SHUFFLE: { CBEGIN(ITEM_LIST); return SHUFFLE; } KFEAT: { CBEGIN(ARGUMENT); return KFEAT; } diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp index fc75c4a53b..f2bb2b17b6 100644 --- a/crawl-ref/source/util/levcomp.ypp +++ b/crawl-ref/source/util/levcomp.ypp @@ -17,8 +17,6 @@ int yylex(); extern int yylineno; -static bool start_marker_segment = false; - void yyerror(const char *e) { if (strstr(e, lc_desfile.c_str()) == e) @@ -319,32 +317,36 @@ bflags : BFLAGS STRING } ; -marker : MARKER - { - lc_map.main.add(yylineno, "marker("); - start_marker_segment = true; - } - marker_spec +marker : MARKER STRING { - lc_map.main.add(yylineno, ")"); - } - ; + std::string key, arg; + int sep(0); -marker_spec : mspec_segments + const std::string err = + mapdef_split_key_item($2, &key, &sep, &arg); -mspec_segments : /* nothing */ - | mspec_segments mspec_segment - ; + if (!err.empty()) + yyerror(err.c_str()); -mspec_segment : STRING - { - lc_map.main.add( - yylineno, - make_stringf( - "%s\"%s\"", - start_marker_segment? "" : " .. ", - quote_lua_string($1).c_str())); - start_marker_segment = false; + // Special treatment for Lua markers. + if (arg.find("lua:") == 0) + { + arg = arg.substr(4); + lc_map.main.add( + yylineno, + make_stringf("lua_marker(\"%s\", function () " + " return %s " + "end)", + quote_lua_string(key).c_str(), + arg.c_str())); + } + else + { + lc_map.main.add( + yylineno, + make_stringf("marker(\"%s\")", + quote_lua_string($2).c_str())); + } } ; |