Skip to content

Commit 479f389

Browse files
committedApr 16, 2015
Schematics: Refactor NodeResolver and add NodeResolveMethod
NodeResolver name lists now belong to the NodeResolver object instead of the associated NodeDefManager. In addition to minimizing unnecessary abstraction and overhead, this move permits NodeResolvers to look up nodes that they had previously set pending for resolution. So far, this functionality has been used in the case of schematics for serialization/deserialization.
1 parent 0c634a9 commit 479f389

17 files changed

+470
-435
lines changed
 

Diff for: ‎doc/lua_api.txt

+13-4
Original file line numberDiff line numberDiff line change
@@ -2170,14 +2170,23 @@ These functions return the leftover itemstack.
21702170
* `force_placement` is a boolean indicating whether nodes other than `air` and
21712171
`ignore` are replaced by the schematic
21722172

2173-
* `minetest.serialize_schematic(schematic, format, use_comments)`
2173+
* `minetest.serialize_schematic(schematic, format, options)`
21742174
* Return the serialized schematic specified by schematic (see: Schematic specifier)
21752175
* in the `format` of either "mts" or "lua".
21762176
* "mts" - a string containing the binary MTS data used in the MTS file format
21772177
* "lua" - a string containing Lua code representing the schematic in table format
2178-
* If `use_comments` is true, the Lua code generated will have (X, Z) position comments
2179-
* for every X row generated in the schematic data for easier reading. This parameter
2180-
* is ignored if `format` is not "lua".
2178+
* `options` is a table containing the following optional parameters:
2179+
* If `use_comments` is true and `format` is "lua", the Lua code generated will have (X, Z)
2180+
* position comments for every X row generated in the schematic data for easier reading.
2181+
* If `register_after_load` is true, then `schematic`, if not yet loaded, will be registered
2182+
* after loading and persist in memory.
2183+
* node_resolve_method can be one of either "none", "direct", or "deferred" (default: "none")
2184+
* This sets the way method by with node names are mapped to their content IDs, if loaded:
2185+
* "none" performs no node resolution and preserves all node names from the schematic definition
2186+
* "direct" performs an immediate lookup of content ID, given all the nodes that have been
2187+
* registered up to this point in script execution
2188+
* "deferred" pends node resolution until after the script registration phase has ended
2189+
* In practice, it is recommended to use "none" in nearly all use cases.
21812190

21822191
### Misc.
21832192
* `minetest.get_connected_players()`: returns list of `ObjectRefs`

Diff for: ‎src/client.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ void Client::step(float dtime)
388388
if(counter <= 0.0) {
389389
counter = 2.0;
390390

391-
Player *myplayer = m_env.getLocalPlayer();
391+
Player *myplayer = m_env.getLocalPlayer();
392392
FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment.");
393393

394394
// Send TOSERVER_INIT_LEGACY
@@ -1631,7 +1631,7 @@ void Client::afterContentReceived(IrrlichtDevice *device)
16311631
draw_load_screen(text, device, guienv, 0, 72);
16321632
m_nodedef->updateAliases(m_itemdef);
16331633
m_nodedef->setNodeRegistrationStatus(true);
1634-
m_nodedef->runNodeResolverCallbacks();
1634+
m_nodedef->runNodeResolveCallbacks();
16351635
delete[] text;
16361636

16371637
// Update node textures and assign shaders to each tile

Diff for: ‎src/mg_biome.cpp

+14-15
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@ BiomeManager::BiomeManager(IGameDef *gamedef) :
4646
b->heat_point = 0.0;
4747
b->humidity_point = 0.0;
4848

49-
NodeResolveInfo *nri = new NodeResolveInfo(b);
50-
nri->nodenames.push_back("air");
51-
nri->nodenames.push_back("air");
52-
nri->nodenames.push_back("mapgen_stone");
53-
nri->nodenames.push_back("mapgen_water_source");
54-
nri->nodenames.push_back("mapgen_water_source");
55-
nri->nodenames.push_back("air");
56-
m_ndef->pendNodeResolve(nri);
49+
b->m_nodenames.push_back("air");
50+
b->m_nodenames.push_back("air");
51+
b->m_nodenames.push_back("mapgen_stone");
52+
b->m_nodenames.push_back("mapgen_water_source");
53+
b->m_nodenames.push_back("mapgen_water_source");
54+
b->m_nodenames.push_back("air");
55+
m_ndef->pendNodeResolve(b, NODE_RESOLVE_DEFERRED);
5756

5857
add(b);
5958
}
@@ -117,13 +116,13 @@ void BiomeManager::clear()
117116
///////////////////////////////////////////////////////////////////////////////
118117

