summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dlua.h
blob: ebb90398f8d6612923ba2e7eaa7d6eccddb16b2a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 *  File:       dlua.h
 *  Summary:    Dungeon-builder Lua interface.
 *  Created by: dshaligram on Sat Jun 23 20:02:09 2007 UTC
 */

#ifndef LUADGN_H
#define LUADGN_H

#include "clua.h"
#include "stuff.h" // for COORDS macro

// Defined in acr.cc
extern CLua dlua;

// Lua chunks cannot exceed 512K. Which is plenty!
const int LUA_CHUNK_MAX_SIZE = 512 * 1024;

class reader;
class writer;

class dlua_chunk
{
private:
    std::string file;
    std::string chunk;
    std::string compiled;
    std::string context;
    int first, last;     // First and last lines of the original source.

    enum chunk_t
    {
        CT_EMPTY,
        CT_SOURCE,
        CT_COMPILED
    };

private:
    int check_op(CLua &, int);
    std::string rewrite_chunk_prefix(const std::string &line,
                                     bool skip_body = false) const;
    std::string get_chunk_prefix(const std::string &s) const;

public:
    mutable std::string error;

public:
    dlua_chunk(const std::string &_context = "dlua_chunk");
    dlua_chunk(lua_State *ls);

    static dlua_chunk precompiled(const std::string &compiled);

    void clear();
    void add(int line, const std::string &line2);
    void set_chunk(const std::string &s);

    int load(CLua &interp);
    int run(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; }
    std::string orig_error() const;
    bool rewrite_chunk_errors(std::string &err) const;

    bool empty() const;

    const std::string &compiled_chunk() const { return compiled; }

    void write(writer&) const;
    void read(reader&);
};

void init_dungeon_lua();
std::string dgn_set_default_depth(const std::string &s);
void dgn_reset_default_depth();
int dlua_stringtable(lua_State *ls, const std::vector<std::string> &s);

dungeon_feature_type dungeon_feature_by_name(const std::string &name);
std::vector<std::string> dungeon_feature_matches(const std::string &name);
const char *dungeon_feature_name(dungeon_feature_type feat);

template <typename T>
inline void dlua_push_userdata(lua_State *ls, T udata, const char *meta)
{
    T *de = clua_new_userdata<T>(ls, meta);
    *de = udata;
}

template <class T>
static void dlua_push_object_type(lua_State *ls, const char *meta, const T &data)
{
    T **ptr = clua_new_userdata<T*>(ls, meta);
    *ptr = new T(data);
}

void print_dlua_stack();


void luaopen_setmeta(lua_State *ls,
                     const char *global,
                     const luaL_reg *lua_lib,
                     const char *meta);

#define LUAFN(name) static int name(lua_State *ls)

#define GETCOORD(c, p1, p2, boundfn)                      \
    coord_def c;                                          \
    c.x = luaL_checkint(ls, p1);                          \
    c.y = luaL_checkint(ls, p2);                          \
    if (!boundfn(c))                                        \
        luaL_error(                                             \
            ls,                                                 \
            make_stringf("Point (%d,%d) is out of bounds",      \
                         c.x, c.y).c_str());                    \
    else ;


#define COORDS(c, p1, p2)                                \
    GETCOORD(c, p1, p2, in_bounds)

#define MAP(ls, n, var)                             \
map_def *var = *(map_def **) luaL_checkudata(ls, n, MAP_METATABLE)
#define DEVENT(ls, n, var) \
dgn_event *var = *(dgn_event **) luaL_checkudata(ls, n, DEVENT_METATABLE)
#define MAPMARKER(ls, n, var) \
map_marker *var = *(map_marker **) luaL_checkudata(ls, n, MAPMARK_METATABLE)

//////////////////////////////////////////////////////////////////////////

#endif