aboutsummaryrefslogtreecommitdiff
path: root/lib/lua/src/lauxlib.h
blob: 34258235dbebff581b08a09d3acff87204cd5406 (plain)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#ifndef lauxlib_h
#define lauxlib_h


#include <stddef.h>
#include <stdio.h>

#include "lua.h"


#if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
#else
#define luaL_getn(L,i)          ((int)lua_objlen(L, i))
#define luaL_setn(L,i,j)        ((void)0)  /* no op! */
#endif

#if defined(LUA_COMPAT_OPENLIB)
#define luaI_openlib	luaL_openlib
#endif


/* extra error code for `luaL_load' */
#define LUA_ERRFILE     (LUA_ERRERR+1)


typedef struct luaL_Reg {
  const char *name;
  lua_CFunction func;
} luaL_Reg;



LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
                                const luaL_Reg *l, int nup);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
                                const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
                                                          size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
                                          const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);

LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
                                          lua_Integer def);

LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);

LUALIB_API int   (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);

LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);

LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
                                   const char *const lst[]);

LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);

LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
                                  const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);

LUALIB_API lua_State *(luaL_newstate) (void);


LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
                                                  const char *r);

LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
                                         const char *fname, int szhint);




/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#define luaL_argcheck(L, cond,numarg,extramsg)	\
		((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n)	(luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d)	(luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n)	((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d)	((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n)	((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d)	((long)luaL_optinteger(L, (n), (d)))

#define luaL_typename(L,i)	lua_typename(L, lua_type(L,(i)))

#define luaL_dofile(L, fn) \
	(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))

#define luaL_dostring(L, s) \
	(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))

#define luaL_getmetatable(L,n)	(lua_getfield(L, LUA_REGISTRYINDEX, (n)))

#define luaL_opt(L,f,n,d)	(lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))

/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/



typedef struct luaL_Buffer {
  char *p;			/* current position in buffer */
  int lvl;  /* number of strings in the stack (level) */
  lua_State *L;
  char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;

#define luaL_addchar(B,c) \
  ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
   (*(B)->p++ = (char)(c)))

/* compatibility only */
#define luaL_putchar(B,c)	luaL_addchar(B,c)

#define luaL_addsize(B,n)	((B)->p += (n))

LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);


/* }====================================================== */


/* compatibility with ref system */

/* pre-defined references */
#define LUA_NOREF       (-2)
#define LUA_REFNIL      (-1)

#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
      (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))

#define lua_unref(L,ref)        luaL_unref(L, LUA_REGISTRYINDEX, (ref))

#define lua_getref(L,ref)       lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))


#define luaL_reg	luaL_Reg

#endif