119118

120-
void Biome::resolveNodeNames(NodeResolveInfo *nri)
119+
void Biome::resolveNodeNames()
121120
{
122-
m_ndef->getIdFromResolveInfo(nri, "mapgen_dirt_with_grass", CONTENT_AIR, c_top);
123-
m_ndef->getIdFromResolveInfo(nri, "mapgen_dirt", CONTENT_AIR, c_filler);
124-
m_ndef->getIdFromResolveInfo(nri, "mapgen_stone", CONTENT_AIR, c_stone);
125-
m_ndef->getIdFromResolveInfo(nri, "mapgen_water_source", CONTENT_AIR, c_water_top);
126-
m_ndef->getIdFromResolveInfo(nri, "mapgen_water_source", CONTENT_AIR, c_water);
127-
m_ndef->getIdFromResolveInfo(nri, "air", CONTENT_IGNORE, c_dust);
121+
getIdFromNrBacklog(&c_top, "mapgen_dirt_with_grass", CONTENT_AIR);
122+
getIdFromNrBacklog(&c_filler, "mapgen_dirt", CONTENT_AIR);
123+
getIdFromNrBacklog(&c_stone, "mapgen_stone", CONTENT_AIR);
124+
getIdFromNrBacklog(&c_water_top, "mapgen_water_source", CONTENT_AIR);
125+
getIdFromNrBacklog(&c_water, "mapgen_water_source", CONTENT_AIR);
126+
getIdFromNrBacklog(&c_dust, "air", CONTENT_IGNORE);
128127
}
129128

Diff for: ‎src/mg_biome.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class Biome : public ObjDef, public NodeResolver {
5353
float heat_point;
5454
float humidity_point;
5555

56-
virtual void resolveNodeNames(NodeResolveInfo *nri);
56+
virtual void resolveNodeNames();
5757
};
5858

5959
class BiomeManager : public ObjDefManager {

Diff for: ‎src/mg_decoration.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ Decoration::~Decoration()
8888
}
8989

9090

91-
void Decoration::resolveNodeNames(NodeResolveInfo *nri)
91+
void Decoration::resolveNodeNames()
9292
{
93-
m_ndef->getIdsFromResolveInfo(nri, c_place_on);
93+
getIdsFromNrBacklog(&c_place_on);
9494
}
9595

9696

@@ -232,11 +232,11 @@ void Decoration::placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
232232
///////////////////////////////////////////////////////////////////////////////
233233

234234

235-
void DecoSimple::resolveNodeNames(NodeResolveInfo *nri)
235+
void DecoSimple::resolveNodeNames()
236236
{
237-
Decoration::resolveNodeNames(nri);
238-
m_ndef->getIdsFromResolveInfo(nri, c_decos);
239-
m_ndef->getIdsFromResolveInfo(nri, c_spawnby);
237+
Decoration::resolveNodeNames();
238+
getIdsFromNrBacklog(&c_decos);
239+
getIdsFromNrBacklog(&c_spawnby);
240240
}
241241

242242

