diff options
Diffstat (limited to 'src/nodedef.cpp')
-rw-r--r-- | src/nodedef.cpp | 211 |
1 files changed, 73 insertions, 138 deletions
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; } |