MCPcopy Create free account
hub / github.com/DFHack/dfhack / add

Method add

plugins/channel-safely/channel-groups.cpp:77–153  ·  view source on GitHub ↗

adds map_pos to a group if an adjacent one exists, or creates one if none exist... if multiple exist they're merged into the first found

Source from the content-addressed store, hash-verified

75
76// adds map_pos to a group if an adjacent one exists, or creates one if none exist... if multiple exist they're merged into the first found
77void ChannelGroups::add(const df::coord &map_pos) {
78 // if we've already added this, we don't need to do it again
79 if (groups_map.count(map_pos)) {
80 return;
81 }
82 /* We need to add map_pos to an existing group if possible...
83 * So what we do is we look at neighbours to see if they belong to one or more existing groups
84 * If there is more than one group, we'll be merging them
85 */
86 df::coord neighbors[8];
87 get_neighbours(map_pos, neighbors);
88 Group* group = nullptr;
89 int group_index = -1;
90
91 DEBUG(groups).print(" add(" COORD ")\n", COORDARGS(map_pos));
92 // and so we begin iterating the neighbours
93 for (auto &neighbour: neighbors) {
94 if unlikely(!Maps::isValidTilePos(neighbour)) continue;
95 // go to the next neighbour if this one doesn't have a group
96 if (!groups_map.count(neighbour)) {
97 TRACE(groups).print(" -> neighbour is not designated\n");
98 continue;
99 }
100 // get the group, since at least one exists... then merge any additional into that one
101 if (!group){
102 TRACE(groups).print(" -> group* has no valid state yet\n");
103 group_index = groups_map.find(neighbour)->second;
104 group = &groups.at(group_index);
105 } else {
106 TRACE(groups).print(" -> group* has an existing state\n");
107
108 // we don't do anything if the found group is the same as the existing group
109 auto index2 = groups_map.find(neighbour)->second;
110 if (group_index != index2) {
111 // we already have group "prime" if you will, so we're going to merge the new find into prime
112 Group &group2 = groups.at(index2);
113 // merge
114 TRACE(groups).print(" -> merging two groups. group 1 size: {}. group 2 size: {}\n", group->size(),
115 group2.size());
116 for (auto pos2: group2) {
117 group->emplace(pos2);
118 groups_map[pos2] = group_index;
119 }
120 group2.clear();
121 free_spots.emplace(index2);
122 TRACE(groups).print(" merged size: {}\n", group->size());
123 }
124 }
125 }
126 // if we haven't found at least one group by now we need to create/get one
127 if (!group) {
128 TRACE(groups).print(" -> no merging took place\n");
129 // first we check if we can re-use a group that's been freed
130 if (!free_spots.empty()) {
131 TRACE(groups).print(" -> use recycled old group\n");
132 // first element in a set is always the lowest value, so we re-use from the front of the vector
133 group_index = *free_spots.begin();
134 group = &groups[group_index];

Callers

nothing calls this directly

Calls 10

get_neighboursFunction · 0.85
isValidTilePosFunction · 0.85
countMethod · 0.45
printMethod · 0.45
findMethod · 0.45
sizeMethod · 0.45
clearMethod · 0.45
emptyMethod · 0.45
beginMethod · 0.45
eraseMethod · 0.45

Tested by

no test coverage detected