aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mapgen.cpp2
-rw-r--r--src/mapgen.h2
-rw-r--r--src/mg_biome.cpp40
-rw-r--r--src/mg_biome.h4
-rw-r--r--src/mg_decoration.cpp26
-rw-r--r--src/mg_decoration.h10
-rw-r--r--src/mg_ore.cpp25
-rw-r--r--src/mg_ore.h5
-rw-r--r--src/mg_schematic.cpp24
-rw-r--r--src/mg_schematic.h10
-rw-r--r--src/nodedef.cpp211
-rw-r--r--src/nodedef.h168
-rw-r--r--src/script/common/c_converter.cpp3
-rw-r--r--src/script/lua_api/l_mapgen.cpp68
-rw-r--r--src/script/lua_api/l_mapgen.h4
-rw-r--r--src/server.cpp12
16 files changed, 264 insertions, 350 deletions
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index ceaabbb1a..24f9fc556 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -384,7 +384,7 @@ void GenerateNotifier::getEvents(
GenElementManager::GenElementManager(IGameDef *gamedef)
{
- m_resolver = gamedef->getNodeDefManager()->getResolver();
+ m_ndef = gamedef->getNodeDefManager();
}
diff --git a/src/mapgen.h b/src/mapgen.h
index 03850cd19..07202f9a2 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -192,7 +192,7 @@ public:
virtual GenElement *getByName(const std::string &name);
protected:
- NodeResolver *m_resolver;
+ INodeDefManager *m_ndef;
std::vector<GenElement *> m_elements;
};
diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp
index a3a6d5128..763bef1bc 100644
--- a/src/mg_biome.cpp
+++ b/src/mg_biome.cpp
@@ -48,12 +48,14 @@ BiomeManager::BiomeManager(IGameDef *gamedef) :
b->heat_point = 0.0;
b->humidity_point = 0.0;
- m_resolver->addNode("air", "", CONTENT_AIR, &b->c_top);
- m_resolver->addNode("air", "", CONTENT_AIR, &b->c_filler);
- m_resolver->addNode("mapgen_stone", "", CONTENT_AIR, &b->c_stone);
- m_resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_water);
- m_resolver->addNode("air", "", CONTENT_AIR, &b->c_dust);
- m_resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_dust_water);
+ NodeResolveInfo *nri = new NodeResolveInfo(b);
+ nri->nodenames.push_back("air");
+ nri->nodenames.push_back("air");
+ nri->nodenames.push_back("mapgen_stone");
+ nri->nodenames.push_back("mapgen_water_source");
+ nri->nodenames.push_back("air");
+ nri->nodenames.push_back("mapgen_water_source");
+ m_ndef->pendNodeResolve(nri);
add(b);
}
@@ -102,18 +104,26 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
void BiomeManager::clear()
{
+
for (size_t i = 1; i < m_elements.size(); i++) {
Biome *b = (Biome *)m_elements[i];
- if (!b)
- continue;
-
- m_resolver->cancelNode(&b->c_top);
- m_resolver->cancelNode(&b->c_filler);
- m_resolver->cancelNode(&b->c_stone);
- m_resolver->cancelNode(&b->c_water);
- m_resolver->cancelNode(&b->c_dust);
- m_resolver->cancelNode(&b->c_dust_water);
+ delete b;
}
+
m_elements.resize(1);
}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+void Biome::resolveNodeNames(NodeResolveInfo *nri)
+{
+ m_ndef->getIdFromResolveInfo(nri, "mapgen_dirt_with_grass", CONTENT_AIR, c_top);
+ m_ndef->getIdFromResolveInfo(nri, "mapgen_dirt", CONTENT_AIR, c_filler);
+ m_ndef->getIdFromResolveInfo(nri, "mapgen_stone", CONTENT_AIR, c_stone);
+ m_ndef->getIdFromResolveInfo(nri, "mapgen_water_source", CONTENT_AIR, c_water);
+ m_ndef->getIdFromResolveInfo(nri, "air", CONTENT_IGNORE, c_dust);
+ m_ndef->getIdFromResolveInfo(nri, "mapgen_water_source", CONTENT_IGNORE, c_dust_water);
+}
+
diff --git a/src/mg_biome.h b/src/mg_biome.h
index f1539dacb..870c11961 100644
--- a/src/mg_biome.h
+++ b/src/mg_biome.h
@@ -33,7 +33,7 @@ enum BiomeType
BIOME_TYPE_FLAT
};
-class Biome : public GenElement {
+class Biome : public GenElement, public NodeResolver {
public:
u32 flags;
@@ -51,6 +51,8 @@ public:
s16 height_max;
float heat_point;
float humidity_point;
+
+ virtual void resolveNodeNames(NodeResolveInfo *nri);
};
class BiomeManager : public GenElementManager {
diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp
index 761b231ed..50e8fb05a 100644
--- a/src/mg_decoration.cpp
+++ b/src/mg_decoration.cpp
@@ -65,10 +65,7 @@ void DecorationManager::clear()
{
for (size_t i = 0; i < m_elements.size(); i++) {
Decoration *deco = (Decoration *)m_elements[i];
- if (!deco)
- continue;
-
- deco->dropResolverEntries(m_resolver);
+ delete deco;
}
m_elements.clear();
}
@@ -91,6 +88,12 @@ Decoration::~Decoration()
}
+void Decoration::resolveNodeNames(NodeResolveInfo *nri)
+{
+ m_ndef->getIdsFromResolveInfo(nri, c_place_on);
+}
+
+
size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
{
PseudoRandom ps(blockseed + 53);
@@ -229,6 +232,14 @@ void Decoration::placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
///////////////////////////////////////////////////////////////////////////////
+void DecoSimple::resolveNodeNames(NodeResolveInfo *nri)
+{
+ Decoration::resolveNodeNames(nri);
+ m_ndef->getIdsFromResolveInfo(nri, c_decos);
+ m_ndef->getIdsFromResolveInfo(nri, c_spawnby);
+}
+
+
bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p)
{
// Don't bother if there aren't any decorations to place
@@ -310,13 +321,6 @@ int DecoSimple::getHeight()
}
-void DecoSimple::dropResolverEntries(NodeResolver *resolver)
-{
- resolver->cancelNodeList(&c_decos);
- resolver->cancelNodeList(&c_spawnby);
-}
-
-
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index dffb524f3..910f1a581 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -58,7 +58,7 @@ struct CutoffData {
};
#endif
-class Decoration : public GenElement {
+class Decoration : public GenElement, public NodeResolver {
public:
INodeDefManager *ndef;
@@ -76,12 +76,13 @@ public:
Decoration();
virtual ~Decoration();
+ virtual void resolveNodeNames(NodeResolveInfo *nri);
+
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
virtual int getHeight() = 0;
- virtual void dropResolverEntries(NodeResolver *resolver) {}
};
class DecoSimple : public Decoration {
@@ -92,12 +93,11 @@ public:
s16 deco_height_max;
s16 nspawnby;
- ~DecoSimple() {}
+ virtual void resolveNodeNames(NodeResolveInfo *nri);
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
virtual int getHeight();
- virtual void dropResolverEntries(NodeResolver *resolver);
};
class DecoSchematic : public Decoration {
@@ -106,8 +106,6 @@ public:
Schematic *schematic;
std::string filename;
- ~DecoSchematic() {}
-
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
virtual int getHeight();
};
diff --git a/src/mg_ore.cpp b/src/mg_ore.cpp
index de3f6b0e5..8681b5782 100644
--- a/src/mg_ore.cpp
+++ b/src/mg_ore.cpp
@@ -64,11 +64,7 @@ void OreManager::clear()
{
for (size_t i = 0; i < m_elements.size(); i++) {
Ore *ore = (Ore *)m_elements[i];
- if (!ore)
- continue;
-
- m_resolver->cancelNodeList(&ore->c_wherein);
- m_resolver->cancelNode(&ore->c_ore);
+ delete ore;
}
m_elements.clear();
}
@@ -84,6 +80,19 @@ Ore::Ore()
}
+Ore::~Ore()
+{
+ delete noise;
+}
+
+
+void Ore::resolveNodeNames(NodeResolveInfo *nri)
+{
+ m_ndef->getIdFromResolveInfo(nri, "", CONTENT_AIR, c_ore);
+ m_ndef->getIdsFromResolveInfo(nri, c_wherein);
+}
+
+
size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
{
int in_range = 0;
@@ -113,6 +122,9 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
}
+///////////////////////////////////////////////////////////////////////////////
+
+
void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
u32 blockseed, v3s16 nmin, v3s16 nmax)
{
@@ -151,6 +163,9 @@ void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
}
+///////////////////////////////////////////////////////////////////////////////
+
+
void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
u32 blockseed, v3s16 nmin, v3s16 nmax)
{
diff --git a/src/mg_ore.h b/src/mg_ore.h
index 585d58f37..3b413674e 100644
--- a/src/mg_ore.h
+++ b/src/mg_ore.h
@@ -54,7 +54,7 @@ enum OreType {
extern FlagDesc flagdesc_ore[];
-class Ore : public GenElement {
+class Ore : public GenElement, public NodeResolver {
public:
static const bool NEEDS_NOISE = false;
@@ -72,6 +72,9 @@ public:
Noise *noise;
Ore();
+ virtual ~Ore();
+
+ virtual void resolveNodeNames(NodeResolveInfo *nri);
size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
diff --git a/src/mg_schematic.cpp b/src/mg_schematic.cpp
index a78824647..299a328c9 100644
--- a/src/mg_schematic.cpp
+++ b/src/mg_schematic.cpp
@@ -58,6 +58,12 @@ Schematic::~Schematic()
}
+void Schematic::resolveNodeNames(NodeResolveInfo *nri)
+{
+ m_ndef->getIdsFromResolveInfo(nri, c_nodes);
+}
+
+
void Schematic::updateContentIds()
{
if (flags & SCHEM_CIDS_UPDATED)
@@ -195,8 +201,7 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags,
bool Schematic::loadSchematicFromFile(const char *filename,
- NodeResolver *resolver,
- std::map<std::string, std::string> &replace_names)
+ INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
{
content_t cignore = CONTENT_IGNORE;
bool have_cignore = false;
@@ -224,10 +229,9 @@ bool Schematic::loadSchematicFromFile(const char *filename,
for (int y = 0; y != size.Y; y++)
slice_probs[y] = (version >= 3) ? readU8(is) : MTSCHEM_PROB_ALWAYS;
- int nodecount = size.X * size.Y * size.Z;
+ NodeResolveInfo *nri = new NodeResolveInfo(this);
u16 nidmapcount = readU16(is);
-
for (int i = 0; i != nidmapcount; i++) {
std::string name = deSerializeString(is);
if (name == "ignore") {
@@ -241,16 +245,22 @@ bool Schematic::loadSchematicFromFile(const char *filename,
if (it != replace_names.end())
name = it->second;
- resolver->addNodeList(name.c_str(), &c_nodes);
+ nri->nodenames.push_back(name);
}
+ nri->nodename_sizes.push_back(nidmapcount);
+ ndef->pendNodeResolve(nri);
+
+ size_t nodecount = size.X * size.Y * size.Z;
+
delete []schemdata;
schemdata = new MapNode[nodecount];
+
MapNode::deSerializeBulk(is, SER_FMT_VER_HIGHEST_READ, schemdata,
- nodecount, 2, 2, true);
+ nodecount, 2, 2, true);
if (version == 1) { // fix up the probability values
- for (int i = 0; i != nodecount; i++) {
+ for (size_t i = 0; i != nodecount; i++) {
if (schemdata[i].param1 == 0)
schemdata[i].param1 = MTSCHEM_PROB_ALWAYS;
if (have_cignore && schemdata[i].getContent() == cignore)
diff --git a/src/mg_schematic.h b/src/mg_schematic.h
index df54d79ba..8d0b18148 100644
--- a/src/mg_schematic.h
+++ b/src/mg_schematic.h
@@ -42,7 +42,7 @@ class NodeResolver;
#define MTSCHEM_PROB_ALWAYS 0xFF
-class Schematic : public GenElement {
+class Schematic : public GenElement, public NodeResolver {
public:
std::vector<content_t> c_nodes;
@@ -52,14 +52,16 @@ public:
u8 *slice_probs;
Schematic();
- ~Schematic();
+ virtual ~Schematic();
+
+ virtual void resolveNodeNames(NodeResolveInfo *nri);
void updateContentIds();
void blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
Rotation rot, bool force_placement, INodeDefManager *ndef);
- bool loadSchematicFromFile(const char *filename, NodeResolver *resolver,
+ bool loadSchematicFromFile(const char *filename, INodeDefManager *ndef,
std::map<std::string, std::string> &replace_names);
void saveSchematicToFile(const char *filename, INodeDefManager *ndef);
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
@@ -86,7 +88,7 @@ public:
};
void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
- std::vector<content_t> *usednodes);
+ std::vector<content_t> *usednodes);
#endif
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index e7bf9091f..bf97ff6d8 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -402,7 +402,15 @@ public:
virtual void updateTextures(IGameDef *gamedef);
void serialize(std::ostream &os, u16 protocol_version);
void deSerialize(std::istream &is);
- virtual NodeResolver *getResolver();
+
+ virtual void pendNodeResolve(NodeResolveInfo *nri);
+ virtual void cancelNodeResolve(NodeResolver *resolver);
+ virtual void runNodeResolverCallbacks();
+
+ virtual bool getIdFromResolveInfo(NodeResolveInfo *nri,
+ const std::string &node_alt, content_t c_fallback, content_t &result);
+ virtual bool getIdsFromResolveInfo(NodeResolveInfo *nri,
+ std::vector<content_t> &result);
private:
void addNameIdMapping(content_t i, std::string name);
@@ -432,13 +440,12 @@ private:
// Next possibly free id
content_t m_next_id;
- // NodeResolver to queue pending node resolutions
- NodeResolver m_resolver;
+ // List of node strings and node resolver callbacks to perform
+ std::list<NodeResolveInfo *> m_pending_node_lookups;
};
-CNodeDefManager::CNodeDefManager() :
- m_resolver(this)
+CNodeDefManager::CNodeDefManager()
{
clear();
}
@@ -1035,12 +1042,6 @@ void CNodeDefManager::addNameIdMapping(content_t i, std::string name)
}
-NodeResolver *CNodeDefManager::getResolver()
-{
- return &m_resolver;
-}
-
-
IWritableNodeDefManager *createNodeDefManager()
{
return new CNodeDefManager();
@@ -1267,166 +1268,100 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version)
}
}
-/*
- NodeResolver
-*/
-NodeResolver::NodeResolver(INodeDefManager *ndef)
+void CNodeDefManager::pendNodeResolve(NodeResolveInfo *nri)
{
- m_ndef = ndef;
- m_is_node_registration_complete = false;
+ nri->resolver->m_ndef = this;
+ m_pending_node_lookups.push_back(nri);
}
-NodeResolver::~NodeResolver()
+void CNodeDefManager::cancelNodeResolve(NodeResolver *resolver)
{
- while (!m_pending_contents.empty()) {
- NodeResolveInfo *nri = m_pending_contents.front();
- m_pending_contents.pop_front();
- delete nri;
- }
-}
-
-
-int NodeResolver::addNode(const std::string &n_wanted, const std::string &n_alt,
- content_t c_fallback, content_t *content)
-{
- if (m_is_node_registration_complete) {
- if (m_ndef->getId(n_wanted, *content))
- return NR_STATUS_SUCCESS;
-
- if (n_alt == "" || !m_ndef->getId(n_alt, *content)) {
- *content = c_fallback;
- return NR_STATUS_FAILURE;
+ for (std::list<NodeResolveInfo *>::iterator
+ it = m_pending_node_lookups.begin();
+ it != m_pending_node_lookups.end();
+ ++it) {
+ NodeResolveInfo *nri = *it;
+ if (resolver == nri->resolver) {
+ it = m_pending_node_lookups.erase(it);
+ delete nri;
}
-
- return NR_STATUS_SUCCESS;
- } else {
- NodeResolveInfo *nfi = new NodeResolveInfo;
- nfi->n_wanted = n_wanted;
- nfi->n_alt = n_alt;
- nfi->c_fallback = c_fallback;
- nfi->output = content;
-
- m_pending_contents.push_back(nfi);
-
- return NR_STATUS_PENDING;
}
}
-int NodeResolver::addNodeList(const std::string &nodename,
- std::vector<content_t> *content_vec)
+void CNodeDefManager::runNodeResolverCallbacks()
{
- if (m_is_node_registration_complete) {
- std::set<content_t> idset;
- std::set<content_t>::iterator it;
-
- m_ndef->getIds(nodename, idset);
- for (it = idset.begin(); it != idset.end(); ++it)
- content_vec->push_back(*it);
-
- return idset.size() ? NR_STATUS_SUCCESS : NR_STATUS_FAILURE;
- } else {
- m_pending_content_vecs.push_back(
- std::make_pair(nodename, content_vec));
- return NR_STATUS_PENDING;
+ while (!m_pending_node_lookups.empty()) {
+ NodeResolveInfo *nri = m_pending_node_lookups.front();
+ m_pending_node_lookups.pop_front();
+ nri->resolver->resolveNodeNames(nri);
+ nri->resolver->m_lookup_done = true;
+ delete nri;
}
}
-bool NodeResolver::cancelNode(content_t *content)
+bool CNodeDefManager::getIdFromResolveInfo(NodeResolveInfo *nri,
+ const std::string &node_alt, content_t c_fallback, content_t &result)
{
- bool found = false;
-
- for (std::list<NodeResolveInfo *>::iterator
- it = m_pending_contents.begin();
- it != m_pending_contents.end();
- ++it) {
- NodeResolveInfo *nfi = *it;
- if (nfi->output == content) {
- it = m_pending_contents.erase(it);
- delete nfi;
- found = true;
- }
+ if (nri->nodenames.empty()) {
+ result = c_fallback;
+ errorstream << "CNodeDefManager::getIdFromResolveInfo: empty "
+ "nodenames list" << std::endl;
+ return false;
}
- return found;
-}
-
+ content_t c;
+ std::string name = nri->nodenames.front();
+ nri->nodenames.pop_front();
-int NodeResolver::cancelNodeList(std::vector<content_t> *content_vec)
-{
- int num_canceled = 0;
+ bool success = getId(name, c);
+ if (!success && node_alt != "") {
+ name = node_alt;
+ success = getId(name, c);
+ }
- for (ContentVectorResolveList::iterator
- it = m_pending_content_vecs.begin();
- it != m_pending_content_vecs.end();
- ++it) {
- if (it->second == content_vec) {
- it = m_pending_content_vecs.erase(it);
- num_canceled++;
- }
+ if (!success) {
+ errorstream << "CNodeDefManager::getIdFromResolveInfo: Failed to "
+ "resolve node name '" << name << "'." << std::endl;
+ c = c_fallback;
}
- return num_canceled;
+ result = c;
+ return success;
}
-int NodeResolver::resolveNodes()
+bool CNodeDefManager::getIdsFromResolveInfo(NodeResolveInfo *nri,
+ std::vector<content_t> &result)
{
- int num_failed = 0;
+ if (nri->nodename_sizes.empty()) {
+ errorstream << "CNodeDefManager::getIdsFromResolveInfo: empty "
+ "nodename_sizes list" << std::endl;
+ return false;
+ }
- //// Resolve pending single node name -> content ID mappings
- while (!m_pending_contents.empty()) {
- NodeResolveInfo *nri = m_pending_contents.front();
- m_pending_contents.pop_front();
+ size_t nitems = nri->nodename_sizes.front();
+ nri->nodename_sizes.pop_front();
- bool success = true;
- if (!m_ndef->getId(nri->n_wanted, *nri->output)) {
- success = (nri->n_alt != "") ?
- m_ndef->getId(nri->n_alt, *nri->output) : false;
+ while (nitems--) {
+ if (nri->nodenames.empty()) {
+ errorstream << "" << std::endl;
+ return false;
}
- if (!success) {
- *nri->output = nri->c_fallback;
- num_failed++;
- errorstream << "NodeResolver::resolveNodes(): Failed to "
- "resolve '" << nri->n_wanted;
- if (nri->n_alt != "")
- errorstream << "' and '" << nri->n_alt;
- errorstream << "'" << std::endl;
+ content_t c;
+ if (getId(nri->nodenames.front(), c)) {
+ result.push_back(c);
+ } else {
+ errorstream << "CNodeDefManager::getIdsFromResolveInfo: empty "
+ "nodenames list" << std::endl;
}
- delete nri;
- }
-
- //// Resolve pending node names and add to content_t vector
- while (!m_pending_content_vecs.empty()) {
- std::pair<std::string, std::vector<content_t> *> item =
- m_pending_content_vecs.front();
- m_pending_content_vecs.pop_front();
-
- std::string &name = item.first;
- std::vector<content_t> *output = item.second;
-
- std::set<content_t> idset;
- std::set<content_t>::iterator it;
-
- m_ndef->getIds(name, idset);
- for (it = idset.begin(); it != idset.end(); ++it)
- output->push_back(*it);
-
- if (idset.empty()) {
- num_failed++;
- errorstream << "NodeResolver::resolveNodes(): Failed to "
- "resolve '" << name << "'" << std::endl;
- }
+ nri->nodenames.pop_front();
}
- //// Mark node registration as complete so future resolve
- //// requests are satisfied immediately
- m_is_node_registration_complete = true;
-
- return num_failed;
+ return true;
}
diff --git a/src/nodedef.h b/src/nodedef.h
index dd76717e1..0c779ddcc 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -40,8 +40,6 @@ class IShaderSource;
class IGameDef;
typedef std::list<std::pair<content_t, int> > GroupItems;
-typedef std::list<std::pair<std::string, std::vector<content_t> *> >
- ContentVectorResolveList;
enum ContentParamType
{
@@ -284,125 +282,18 @@ struct ContentFeatures
}
};
-struct NodeResolveInfo {
- std::string n_wanted;
- std::string n_alt;
- content_t c_fallback;
- content_t *output;
-};
-
-#define NR_STATUS_FAILURE 0
-#define NR_STATUS_PENDING 1
-#define NR_STATUS_SUCCESS 2
-
-/**
- NodeResolver
-
- NodeResolver attempts to resolve node names to content ID integers. If the
- node registration phase has not yet finished at the time the resolution
- request is placed, the request is marked as pending and added to an internal
- queue. The name resolution request is later satisfied by writing directly
- to the output location when the node registration phase has been completed.
-
- This is primarily intended to be used for objects registered during script
- initialization (i.e. while nodes are being registered) that reference
- particular nodes.
-*/
-class NodeResolver {
-public:
- NodeResolver(INodeDefManager *ndef);
- ~NodeResolver();
-
- /**
- Add a request to resolve the node n_wanted and set *content to the
- result, or alternatively, n_alt if n_wanted is not found. If n_alt
- cannot be found either, or has not been specified, *content is set
- to c_fallback.
-
- If node registration is complete, the request is finished immediately
- and NR_STATUS_SUCCESS is returned (or NR_STATUS_FAILURE if no node can
- be found). Otherwise, NR_STATUS_PENDING is returned and the resolution
- request is queued.
-
- N.B. If the memory in which content is located has been deallocated
- before the pending request had been satisfied, cancelNode() must be
- called.
-
- @param n_wanted Name of node that is wanted.
- @param n_alt Name of node in case n_wanted could not be found. Blank
- if no alternative node is desired.
- @param c_fallback Content ID that content is set to in case of node
- resolution failure (should be CONTENT_AIR, CONTENT_IGNORE, etc.)
- @param content Pointer to content_t that receives the result of the
- node name resolution.
- @return Status of node resolution request.
- */
- int addNode(const std::string &n_wanted, const std::string &n_alt,
- content_t c_fallback, content_t *content);
-
- /**
- Add a request to resolve the node(s) specified by nodename.
-
- If node registration is complete, the request is finished immediately
- and NR_STATUS_SUCCESS is returned if at least one node is resolved; if
- zero were resolved, NR_STATUS_FAILURE. Otherwise, NR_STATUS_PENDING is
- returned and the resolution request is queued.
-
- N.B. If the memory in which content_vec is located has been deallocated
- before the pending request had been satisfied, cancelNodeList() must be
- called.
-
- @param nodename Name of node (or node group) to be resolved.
- @param content_vec Pointer to content_t vector onto which the results
- are added.
-
- @return Status of node resolution request.
- */
- int addNodeList(const std::string &nodename,
- std::vector<content_t> *content_vec);
-
- /**
- Removes all pending requests from the resolution queue with the output
- address of 'content'.
-
- @param content Location of the content ID for the request being
- cancelled.
- @return Number of pending requests cancelled.
- */
- bool cancelNode(content_t *content);
-
- /**
- Removes all pending requests from the resolution queue with the output
- address of 'content_vec'.
-
- @param content_vec Location of the content ID vector for requests being
- cancelled.
- @return Number of pending requests cancelled.
- */
- int cancelNodeList(std::vector<content_t> *content_vec);
-
- /**
- Carries out all pending node resolution requests. Call this when the
- node registration phase has completed.
-
- Internally marks node registration as complete.
+class NodeResolver;
+class INodeDefManager;
- @return Number of failed pending requests.
- */
- int resolveNodes();
-
- /**
- Returns the status of the node registration phase.
-
- @return Boolean of whether the registration phase is complete.
- */
- bool isNodeRegFinished() { return m_is_node_registration_complete; }
+struct NodeResolveInfo {
+ NodeResolveInfo(NodeResolver *nr)
+ {
+ resolver = nr;
+ }
-private:
- INodeDefManager *m_ndef;
- bool m_is_node_registration_complete;
- std::list<NodeResolveInfo *> m_pending_contents;
- ContentVectorResolveList m_pending_content_vecs;
+ std::list<std::string> nodenames;
+ std::list<size_t> nodename_sizes;
+ NodeResolver *resolver;
};
class INodeDefManager
@@ -422,7 +313,14 @@ public:
virtual void serialize(std::ostream &os, u16 protocol_version)=0;
- virtual NodeResolver *getResolver()=0;
+ virtual void pendNodeResolve(NodeResolveInfo *nri)=0;
+ virtual void cancelNodeResolve(NodeResolver *resolver)=0;
+ virtual void runNodeResolverCallbacks()=0;
+
+ virtual bool getIdFromResolveInfo(NodeResolveInfo *nri,
+ const std::string &node_alt, content_t c_fallback, content_t &result)=0;
+ virtual bool getIdsFromResolveInfo(NodeResolveInfo *nri,
+ std::vector<content_t> &result)=0;
};
class IWritableNodeDefManager : public INodeDefManager
@@ -464,10 +362,38 @@ public:
virtual void serialize(std::ostream &os, u16 protocol_version)=0;
virtual void deSerialize(std::istream &is)=0;
- virtual NodeResolver *getResolver()=0;
+ virtual void pendNodeResolve(NodeResolveInfo *nri)=0;
+ virtual void cancelNodeResolve(NodeResolver *resolver)=0;
+ virtual void runNodeResolverCallbacks()=0;
+
+ virtual bool getIdFromResolveInfo(NodeResolveInfo *nri,
+ const std::string &node_alt, content_t c_fallback, content_t &result)=0;
+ virtual bool getIdsFromResolveInfo(NodeResolveInfo *nri,
+ std::vector<content_t> &result)=0;
};
IWritableNodeDefManager *createNodeDefManager();
+class NodeResolver {
+public:
+ NodeResolver()
+ {
+ m_lookup_done = false;
+ m_ndef = NULL;
+ }
+
+ ~NodeResolver()
+ {
+ if (!m_lookup_done)
+ m_ndef->cancelNodeResolve(this);
+ }
+
+ virtual void resolveNodeNames(NodeResolveInfo *nri) = 0;
+
+ bool m_lookup_done;
+ INodeDefManager *m_ndef;
+};
+
+
#endif
diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp
index a906171d3..66eeec68e 100644
--- a/src/script/common/c_converter.cpp
+++ b/src/script/common/c_converter.cpp
@@ -235,7 +235,8 @@ bool read_stringlist(lua_State *L, int index, std::vector<const char *> &result)
if (lua_istable(L, index)) {
lua_pushnil(L);
while (lua_next(L, index)) {
- result.push_back(lua_tostring(L, -1));
+ if (lua_isstring(L, -1))
+ result.push_back(lua_tostring(L, -1));
lua_pop(L, 1);
}
} else if (lua_isstring(L, index)) {
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 177e0d85b..a90c2c6c5 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -183,9 +183,8 @@ bool get_schematic(lua_State *L, int index, Schematic *schem,
if (lua_istable(L, index)) {
return read_schematic(L, index, schem, ndef, replace_names);
} else if (lua_isstring(L, index)) {
- NodeResolver *resolver = ndef->getResolver();
const char *filename = lua_tostring(L, index);
- return schem->loadSchematicFromFile(filename, resolver, replace_names);
+ return schem->loadSchematicFromFile(filename, ndef, replace_names);
} else {
return false;
}
@@ -415,8 +414,8 @@ int ModApiMapgen::l_register_biome(lua_State *L)
int index = 1;
luaL_checktype(L, index, LUA_TTABLE);
- NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
- BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
+ INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+ BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
enum BiomeType biometype = (BiomeType)getenumfield(L, index, "type",
es_BiomeTerrainType, BIOME_TYPE_NORMAL);
@@ -437,19 +436,15 @@ int ModApiMapgen::l_register_biome(lua_State *L)
return 0;
}
- // Pend node resolutions only if insertion succeeded
- resolver->addNode(getstringfield_default(L, index, "node_top", ""),
- "mapgen_dirt_with_grass", CONTENT_AIR, &b->c_top);
- resolver->addNode(getstringfield_default(L, index, "node_filler", ""),
- "mapgen_dirt", CONTENT_AIR, &b->c_filler);
- resolver->addNode(getstringfield_default(L, index, "node_stone", ""),
- "mapgen_stone", CONTENT_AIR, &b->c_stone);
- resolver->addNode(getstringfield_default(L, index, "node_water", ""),
- "mapgen_water_source", CONTENT_AIR, &b->c_water);
- resolver->addNode(getstringfield_default(L, index, "node_dust", ""),
- "air", CONTENT_IGNORE, &b->c_dust);
- resolver->addNode(getstringfield_default(L, index, "node_dust_water", ""),
- "mapgen_water_source", CONTENT_IGNORE, &b->c_dust_water);
+ NodeResolveInfo *nri = new NodeResolveInfo(b);
+ std::list<std::string> &nnames = nri->nodenames;
+ nnames.push_back(getstringfield_default(L, index, "node_top", ""));
+ nnames.push_back(getstringfield_default(L, index, "node_filler", ""));
+ nnames.push_back(getstringfield_default(L, index, "node_stone", ""));
+ nnames.push_back(getstringfield_default(L, index, "node_water", ""));
+ nnames.push_back(getstringfield_default(L, index, "node_dust", ""));
+ nnames.push_back(getstringfield_default(L, index, "node_dust_water", ""));
+ ndef->pendNodeResolve(nri);
verbosestream << "register_biome: " << b->name << std::endl;
@@ -485,7 +480,6 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
luaL_checktype(L, index, LUA_TTABLE);
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
- NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr;
@@ -509,11 +503,14 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
return 0;
}
+ NodeResolveInfo *nri = new NodeResolveInfo(deco);
+
//// Get node name(s) to place decoration on
std::vector<const char *> place_on_names;
getstringlistfield(L, index, "place_on", place_on_names);
+ nri->nodename_sizes.push_back(place_on_names.size());
for (size_t i = 0; i != place_on_names.size(); i++)
- resolver->addNodeList(place_on_names[i], &deco->c_place_on);
+ nri->nodenames.push_back(place_on_names[i]);
getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL);
@@ -538,7 +535,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
bool success = false;
switch (decotype) {
case DECO_SIMPLE:
- success = regDecoSimple(L, resolver, (DecoSimple *)deco);
+ success = regDecoSimple(L, nri, (DecoSimple *)deco);
break;
case DECO_SCHEMATIC:
success = regDecoSchematic(L, ndef, (DecoSchematic *)deco);
@@ -547,6 +544,8 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
break;
}
+ ndef->pendNodeResolve(nri);
+
if (!success) {
delete deco;
return 0;
@@ -558,12 +557,14 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
return 0;
}
+ verbosestream << "register_decoration: " << deco->name << std::endl;
+
lua_pushinteger(L, id);
return 1;
}
bool ModApiMapgen::regDecoSimple(lua_State *L,
- NodeResolver *resolver, DecoSimple *deco)
+ NodeResolveInfo *nri, DecoSimple *deco)
{
int index = 1;
@@ -584,6 +585,9 @@ bool ModApiMapgen::regDecoSimple(lua_State *L,
"defined" << std::endl;
return false;
}
+ nri->nodename_sizes.push_back(deco_names.size());
+ for (size_t i = 0; i != deco_names.size(); i++)
+ nri->nodenames.push_back(deco_names[i]);
std::vector<const char *> spawnby_names;
getstringlistfield(L, index, "spawn_by", spawnby_names);
@@ -592,11 +596,9 @@ bool ModApiMapgen::regDecoSimple(lua_State *L,
" but num_spawn_by specified" << std::endl;
return false;
}
-
- for (size_t i = 0; i != deco_names.size(); i++)
- resolver->addNodeList(deco_names[i], &deco->c_decos);
+ nri->nodename_sizes.push_back(spawnby_names.size());
for (size_t i = 0; i != spawnby_names.size(); i++)
- resolver->addNodeList(spawnby_names[i], &deco->c_spawnby);
+ nri->nodenames.push_back(spawnby_names[i]);
return true;
}
@@ -615,6 +617,7 @@ bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef,
read_schematic_replacements(L, replace_names, lua_gettop(L));
lua_pop(L, 1);
+ // TODO(hmmmm): get a ref from registered schematics
Schematic *schem = new Schematic;
lua_getfield(L, index, "schematic");
if (!get_schematic(L, -1, schem, ndef, replace_names)) {
@@ -635,8 +638,8 @@ int ModApiMapgen::l_register_ore(lua_State *L)
int index = 1;
luaL_checktype(L, index, LUA_TTABLE);
- NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
- OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr;
+ INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+ OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr;
enum OreType oretype = (OreType)getenumfield(L, index,
"ore_type", es_OreType, ORE_SCATTER);
@@ -683,13 +686,18 @@ int ModApiMapgen::l_register_ore(lua_State *L)
return 0;
}
+ NodeResolveInfo *nri = new NodeResolveInfo(ore);
+ nri->nodenames.push_back(getstringfield_default(L, index, "ore", ""));
+
std::vector<const char *> wherein_names;
getstringlistfield(L, index, "wherein", wherein_names);
+ nri->nodename_sizes.push_back(wherein_names.size());
for (size_t i = 0; i != wherein_names.size(); i++)
- resolver->addNodeList(wherein_names[i], &ore->c_wherein);
+ nri->nodenames.push_back(wherein_names[i]);
+
+ ndef->pendNodeResolve(nri);
- resolver->addNode(getstringfield_default(L, index, "ore", ""),
- "", CONTENT_AIR, &ore->c_ore);
+ verbosestream << "register_ore: " << ore->name << std::endl;
lua_pushinteger(L, id);
return 1;
diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h
index 87ae9fd81..247043a01 100644
--- a/src/script/lua_api/l_mapgen.h
+++ b/src/script/lua_api/l_mapgen.h
@@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_base.h"
class INodeDefManager;
-class NodeResolver;
+class NodeResolveInfo;
class DecoSimple;
class DecoSchematic;
@@ -68,7 +68,7 @@ private:
static int l_place_schematic(lua_State *L);
static bool regDecoSimple(lua_State *L,
- NodeResolver *resolver, DecoSimple *deco);
+ NodeResolveInfo *nri, DecoSimple *deco);
static bool regDecoSchematic(lua_State *L,
INodeDefManager *ndef, DecoSchematic *deco);
diff --git a/src/server.cpp b/src/server.cpp
index d56c34c65..161aaafc7 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -337,7 +337,7 @@ Server::Server(
m_nodedef->updateAliases(m_itemdef);
// Perform pending node name resolutions
- m_nodedef->getResolver()->resolveNodes();
+ m_nodedef->runNodeResolverCallbacks();
// Load the mapgen params from global settings now after any
// initial overrides have been set by the mods
@@ -2650,7 +2650,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
} // action == 4
-
+
/*
Catch invalid actions
@@ -4570,7 +4570,7 @@ bool Server::showFormspec(const char *playername, const std::string &formspec, c
u32 Server::hudAdd(Player *player, HudElement *form) {
if (!player)
return -1;
-
+
u32 id = player->addHud(form);
SendHUDAdd(player->peer_id, id, form);
@@ -4586,7 +4586,7 @@ bool Server::hudRemove(Player *player, u32 id) {
if (!todel)
return false;
-
+
delete todel;
SendHUDRemove(player->peer_id, id);
@@ -4607,9 +4607,9 @@ bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) {
SendHUDSetFlags(player->peer_id, flags, mask);
player->hud_flags = flags;
-
+
PlayerSAO* playersao = player->getPlayerSAO();
-
+
if (playersao == NULL)
return false;