diff options
-rw-r--r-- | src/nodedef.cpp | 15 | ||||
-rw-r--r-- | src/nodedef.h | 86 |
2 files changed, 97 insertions, 4 deletions
diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 3fc9bbc11..820f4eb30 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1282,11 +1282,12 @@ int NodeResolver::addNode(std::string n_wanted, std::string n_alt, if (m_ndef->getId(n_wanted, *content)) return NR_STATUS_SUCCESS; - if (n_alt == "") + if (n_alt == "" || !m_ndef->getId(n_alt, *content)) { + *content = c_fallback; return NR_STATUS_FAILURE; + } - return m_ndef->getId(n_alt, *content) ? - NR_STATUS_SUCCESS : NR_STATUS_FAILURE; + return NR_STATUS_SUCCESS; } else { NodeResolveInfo *nfi = new NodeResolveInfo; nfi->n_wanted = n_wanted; @@ -1378,7 +1379,7 @@ int NodeResolver::resolveNodes() "resolve '" << nri->n_wanted; if (nri->n_alt != "") errorstream << "' and '" << nri->n_alt; - errorstream << "' to a content ID" << std::endl; + errorstream << "'" << std::endl; } delete nri; @@ -1399,6 +1400,12 @@ int NodeResolver::resolveNodes() m_ndef->getIds(name, idset); for (it = idset.begin(); it != idset.end(); ++it) output->push_back(*it); + + if (idset.size() == 0) { + num_failed++; + errorstream << "NodeResolver::resolveNodes(): Failed to " + "resolve '" << name << "'" << std::endl; + } } //// Mark node registration as complete so future resolve diff --git a/src/nodedef.h b/src/nodedef.h index bd29b92b6..489aefffd 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -293,20 +293,106 @@ struct NodeResolveInfo { #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(std::string n_wanted, 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 char *nodename, std::vector<content_t> *content_vec); + /** + Removes all pending requests from the resolution queue to be satisfied + to 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 to be satisfied + to 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. + + @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; } private: |