Diff for: ‎src/mg_decoration.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Decoration : public ObjDef, public NodeResolver {
7979
Decoration();
8080
virtual ~Decoration();
8181

82-
virtual void resolveNodeNames(NodeResolveInfo *nri);
82+
virtual void resolveNodeNames();
8383

8484
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
8585
//size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
@@ -96,7 +96,7 @@ class DecoSimple : public Decoration {
9696
s16 deco_height_max;
9797
s16 nspawnby;
9898

99-
virtual void resolveNodeNames(NodeResolveInfo *nri);
99+
virtual void resolveNodeNames();
100100

101101
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
102102
virtual size_t generate(MMVManip *vm, PseudoRandom *pr, v3s16 p);

Diff for: ‎src/mg_ore.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ Ore::~Ore()
8282
}
8383

8484

85-
void Ore::resolveNodeNames(NodeResolveInfo *nri)
85+
void Ore::resolveNodeNames()
8686
{
87-
m_ndef->getIdFromResolveInfo(nri, "", CONTENT_AIR, c_ore);
88-
m_ndef->getIdsFromResolveInfo(nri, c_wherein);
87+
getIdFromNrBacklog(&c_ore, "", CONTENT_AIR);
88+
getIdsFromNrBacklog(&c_wherein);
8989
}
9090

9191

Diff for: ‎src/mg_ore.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Ore : public ObjDef, public NodeResolver {
6767
Ore();
6868
virtual ~Ore();
6969

70-
virtual void resolveNodeNames(NodeResolveInfo *nri);
70+
virtual void resolveNodeNames();
7171

7272
size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
7373
virtual void generate(MMVManip *vm, int mapseed, u32 blockseed,

Diff for: ‎src/mg_schematic.cpp

+28-36
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,16 @@ Schematic::~Schematic()
5656
}
5757

5858

59-
void Schematic::resolveNodeNames(NodeResolveInfo *nri)
59+
void Schematic::resolveNodeNames()
6060
{
61-
m_ndef->getIdsFromResolveInfo(nri, c_nodes);
62-
}
63-
64-
65-
void Schematic::updateContentIds()
66-
{
67-
if (flags & SCHEM_CIDS_UPDATED)
68-
return;
69-
70-
flags |= SCHEM_CIDS_UPDATED;
61+
getIdsFromNrBacklog(&c_nodes, true, CONTENT_AIR);
7162

7263
size_t bufsize = size.X * size.Y * size.Z;
73-
for (size_t i = 0; i != bufsize; i++)
74-
schemdata[i].setContent(c_nodes[schemdata[i].getContent()]);
64+
for (size_t i = 0; i != bufsize; i++) {
65+
content_t c_original = schemdata[i].getContent();
66+
content_t c_new = c_nodes[c_original];
67+
schemdata[i].setContent(c_new);
68+
}
7569
}
7670

7771

@@ -82,8 +76,6 @@ void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot,
8276
int ystride = size.X;
8377
int zstride = size.X * size.Y;
8478

85-
updateContentIds();
86-
8779
s16 sx = size.X;
8880
s16 sy = size.Y;
8981
s16 sz = size.Z;
@@ -198,8 +190,7 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
198190
}
199191

200192

201-
bool Schematic::deserializeFromMts(std::istream *is,
202-
INodeDefManager *ndef, std::vector<std::string> *names)
193+
bool Schematic::deserializeFromMts(std::istream *is, std::vector<std::string> *names)
203194
{
204195
std::istream &ss = *is;
205196
content_t cignore = CONTENT_IGNORE;
@@ -263,7 +254,7 @@ bool Schematic::deserializeFromMts(std::istream *is,
263254
}
264255

265256

266-
bool Schematic::serializeToMts(std::ostream *os, INodeDefManager *ndef)
257+
bool Schematic::serializeToMts(std::ostream *os)
267258
{
268259
std::ostream &ss = *os;
269260

@@ -281,7 +272,7 @@ bool Schematic::serializeToMts(std::ostream *os, INodeDefManager *ndef)
281272
u16 numids = usednodes.size();
282273
writeU16(ss, numids); // name count
283274
for (int i = 0; i != numids; i++)
284-
ss << serializeString(ndef->get(usednodes[i]).name); // node names
275+
ss << serializeString(getNodeName(usednodes[i])); // node names
285276

286277
// compressed bulk node data
287278
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE,
@@ -291,8 +282,7 @@ bool Schematic::serializeToMts(std::ostream *os, INodeDefManager *ndef)
291282
}
292283

293284

294-
bool Schematic::serializeToLua(std::ostream *os,
295-
INodeDefManager *ndef, bool use_comments)
285+
bool Schematic::serializeToLua(std::ostream *os, bool use_comments)
296286
{
297287
std::ostream &ss = *os;
298288

@@ -335,7 +325,7 @@ bool Schematic::serializeToLua(std::ostream *os,
335325

336326
for (u16 x = 0; x != size.X; x++, i++) {
337327
ss << "\t\t{"
338-
<< "name=\"" << ndef->get(schemdata[i]).name
328+
<< "name=\"" << getNodeName(schemdata[i].getContent())
339329
<< "\", param1=" << (u16)schemdata[i].param1
340330
<< ", param2=" << (u16)schemdata[i].param2
341331
<< "}," << std::endl;
@@ -351,8 +341,9 @@ bool Schematic::serializeToLua(std::ostream *os,
351341
}
352342

353343

354-
bool Schematic::loadSchematicFromFile(const char *filename,
355-
INodeDefManager *ndef, StringMap *replace_names)
344+
bool Schematic::loadSchematicFromFile(const std::string &filename,
345+
INodeDefManager *ndef, StringMap *replace_names,
346+
NodeResolveMethod resolve_method)
356347
{
357348
std::ifstream is(filename, std::ios_base::binary);
358349
if (!is.good()) {
@@ -361,30 +352,31 @@ bool Schematic::loadSchematicFromFile(const char *filename,
361352
return false;
362353
}
363354

364-
std::vector<std::string> names;
365-
if (!deserializeFromMts(&is, ndef, &names))
355+
size_t origsize = m_nodenames.size();
356+
if (!deserializeFromMts(&is, &m_nodenames))
366357
return false;
367358

368-
NodeResolveInfo *nri = new NodeResolveInfo(this);
369-
for (size_t i = 0; i != names.size(); i++) {
370-
if (replace_names) {
371-
StringMap::iterator it = replace_names->find(names[i]);
359+
if (replace_names) {
360+
for (size_t i = origsize; i != m_nodenames.size(); i++) {
361+
std::string &name = m_nodenames[i];
362+
StringMap::iterator it = replace_names->find(name);
372363
if (it != replace_names->end())
373-
names[i] = it->second;
364+
name = it->second;
374365
}
375-
nri->nodenames.push_back(names[i]);
376366
}
377-
nri->nodelistinfo.push_back(NodeListInfo(names.size(), CONTENT_AIR));
378-
ndef->pendNodeResolve(nri);
367+
368+
m_nnlistsizes.push_back(m_nodenames.size() - origsize);
369+
370+
ndef->pendNodeResolve(this, resolve_method);
379371

380372
return true;
381373
}
382374

383375

384-
bool Schematic::saveSchematicToFile(const char *filename, INodeDefManager *ndef)
376+
bool Schematic::saveSchematicToFile(const std::string &filename)
385377
{
386378
std::ostringstream os(std::ios_base::binary);
387-
serializeToMts(&os, ndef);
379+
serializeToMts(&os);
388380
return fs::safeWriteToFile(filename, os.str());
389381
}
390382

Diff for: ‎src/mg_schematic.h

+7-11
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,28 @@ class Schematic : public ObjDef, public NodeResolver {
9494
Schematic();
9595
virtual ~Schematic();
9696

97-
virtual void resolveNodeNames(NodeResolveInfo *nri);
97+
virtual void resolveNodeNames();
9898

9999
void updateContentIds();
100100

101101
void blitToVManip(v3s16 p, MMVManip *vm,
102102
Rotation rot, bool force_placement, INodeDefManager *ndef);
103103

104-
bool loadSchematicFromFile(const char *filename, INodeDefManager *ndef,
105-
StringMap *replace_names);
106-
bool saveSchematicToFile(const char *filename, INodeDefManager *ndef);
104+
bool loadSchematicFromFile(const std::string &filename, INodeDefManager *ndef,
105+
StringMap *replace_names, NodeResolveMethod resolve_method);
106+
bool saveSchematicToFile(const std::string &filename);
107107
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
108108

109-
bool deserializeFromMts(std::istream *is, INodeDefManager *ndef,
110-
std::vector<std::string> *names);
111-
bool serializeToMts(std::ostream *os, INodeDefManager *ndef);
112-
bool serializeToLua(std::ostream *os,
113-
INodeDefManager *ndef, bool use_comments);
109+
bool deserializeFromMts(std::istream *is, std::vector<std::string> *names_out);
110+
bool serializeToMts(std::ostream *os);
111+
bool serializeToLua(std::ostream *os, bool use_comments);
114112

115113

116114
void placeStructure(Map *map, v3s16 p, u32 flags,
117115
Rotation rot, bool force_placement, INodeDefManager *nef);
118116
void applyProbabilities(v3s16 p0,
119117
std::vector<std::pair<v3s16, u8> > *plist,
120118
std::vector<std::pair<s16, u8> > *splist);
121-
122-
std::string getAsLuaTable(INodeDefManager *ndef, bool use_comments);
123119
};
124120

125121
class SchematicManager : public ObjDefManager {

0 commit comments

Comments
 (0)
Please sign in to comment.