Skip to content

Commit

Permalink
Make INodeDefManager::getIds return a vector, not a set
Browse files Browse the repository at this point in the history
  • Loading branch information
kahrl authored and sfan5 committed Sep 12, 2017
1 parent 5b3fbf9 commit 17fd5fe
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 83 deletions.
61 changes: 20 additions & 41 deletions src/nodedef.cpp
Expand Up @@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h" #include "gamedef.h"
#include "mapnode.h" #include "mapnode.h"
#include <fstream> // Used in applyTextureOverrides() #include <fstream> // Used in applyTextureOverrides()
#include <algorithm>


/* /*
NodeBox NodeBox
Expand Down Expand Up @@ -485,7 +486,7 @@ void ContentFeatures::deSerialize(std::istream &is)
u16 connects_to_size = readU16(is); u16 connects_to_size = readU16(is);
connects_to_ids.clear(); connects_to_ids.clear();
for (u16 i = 0; i < connects_to_size; i++) for (u16 i = 0; i < connects_to_size; i++)
connects_to_ids.insert(readU16(is)); connects_to_ids.push_back(readU16(is));
post_effect_color.setAlpha(readU8(is)); post_effect_color.setAlpha(readU8(is));
post_effect_color.setRed(readU8(is)); post_effect_color.setRed(readU8(is));
post_effect_color.setGreen(readU8(is)); post_effect_color.setGreen(readU8(is));
Expand Down Expand Up @@ -845,7 +846,7 @@ class CNodeDefManager: public IWritableNodeDefManager {
inline virtual const ContentFeatures& get(const MapNode &n) const; inline virtual const ContentFeatures& get(const MapNode &n) const;
virtual bool getId(const std::string &name, content_t &result) const; virtual bool getId(const std::string &name, content_t &result) const;
virtual content_t getId(const std::string &name) const; virtual content_t getId(const std::string &name) const;
virtual bool getIds(const std::string &name, std::set<content_t> &result) const; virtual bool getIds(const std::string &name, std::vector<content_t> &result) const;
virtual const ContentFeatures& get(const std::string &name) const; virtual const ContentFeatures& get(const std::string &name) const;
content_t allocateId(); content_t allocateId();
virtual content_t set(const std::string &name, const ContentFeatures &def); virtual content_t set(const std::string &name, const ContentFeatures &def);
Expand Down Expand Up @@ -892,10 +893,10 @@ class CNodeDefManager: public IWritableNodeDefManager {


std::unordered_map<std::string, content_t> m_name_id_mapping_with_aliases; std::unordered_map<std::string, content_t> m_name_id_mapping_with_aliases;


// A mapping from groups to a list of content_ts (and their levels) // A mapping from groups to a vector of content_ts that belong to it.
// that belong to it. Necessary for a direct lookup in getIds(). // Necessary for a direct lookup in getIds().
// Note: Not serialized. // Note: Not serialized.
std::unordered_map<std::string, GroupItems> m_group_to_items; std::unordered_map<std::string, std::vector<content_t>> m_group_to_items;


// Next possibly free id // Next possibly free id
content_t m_next_id; content_t m_next_id;
Expand Down Expand Up @@ -1037,28 +1038,25 @@ content_t CNodeDefManager::getId(const std::string &name) const




bool CNodeDefManager::getIds(const std::string &name, bool CNodeDefManager::getIds(const std::string &name,
std::set<content_t> &result) const std::vector<content_t> &result) const
{ {
//TimeTaker t("getIds", NULL, PRECISION_MICRO); //TimeTaker t("getIds", NULL, PRECISION_MICRO);
if (name.substr(0,6) != "group:") { if (name.substr(0,6) != "group:") {
content_t id = CONTENT_IGNORE; content_t id = CONTENT_IGNORE;
bool exists = getId(name, id); bool exists = getId(name, id);
if (exists) if (exists)
result.insert(id); result.push_back(id);
return exists; return exists;
} }
std::string group = name.substr(6); std::string group = name.substr(6);


std::unordered_map<std::string, GroupItems>::const_iterator std::unordered_map<std::string, std::vector<content_t>>::const_iterator
i = m_group_to_items.find(group); i = m_group_to_items.find(group);
if (i == m_group_to_items.end()) if (i == m_group_to_items.end())
return true; return true;


const GroupItems &items = i->second; const std::vector<content_t> &items = i->second;
for (const auto &item : items) { result.insert(result.end(), items.begin(), items.end());
if (item.second != 0)
result.insert(item.first);
}
//printf("getIds: %dus\n", t.stop()); //printf("getIds: %dus\n", t.stop());
return true; return true;
} }
Expand Down Expand Up @@ -1247,15 +1245,7 @@ content_t CNodeDefManager::set(const std::string &name, const ContentFeatures &d
// belongs to when a node is re-registered // belongs to when a node is re-registered
for (const auto &group : def.groups) { for (const auto &group : def.groups) {
const std::string &group_name = group.first; const std::string &group_name = group.first;

m_group_to_items[group_name].push_back(id);
std::unordered_map<std::string, GroupItems>::iterator
j = m_group_to_items.find(group_name);
if (j == m_group_to_items.end()) {
m_group_to_items[group_name].emplace_back(id, group.second);
} else {
GroupItems &items = j->second;
items.emplace_back(id, group.second);
}
} }
return id; return id;
} }
Expand Down Expand Up @@ -1283,16 +1273,10 @@ void CNodeDefManager::removeNode(const std::string &name)
} }


// Erase node content from all groups it belongs to // Erase node content from all groups it belongs to
for (std::unordered_map<std::string, GroupItems>::iterator iter_groups = for (std::unordered_map<std::string, std::vector<content_t>>::iterator iter_groups =
m_group_to_items.begin(); iter_groups != m_group_to_items.end();) { m_group_to_items.begin(); iter_groups != m_group_to_items.end();) {
GroupItems &items = iter_groups->second; std::vector<content_t> &items = iter_groups->second;
for (GroupItems::iterator iter_groupitems = items.begin(); items.erase(std::remove(items.begin(), items.end(), id), items.end());
iter_groupitems != items.end();) {
if (iter_groupitems->first == id)
items.erase(iter_groupitems++);
else
++iter_groupitems;
}


// Check if group is empty // Check if group is empty
if (items.empty()) if (items.empty())
Expand Down Expand Up @@ -1545,9 +1529,8 @@ void CNodeDefManager::mapNodeboxConnections()
if (f.drawtype != NDT_NODEBOX || f.node_box.type != NODEBOX_CONNECTED) if (f.drawtype != NDT_NODEBOX || f.node_box.type != NODEBOX_CONNECTED)
continue; continue;


for (std::vector<std::string>::const_iterator it = f.connects_to.begin(); for (const std::string &name : f.connects_to) {
it != f.connects_to.end(); ++it) { getIds(name, f.connects_to_ids);
getIds(*it, f.connects_to_ids);
} }
} }
} }
Expand All @@ -1560,14 +1543,14 @@ bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to, u8 connect_face)
return false; return false;


// lookup target in connected set // lookup target in connected set
if (f1.connects_to_ids.find(to.param0) == f1.connects_to_ids.end()) if (!CONTAINS(f1.connects_to_ids, to.param0))
return false; return false;


const ContentFeatures &f2 = get(to); const ContentFeatures &f2 = get(to);


if ((f2.drawtype == NDT_NODEBOX) && (f2.node_box.type == NODEBOX_CONNECTED)) if ((f2.drawtype == NDT_NODEBOX) && (f2.node_box.type == NODEBOX_CONNECTED))
// ignores actually looking if back connection exists // ignores actually looking if back connection exists
return (f2.connects_to_ids.find(from.param0) != f2.connects_to_ids.end()); return CONTAINS(f2.connects_to_ids, from.param0);


// does to node declare usable faces? // does to node declare usable faces?
if (f2.connect_sides > 0) { if (f2.connect_sides > 0) {
Expand Down Expand Up @@ -1686,11 +1669,7 @@ bool NodeResolver::getIdsFromNrBacklog(std::vector<content_t> *result_out,
success = false; success = false;
} }
} else { } else {
std::set<content_t> cids; m_ndef->getIds(name, *result_out);
std::set<content_t>::iterator it;
m_ndef->getIds(name, cids);
for (it = cids.begin(); it != cids.end(); ++it)
result_out->push_back(*it);
} }
} }


Expand Down
9 changes: 3 additions & 6 deletions src/nodedef.h
Expand Up @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <list>
#include "mapnode.h" #include "mapnode.h"
#ifndef SERVER #ifndef SERVER
#include "client/tile.h" #include "client/tile.h"
Expand All @@ -42,8 +41,6 @@ class IShaderSource;
class IGameDef; class IGameDef;
class NodeResolver; class NodeResolver;


typedef std::list<std::pair<content_t, int> > GroupItems;

enum ContentParamType enum ContentParamType
{ {
CPT_NONE, CPT_NONE,
Expand Down Expand Up @@ -290,7 +287,7 @@ struct ContentFeatures
// for NDT_CONNECTED pairing // for NDT_CONNECTED pairing
u8 connect_sides; u8 connect_sides;
std::vector<std::string> connects_to; std::vector<std::string> connects_to;
std::set<content_t> connects_to_ids; std::vector<content_t> connects_to_ids;
// Post effect color, drawn when the camera is inside the node. // Post effect color, drawn when the camera is inside the node.
video::SColor post_effect_color; video::SColor post_effect_color;
// Flowing liquid or snow, value = default level // Flowing liquid or snow, value = default level
Expand Down Expand Up @@ -424,7 +421,7 @@ class INodeDefManager {
virtual content_t getId(const std::string &name) const=0; virtual content_t getId(const std::string &name) const=0;
// Allows "group:name" in addition to regular node names // Allows "group:name" in addition to regular node names
// returns false if node name not found, true otherwise // returns false if node name not found, true otherwise
virtual bool getIds(const std::string &name, std::set<content_t> &result) virtual bool getIds(const std::string &name, std::vector<content_t> &result)
const=0; const=0;
virtual const ContentFeatures &get(const std::string &name) const=0; virtual const ContentFeatures &get(const std::string &name) const=0;


Expand Down Expand Up @@ -452,7 +449,7 @@ class IWritableNodeDefManager : public INodeDefManager {
// If not found, returns CONTENT_IGNORE // If not found, returns CONTENT_IGNORE
virtual content_t getId(const std::string &name) const=0; virtual content_t getId(const std::string &name) const=0;
// Allows "group:name" in addition to regular node names // Allows "group:name" in addition to regular node names
virtual bool getIds(const std::string &name, std::set<content_t> &result) virtual bool getIds(const std::string &name, std::vector<content_t> &result)
const=0; const=0;
// If not found, returns the features of CONTENT_UNKNOWN // If not found, returns the features of CONTENT_UNKNOWN
virtual const ContentFeatures &get(const std::string &name) const=0; virtual const ContentFeatures &get(const std::string &name) const=0;
Expand Down
12 changes: 6 additions & 6 deletions src/script/cpp_api/s_env.cpp
Expand Up @@ -108,37 +108,37 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
int id = lua_tonumber(L, -2); int id = lua_tonumber(L, -2);
int current_abm = lua_gettop(L); int current_abm = lua_gettop(L);


std::set<std::string> trigger_contents; std::vector<std::string> trigger_contents;
lua_getfield(L, current_abm, "nodenames"); lua_getfield(L, current_abm, "nodenames");
if (lua_istable(L, -1)) { if (lua_istable(L, -1)) {
int table = lua_gettop(L); int table = lua_gettop(L);
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, table)) { while (lua_next(L, table)) {
// key at index -2 and value at index -1 // key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING); luaL_checktype(L, -1, LUA_TSTRING);
trigger_contents.insert(lua_tostring(L, -1)); trigger_contents.push_back(lua_tostring(L, -1));
// removes value, keeps key for next iteration // removes value, keeps key for next iteration
lua_pop(L, 1); lua_pop(L, 1);
} }
} else if (lua_isstring(L, -1)) { } else if (lua_isstring(L, -1)) {
trigger_contents.insert(lua_tostring(L, -1)); trigger_contents.push_back(lua_tostring(L, -1));
} }
lua_pop(L, 1); lua_pop(L, 1);


std::set<std::string> required_neighbors; std::vector<std::string> required_neighbors;
lua_getfield(L, current_abm, "neighbors"); lua_getfield(L, current_abm, "neighbors");
if (lua_istable(L, -1)) { if (lua_istable(L, -1)) {
int table = lua_gettop(L); int table = lua_gettop(L);
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, table)) { while (lua_next(L, table)) {
// key at index -2 and value at index -1 // key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING); luaL_checktype(L, -1, LUA_TSTRING);
required_neighbors.insert(lua_tostring(L, -1)); required_neighbors.push_back(lua_tostring(L, -1));
// removes value, keeps key for next iteration // removes value, keeps key for next iteration
lua_pop(L, 1); lua_pop(L, 1);
} }
} else if (lua_isstring(L, -1)) { } else if (lua_isstring(L, -1)) {
required_neighbors.insert(lua_tostring(L, -1)); required_neighbors.push_back(lua_tostring(L, -1));
} }
lua_pop(L, 1); lua_pop(L, 1);


Expand Down
27 changes: 16 additions & 11 deletions src/script/lua_api/l_env.cpp
Expand Up @@ -719,7 +719,7 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
INodeDefManager *ndef = getGameDef(L)->ndef(); INodeDefManager *ndef = getGameDef(L)->ndef();
v3s16 pos = read_v3s16(L, 1); v3s16 pos = read_v3s16(L, 1);
int radius = luaL_checkinteger(L, 2); int radius = luaL_checkinteger(L, 2);
std::set<content_t> filter; std::vector<content_t> filter;
if (lua_istable(L, 3)) { if (lua_istable(L, 3)) {
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, 3) != 0) { while (lua_next(L, 3) != 0) {
Expand Down Expand Up @@ -748,7 +748,7 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
for (const v3s16 &i : list) { for (const v3s16 &i : list) {
v3s16 p = pos + i; v3s16 p = pos + i;
content_t c = env->getMap().getNodeNoEx(p).getContent(); content_t c = env->getMap().getNodeNoEx(p).getContent();
if (filter.count(c) != 0) { if (CONTAINS(filter, c)) {
push_v3s16(L, p); push_v3s16(L, p);
return 1; return 1;
} }
Expand Down Expand Up @@ -780,7 +780,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
return 0; return 0;
} }


std::set<content_t> filter; std::vector<content_t> filter;
if (lua_istable(L, 3)) { if (lua_istable(L, 3)) {
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, 3) != 0) { while (lua_next(L, 3) != 0) {
Expand All @@ -794,7 +794,8 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
ndef->getIds(lua_tostring(L, 3), filter); ndef->getIds(lua_tostring(L, 3), filter);
} }


std::unordered_map<content_t, u32> individual_count; std::vector<u32> individual_count;
individual_count.resize(filter.size());


lua_newtable(L); lua_newtable(L);
u64 i = 0; u64 i = 0;
Expand All @@ -803,16 +804,20 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
for (s16 z = minp.Z; z <= maxp.Z; z++) { for (s16 z = minp.Z; z <= maxp.Z; z++) {
v3s16 p(x, y, z); v3s16 p(x, y, z);
content_t c = env->getMap().getNodeNoEx(p).getContent(); content_t c = env->getMap().getNodeNoEx(p).getContent();
if (filter.count(c) != 0) {
std::vector<content_t>::iterator it = std::find(filter.begin(), filter.end(), c);
if (it != filter.end()) {
push_v3s16(L, p); push_v3s16(L, p);
lua_rawseti(L, -2, ++i); lua_rawseti(L, -2, ++i);
individual_count[c]++;
u32 filt_index = it - filter.begin();
individual_count[filt_index]++;
} }
} }
lua_newtable(L); lua_newtable(L);
for (content_t it : filter) { for (u32 i = 0; i < filter.size(); i++) {
lua_pushnumber(L, individual_count[it]); lua_pushnumber(L, individual_count[i]);
lua_setfield(L, -2, ndef->get(it).name.c_str()); lua_setfield(L, -2, ndef->get(filter[i]).name.c_str());
} }
return 2; return 2;
} }
Expand Down Expand Up @@ -847,7 +852,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
return 0; return 0;
} }


std::set<content_t> filter; std::vector<content_t> filter;


if (lua_istable(L, 3)) { if (lua_istable(L, 3)) {
lua_pushnil(L); lua_pushnil(L);
Expand All @@ -873,7 +878,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
v3s16 psurf(x, y + 1, z); v3s16 psurf(x, y + 1, z);
content_t csurf = env->getMap().getNodeNoEx(psurf).getContent(); content_t csurf = env->getMap().getNodeNoEx(psurf).getContent();
if (c != CONTENT_AIR && csurf == CONTENT_AIR && if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
filter.count(c) != 0) { CONTAINS(filter, c)) {
push_v3s16(L, v3s16(x, y, z)); push_v3s16(L, v3s16(x, y, z));
lua_rawseti(L, -2, ++i); lua_rawseti(L, -2, ++i);
} }
Expand Down
12 changes: 6 additions & 6 deletions src/script/lua_api/l_env.h
Expand Up @@ -188,15 +188,15 @@ class LuaABM : public ActiveBlockModifier {
private: private:
int m_id; int m_id;


std::set<std::string> m_trigger_contents; std::vector<std::string> m_trigger_contents;
std::set<std::string> m_required_neighbors; std::vector<std::string> m_required_neighbors;
float m_trigger_interval; float m_trigger_interval;
u32 m_trigger_chance; u32 m_trigger_chance;
bool m_simple_catch_up; bool m_simple_catch_up;
public: public:
LuaABM(lua_State *L, int id, LuaABM(lua_State *L, int id,
const std::set<std::string> &trigger_contents, const std::vector<std::string> &trigger_contents,
const std::set<std::string> &required_neighbors, const std::vector<std::string> &required_neighbors,
float trigger_interval, u32 trigger_chance, bool simple_catch_up): float trigger_interval, u32 trigger_chance, bool simple_catch_up):
m_id(id), m_id(id),
m_trigger_contents(trigger_contents), m_trigger_contents(trigger_contents),
Expand All @@ -206,11 +206,11 @@ class LuaABM : public ActiveBlockModifier {
m_simple_catch_up(simple_catch_up) m_simple_catch_up(simple_catch_up)
{ {
} }
virtual const std::set<std::string> &getTriggerContents() const virtual const std::vector<std::string> &getTriggerContents() const
{ {
return m_trigger_contents; return m_trigger_contents;
} }
virtual const std::set<std::string> &getRequiredNeighbors() const virtual const std::vector<std::string> &getRequiredNeighbors() const
{ {
return m_required_neighbors; return m_required_neighbors;
} }
Expand Down

0 comments on commit 17fd5fe

Please sign in to comment.