pc"> #include "mapgen_v7.h" #include "mapgen_singlenode.h" class EmergeThread : public JThread { public: Server *m_server; ServerMap *map; EmergeManager *emerge; Mapgen *mapgen; bool enable_mapgen_debug_info; int id; Event qevent; std::queue<v3s16> blockqueue; EmergeThread(Server *server, int ethreadid): JThread(), m_server(server), map(NULL), emerge(NULL), mapgen(NULL), enable_mapgen_debug_info(false), id(ethreadid) { } void *Thread(); bool popBlockEmerge(v3s16 *pos, u8 *flags); bool getBlockOrStartGen(v3s16 p, MapBlock **b, BlockMakeData *data, bool allow_generate); }; /////////////////////////////// Emerge Manager //////////////////////////////// EmergeManager::EmergeManager(IGameDef *gamedef) { //register built-in mapgens registerMapgen("v5", new MapgenFactoryV5()); registerMapgen("v6", new MapgenFactoryV6()); registerMapgen("v7", new MapgenFactoryV7()); registerMapgen("singlenode", new MapgenFactorySinglenode()); this->ndef = gamedef->getNodeDefManager(); this->biomemgr = new BiomeManager(gamedef); this->oremgr = new OreManager(gamedef); this->decomgr = new DecorationManager(gamedef); this->schemmgr = new SchematicManager(gamedef); this->gen_notify_on = 0; // Note that accesses to this variable are not synchronized. // This is because the *only* thread ever starting or stopping // EmergeThreads should be the ServerThread. this->threads_active = false; mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); // if unspecified, leave a proc for the main thread and one for // some other misc thread s16 nthreads = 0; if (!g_settings->getS16NoEx("num_emerge_threads", nthreads)) nthreads = porting::getNumberOfProcessors() - 2; if (nthreads < 1) nthreads = 1; qlimit_total = g_settings->getU16("emergequeue_limit_total"); if (!g_settings->getU16NoEx("emergequeue_limit_diskonly", qlimit_diskonly)) qlimit_diskonly = nthreads * 5 + 1; if (!g_settings->getU16NoEx("emergequeue_limit_generate", qlimit_generate)) qlimit_generate = nthreads + 1; // don't trust user input for something very important like this if (qlimit_total < 1) qlimit_total = 1; if (qlimit_diskonly < 1) qlimit_diskonly = 1; if (qlimit_generate < 1) qlimit_generate = 1; for (s16 i = 0; i < nthreads; i++) emergethread.push_back(new EmergeThread((Server *) gamedef, i)); infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } EmergeManager::~EmergeManager() { for (unsigned int i = 0; i != emergethread.size(); i++) { if (threads_active) { emergethread[i]->Stop(); emergethread[i]->qevent.signal(); emergethread[i]->Wait(); } delete emergethread[i]; delete mapgen[i]; } emergethread.clear(); mapgen.clear(); std::map<std::string, MapgenFactory *>::iterator it; for (it = mglist.begin(); it != mglist.end(); ++it) delete it->second; mglist.clear(); delete biomemgr; delete oremgr; delete decomgr; delete schemmgr; if (params.sparams) { delete params.sparams; params.sparams = NULL; } } void EmergeManager::loadMapgenParams() { loadParamsFromSettings(g_settings); if (g_settings->get("fixed_map_seed").empty()) { params.seed = (((u64)(myrand() & 0xffff) << 0) | ((u64)(myrand() & 0xffff) << 16) | ((u64)(myrand() & 0xffff) << 32) | ((u64)(myrand() & 0xffff) << 48)); } } void EmergeManager::initMapgens() { if (mapgen.size()) return; if (!params.sparams) { params.sparams = createMapgenParams(params.mg_name); if (!params.sparams) { params.mg_name = DEFAULT_MAPGEN; params.sparams = createMapgenParams(params.mg_name); assert(params.sparams); } params.sparams->readParams(g_settings); } // Create the mapgens for (size_t i = 0; i != emergethread.size(); i++) { Mapgen *mg = createMapgen(params.mg_name, i, &params); assert(mg); mapgen.push_back(mg); } } Mapgen *EmergeManager::getCurrentMapgen() { for (unsigned int i = 0; i != emergethread.size(); i++) { if (emergethread[i]->IsSameThread()) return emergethread[i]->mapgen; } return NULL; } void EmergeManager::startThreads() { if (threads_active) return; for (unsigned int i = 0; i != emergethread.size(); i++) emergethread[i]->Start(); threads_active = true; } void EmergeManager::stopThreads() { if (!threads_active) return; // Request thread stop in parallel for (unsigned int i = 0; i != emergethread.size(); i++) { emergethread[i]->Stop(); emergethread[i]->qevent.signal(); } // Then do the waiting for each for (unsigned int i = 0; i != emergethread.size(); i++) emergethread[i]->Wait(); threads_active = false; } bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { std::map<v3s16, BlockEmergeData *>::const_iterator iter; BlockEmergeData *bedata; u16 count; u8 flags = 0; int idx = 0; if (allow_generate) flags |= BLOCK_EMERGE_ALLOWGEN; { JMutexAutoLock queuelock(queuemutex); count = blocks_enqueued.size(); if (count >= qlimit_total) return false; count = peer_queue_count[peer_id]; u16 qlimit_peer = allow_generate ? qlimit_generate : qlimit_diskonly; if (count >= qlimit_peer) return false; iter = blocks_enqueued.find(p); if (iter != blocks_enqueued.end()) { bedata = iter->second; bedata->flags |= flags; return true; } bedata = new BlockEmergeData; bedata->flags = flags; bedata->peer_requested = peer_id; blocks_enqueued.insert(std::make_pair(p, bedata)); peer_queue_count[peer_id] = count + 1; // insert into the EmergeThread queue with the least items int lowestitems = emergethread[0]->blockqueue.size(); for (unsigned int i = 1; i != emergethread.size(); i++) { int nitems = emergethread[i]->blockqueue.size(); if (nitems < lowestitems) { idx = i; lowestitems = nitems; } } emergethread[idx]->blockqueue.push(p); } emergethread[idx]->qevent.signal(); return true; } int EmergeManager::getGroundLevelAtPoint(v2s16 p) { if (mapgen.size() == 0 || !mapgen[0]) { errorstream << "EmergeManager: getGroundLevelAtPoint() called" " before mapgen initialized" << std::endl; return 0; } return mapgen[0]->getGroundLevelAtPoint(p); } bool EmergeManager::isBlockUnderground(v3s16 blockpos) { /* v2s16 p = v2s16((blockpos.X * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2, (blockpos.Y * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2); int ground_level = getGroundLevelAtPoint(p); return blockpos.Y * (MAP_BLOCKSIZE + 1) <= min(water_level, ground_level); */ //yuck, but then again, should i bother being accurate? //the height of the nodes in a single block is quite variable return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level; } u32 EmergeManager::getBlockSeed(v3s16 p) { return (u32)(params.seed & 0xFFFFFFFF) + p.Z * 38134234 + p.Y * 42123 + p.X * 23; } Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid, MapgenParams *mgparams) { std::map<std::string, MapgenFactory *>::const_iterator iter; iter = mglist.find(mgname); if (iter == mglist.end()) { errorstream << "EmergeManager; mapgen " << mgname << " not registered" << std::endl; return NULL; } MapgenFactory *mgfactory = iter->second; return mgfactory->createMapgen(mgid, mgparams, this); } MapgenSpecificParams *EmergeManager::createMapgenParams(std::string mgname) { std::map<std::string, MapgenFactory *>::const_iterator iter; iter = mglist.find(mgname); if (iter == mglist.end()) { errorstream << "EmergeManager: mapgen " << mgname << " not registered" << std::endl; return NULL; } MapgenFactory *mgfactory = iter->second; return mgfactory->createMapgenParams(); } void EmergeManager::loadParamsFromSettings(Settings *settings) { std::string seed_str; const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed"; if (settings->getNoEx(setname, seed_str)) params.seed = read_seed(seed_str.c_str()); settings->getNoEx("mg_name", params.mg_name); settings->getS16NoEx("water_level", params.water_level); settings->getS16NoEx("chunksize", params.chunksize); settings->getFlagStrNoEx("mg_flags", params.flags, flagdesc_mapgen); settings->getNoiseParams("mg_biome_np_heat", params.np_biome_heat); settings->getNoiseParams("mg_biome_np_humidity", params.np_biome_humidity); delete params.sparams; params.sparams = createMapgenParams(params.mg_name); if (params.sparams) params.sparams->readParams(settings); } void EmergeManager::saveParamsToSettings(Settings *settings) { settings->set("mg_name", params.mg_name); settings->setU64("seed", params.seed); settings->setS16("water_level", params.water_level); settings->setS16("chunksize", params.chunksize); settings->setFlagStr("mg_flags", params.flags, flagdesc_mapgen, (u32)-1); settings->setNoiseParams("mg_biome_np_heat", params.np_biome_heat); settings->setNoiseParams("mg_biome_np_humidity", params.np_biome_humidity); if (params.sparams) params.sparams->writeParams(settings); } void EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory) { mglist.insert(std::make_pair(mgname, mgfactory)); infostream << "EmergeManager: registered mapgen " << mgname << std::endl; } ////////////////////////////// Emerge Thread ////////////////////////////////// bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) { std::map<v3s16, BlockEmergeData *>::iterator iter; JMutexAutoLock queuelock(emerge->queuemutex); if (blockqueue.empty()) return false; v3s16 p = blockqueue.front(); blockqueue.pop(); *pos = p; iter = emerge->blocks_enqueued.find(p); if (iter == emerge->blocks_enqueued.end()) return false; //uh oh, queue and map out of sync!! BlockEmergeData *bedata = iter->second; *flags = bedata->flags; emerge->peer_queue_count[bedata->peer_requested]--; delete bedata; emerge->blocks_enqueued.erase(iter); return true; } bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, BlockMakeData *data, bool allow_gen) { v2s16 p2d(p.X, p.Z); //envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire