Skip to content

Commit

Permalink
NodeResolver: Remove NodeResolveMethod
Browse files Browse the repository at this point in the history
This simplifies NodeResolver logic and makes some interfaces cleaner.
  • Loading branch information
kwolekr committed May 7, 2015
1 parent d720fd5 commit 656575b
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 169 deletions.
9 changes: 0 additions & 9 deletions doc/lua_api.txt
Expand Up @@ -2180,15 +2180,6 @@ These functions return the leftover itemstack.
* `options` is a table containing the following optional parameters:
* If `use_comments` is true and `format` is "lua", the Lua code generated will have (X, Z)
* position comments for every X row generated in the schematic data for easier reading.
* If `register_after_load` is true, then `schematic`, if not yet loaded, will be registered
* after loading and persist in memory.
* node_resolve_method can be one of either "none", "direct", or "deferred" (default: "none")
* This sets the way method by with node names are mapped to their content IDs, if loaded:
* "none" performs no node resolution and preserves all node names from the schematic definition
* "direct" performs an immediate lookup of content ID, given all the nodes that have been
* registered up to this point in script execution
* "deferred" pends node resolution until after the script registration phase has ended
* In practice, it is recommended to use "none" in nearly all use cases.

### Misc.
* `minetest.get_connected_players()`: returns list of `ObjectRefs`
Expand Down
2 changes: 1 addition & 1 deletion src/mg_biome.cpp
Expand Up @@ -57,7 +57,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef) :
b->m_nodenames.push_back("mapgen_water_source");
b->m_nodenames.push_back("mapgen_river_water_source");
b->m_nodenames.push_back("air");
m_ndef->pendNodeResolve(b, NODE_RESOLVE_DEFERRED);
m_ndef->pendNodeResolve(b);

add(b);
}
Expand Down
2 changes: 1 addition & 1 deletion src/mg_decoration.cpp
Expand Up @@ -340,7 +340,7 @@ size_t DecoSchematic::generate(MMVManip *vm, PseudoRandom *pr, v3s16 p)

bool force_placement = (flags & DECO_FORCE_PLACEMENT);

schematic->blitToVManip(p, vm, rot, force_placement, m_ndef);
schematic->blitToVManip(p, vm, rot, force_placement);

return 1;
}
Expand Down
81 changes: 54 additions & 27 deletions src/mg_schematic.cpp
Expand Up @@ -94,9 +94,11 @@ void Schematic::resolveNodeNames()
}


void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot,
bool force_placement, INodeDefManager *ndef)
void Schematic::blitToVManip(v3s16 p, MMVManip *vm,
Rotation rot, bool force_placement)
{
sanity_check(m_ndef != NULL);

int xstride = 1;
int ystride = size.X;
int zstride = size.X * size.Y;
Expand Down Expand Up @@ -163,18 +165,20 @@ void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot,
vm->m_data[vi].param1 = 0;

if (rot)
vm->m_data[vi].rotateAlongYAxis(ndef, rot);
vm->m_data[vi].rotateAlongYAxis(m_ndef, rot);
}
}
y_map++;
}
}


void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
bool force_placement, INodeDefManager *ndef)
void Schematic::placeStructure(Map *map, v3s16 p, u32 flags,
Rotation rot, bool force_placement)
{
assert(schemdata != NULL); // Pre-condition
sanity_check(m_ndef != NULL);

MMVManip *vm = new MMVManip(map);

if (rot == ROTATE_RAND)
Expand All @@ -194,7 +198,7 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
v3s16 bp2 = getNodeBlockPos(p + s - v3s16(1,1,1));
vm->initialEmerge(bp1, bp2);

blitToVManip(p, vm, rot, force_placement, ndef);
blitToVManip(p, vm, rot, force_placement);

std::map<v3s16, MapBlock *> lighting_modified_blocks;
std::map<v3s16, MapBlock *> modified_blocks;
Expand All @@ -215,7 +219,8 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
}


bool Schematic::deserializeFromMts(std::istream *is, std::vector<std::string> *names)
bool Schematic::deserializeFromMts(std::istream *is,
std::vector<std::string> *names)
{
std::istream &ss = *is;
content_t cignore = CONTENT_IGNORE;
Expand Down Expand Up @@ -279,7 +284,8 @@ bool Schematic::deserializeFromMts(std::istream *is, std::vector<std::string> *n
}


bool Schematic::serializeToMts(std::ostream *os)
bool Schematic::serializeToMts(std::ostream *os,
const std::vector<std::string> &names)
{
std::ostream &ss = *os;

Expand All @@ -290,24 +296,20 @@ bool Schematic::serializeToMts(std::ostream *os)
for (int y = 0; y != size.Y; y++) // Y slice probabilities
writeU8(ss, slice_probs[y]);

std::vector<content_t> usednodes;
int nodecount = size.X * size.Y * size.Z;
build_nnlist_and_update_ids(schemdata, nodecount, &usednodes);

u16 numids = usednodes.size();
writeU16(ss, numids); // name count
for (int i = 0; i != numids; i++)
ss << serializeString(getNodeName(usednodes[i])); // node names
writeU16(ss, names.size()); // name count
for (size_t i = 0; i != names.size(); i++)
ss << serializeString(names[i]); // node names

// compressed bulk node data
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE,
schemdata, nodecount, 2, 2, true);
schemdata, size.X * size.Y * size.Z, 2, 2, true);

return true;
}


bool Schematic::serializeToLua(std::ostream *os, bool use_comments)
bool Schematic::serializeToLua(std::ostream *os,
const std::vector<std::string> &names, bool use_comments)
{
std::ostream &ss = *os;

Expand Down Expand Up @@ -350,7 +352,7 @@ bool Schematic::serializeToLua(std::ostream *os, bool use_comments)

for (u16 x = 0; x != size.X; x++, i++) {
ss << "\t\t{"
<< "name=\"" << getNodeName(schemdata[i].getContent())
<< "name=\"" << names[schemdata[i].getContent()]
<< "\", param1=" << (u16)schemdata[i].param1
<< ", param2=" << (u16)schemdata[i].param2
<< "}," << std::endl;
Expand All @@ -367,8 +369,7 @@ bool Schematic::serializeToLua(std::ostream *os, bool use_comments)


bool Schematic::loadSchematicFromFile(const std::string &filename,
INodeDefManager *ndef, StringMap *replace_names,
NodeResolveMethod resolve_method)
INodeDefManager *ndef, StringMap *replace_names)
{
std::ifstream is(filename.c_str(), std::ios_base::binary);
if (!is.good()) {
Expand All @@ -392,16 +393,42 @@ bool Schematic::loadSchematicFromFile(const std::string &filename,

m_nnlistsizes.push_back(m_nodenames.size() - origsize);

ndef->pendNodeResolve(this, resolve_method);
if (ndef)
ndef->pendNodeResolve(this);

return true;
}


bool Schematic::saveSchematicToFile(const std::string &filename)
{
MapNode *orig_schemdata = schemdata;
std::vector<std::string> ndef_nodenames;
std::vector<std::string> *names;

// Only carry out the modification if we know the nodes
// were resolved at this point
if (m_resolve_done) {
names = &ndef_nodenames;

u32 volume = size.X * size.Y * size.Z;
schemdata = new MapNode[volume];
for (u32 i = 0; i != volume; i++)
schemdata[i] = orig_schemdata[i];

generate_nodelist_and_update_ids(schemdata, volume, names, m_ndef);
} else { // otherwise, use the names we have on hand in the list
names = &m_nodenames;
}

std::ostringstream os(std::ios_base::binary);
serializeToMts(&os);
serializeToMts(&os, *names);

if (m_resolve_done) {
delete []schemdata;
schemdata = orig_schemdata;
}

return fs::safeWriteToFile(filename, os.str());
}

Expand Down Expand Up @@ -461,13 +488,13 @@ void Schematic::applyProbabilities(v3s16 p0,
}


void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
std::vector<content_t> *usednodes)
void generate_nodelist_and_update_ids(MapNode *nodes, size_t nodecount,
std::vector<std::string> *usednodes, INodeDefManager *ndef)
{
std::map<content_t, content_t> nodeidmap;
content_t numids = 0;

for (u32 i = 0; i != nodecount; i++) {
for (size_t i = 0; i != nodecount; i++) {
content_t id;
content_t c = nodes[i].getContent();

Expand All @@ -476,7 +503,7 @@ void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
id = numids;
numids++;

usednodes->push_back(c);
usednodes->push_back(ndef->get(c).name);
nodeidmap.insert(std::make_pair(c, id));
} else {
id = it->second;
Expand Down
19 changes: 9 additions & 10 deletions src/mg_schematic.h
Expand Up @@ -100,20 +100,20 @@ class Schematic : public ObjDef, public NodeResolver {
void updateContentIds();

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

bool loadSchematicFromFile(const std::string &filename, INodeDefManager *ndef,
StringMap *replace_names, NodeResolveMethod resolve_method);
StringMap *replace_names);
bool saveSchematicToFile(const std::string &filename);
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);

bool deserializeFromMts(std::istream *is, std::vector<std::string> *names_out);
bool serializeToMts(std::ostream *os);
bool serializeToLua(std::ostream *os, bool use_comments);

bool deserializeFromMts(std::istream *is, std::vector<std::string> *names);
bool serializeToMts(std::ostream *os, const std::vector<std::string> &names);
bool serializeToLua(std::ostream *os, const std::vector<std::string> &names,
bool use_comments);

void placeStructure(Map *map, v3s16 p, u32 flags,
Rotation rot, bool force_placement, INodeDefManager *nef);
Rotation rot, bool force_placement);
void applyProbabilities(v3s16 p0,
std::vector<std::pair<v3s16, u8> > *plist,
std::vector<std::pair<s16, u8> > *splist);
Expand All @@ -140,8 +140,7 @@ class SchematicManager : public ObjDefManager {
IGameDef *m_gamedef;
};

void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
std::vector<content_t> *usednodes);

void generate_nodelist_and_update_ids(MapNode *nodes, size_t nodecount,
std::vector<std::string> *usednodes, INodeDefManager *ndef);

#endif
33 changes: 5 additions & 28 deletions src/nodedef.cpp
Expand Up @@ -406,7 +406,7 @@ class CNodeDefManager: public IWritableNodeDefManager {
inline virtual bool getNodeRegistrationStatus() const;
inline virtual void setNodeRegistrationStatus(bool completed);

virtual void pendNodeResolve(NodeResolver *nr, NodeResolveMethod how);
virtual void pendNodeResolve(NodeResolver *nr);
virtual bool cancelNodeResolveCallback(NodeResolver *nr);
virtual void runNodeResolveCallbacks();
virtual void resetNodeResolveState();
Expand Down Expand Up @@ -1294,23 +1294,13 @@ inline void CNodeDefManager::setNodeRegistrationStatus(bool completed)
}


void CNodeDefManager::pendNodeResolve(NodeResolver *nr, NodeResolveMethod how)
void CNodeDefManager::pendNodeResolve(NodeResolver *nr)
{
nr->m_ndef = this;

switch (how) {
case NODE_RESOLVE_NONE:
break;
case NODE_RESOLVE_DIRECT:
if (m_node_registration_complete)
nr->nodeResolveInternal();
break;
case NODE_RESOLVE_DEFERRED:
if (m_node_registration_complete)
nr->nodeResolveInternal();
else
m_pending_resolve_callbacks.push_back(nr);
break;
}
else
m_pending_resolve_callbacks.push_back(nr);
}


Expand Down Expand Up @@ -1385,19 +1375,6 @@ void NodeResolver::nodeResolveInternal()
}


const std::string &NodeResolver::getNodeName(content_t c) const
{
if (c < m_nodenames.size())
return m_nodenames[c];

if (m_ndef)
return m_ndef->get(c).name;

static const std::string unknown_str("unknown");
return unknown_str;
}


bool NodeResolver::getIdFromNrBacklog(content_t *result_out,
const std::string &node_alt, content_t c_fallback)
{
Expand Down
11 changes: 2 additions & 9 deletions src/nodedef.h
Expand Up @@ -282,12 +282,6 @@ struct ContentFeatures
}
};

enum NodeResolveMethod {
NODE_RESOLVE_NONE,
NODE_RESOLVE_DIRECT,
NODE_RESOLVE_DEFERRED,
};

class INodeDefManager {
public:
INodeDefManager(){}
Expand All @@ -306,7 +300,7 @@ class INodeDefManager {

virtual bool getNodeRegistrationStatus() const=0;

virtual void pendNodeResolve(NodeResolver *nr, NodeResolveMethod how)=0;
virtual void pendNodeResolve(NodeResolver *nr)=0;
virtual bool cancelNodeResolveCallback(NodeResolver *nr)=0;
};

Expand Down Expand Up @@ -353,7 +347,7 @@ class IWritableNodeDefManager : public INodeDefManager {
virtual bool getNodeRegistrationStatus() const=0;
virtual void setNodeRegistrationStatus(bool completed)=0;

virtual void pendNodeResolve(NodeResolver *nr, NodeResolveMethod how)=0;
virtual void pendNodeResolve(NodeResolver *nr)=0;
virtual bool cancelNodeResolveCallback(NodeResolver *nr)=0;
virtual void runNodeResolveCallbacks()=0;
virtual void resetNodeResolveState()=0;
Expand All @@ -371,7 +365,6 @@ class NodeResolver {
const std::string &node_alt, content_t c_fallback);
bool getIdsFromNrBacklog(std::vector<content_t> *result_out,
bool all_required=false, content_t c_fallback=CONTENT_IGNORE);
const std::string &getNodeName(content_t c) const;

void nodeResolveInternal();

Expand Down

0 comments on commit 656575b

Please sign in to comment.