builds groupings of adjacent channel designations
| 175 | |
| 176 | // builds groupings of adjacent channel designations |
| 177 | void ChannelGroups::scan(bool full_scan) { |
| 178 | static std::default_random_engine RNG(0); |
| 179 | static std::bernoulli_distribution sometimes_scanFULLY(0.15); |
| 180 | if (!full_scan) { |
| 181 | full_scan = sometimes_scanFULLY(RNG); |
| 182 | } |
| 183 | |
| 184 | // save current jobs, then clear and load the current jobs |
| 185 | std::set<df::coord> last_jobs; |
| 186 | for (auto &pos : jobs) { |
| 187 | last_jobs.emplace(pos); |
| 188 | } |
| 189 | jobs.load_channel_jobs(); |
| 190 | // transpose channel jobs to |
| 191 | std::set<df::coord> new_jobs; |
| 192 | std::set<df::coord> gone_jobs; |
| 193 | set_difference(last_jobs, jobs, gone_jobs); |
| 194 | set_difference(jobs, last_jobs, new_jobs); |
| 195 | INFO(groups).print("gone jobs: {}\nnew jobs: {}\n",gone_jobs.size(), new_jobs.size()); |
| 196 | for (auto &pos : new_jobs) { |
| 197 | add(pos); |
| 198 | } |
| 199 | for (auto &pos : gone_jobs){ |
| 200 | remove(pos); |
| 201 | } |
| 202 | |
| 203 | DEBUG(groups).print(" scan()\n"); |
| 204 | // foreach block |
| 205 | for (int32_t z = mapz - 1; z >= 0; --z) { |
| 206 | for (int32_t by = 0; by < mapy; ++by) { |
| 207 | for (int32_t bx = 0; bx < mapx; ++bx) { |
| 208 | // the block |
| 209 | if (df::map_block* block = Maps::getBlock(bx, by, z)) { |
| 210 | // skip this block? |
| 211 | if (!full_scan && !block->flags.bits.designated) { |
| 212 | continue; |
| 213 | } |
| 214 | df::map_block* block_above = Maps::getBlock(bx, by, z+1); |
| 215 | // foreach tile |
| 216 | bool empty_group = true; |
| 217 | for (int16_t lx = 0; lx < 16; ++lx) { |
| 218 | for (int16_t ly = 0; ly < 16; ++ly) { |
| 219 | // the tile, check if it has a channel designation |
| 220 | df::coord map_pos((bx * 16) + lx, (by * 16) + ly, z); |
| 221 | if (TileCache::Get().hasChanged(map_pos, block->tiletype[lx][ly])) { |
| 222 | TileCache::Get().uncache(map_pos); |
| 223 | remove(map_pos); |
| 224 | if (jobs.count(map_pos)) { |
| 225 | jobs.erase(map_pos); |
| 226 | } |
| 227 | block->designation[lx][ly].bits.dig = df::tile_dig_designation::No; |
| 228 | } else if (is_dig_designation(block->designation[lx][ly]) || block->occupancy[lx][ly].bits.dig_marked ) { |
| 229 | // We have a dig designated, or marked. Some of these will not need intervention. |
| 230 | if (block_above && |
| 231 | !is_channel_designation(block->designation[lx][ly]) && |
| 232 | !is_channel_designation(block_above->designation[lx][ly])) { |
| 233 | // if this tile isn't a channel designation, and doesn't have a channel designation above it.. we can skip it |
| 234 | continue; |
no test coverage detected