mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: Reduce size of class WaterRegion
The tile patch array is 256 bytes and is not needed for the majority of water regions, change it to be optional via std::unique_ptr
This commit is contained in:
parent
e42aec5a89
commit
2189607c34
|
@ -38,6 +38,8 @@ static inline int GetWaterRegionMapSizeY() { return Map::SizeY() / WATER_REGION_
|
||||||
static inline TWaterRegionIndex GetWaterRegionIndex(int region_x, int region_y) { return GetWaterRegionMapSizeX() * region_y + region_x; }
|
static inline TWaterRegionIndex GetWaterRegionIndex(int region_x, int region_y) { return GetWaterRegionMapSizeX() * region_y + region_x; }
|
||||||
static inline TWaterRegionIndex GetWaterRegionIndex(TileIndex tile) { return GetWaterRegionIndex(GetWaterRegionX(tile), GetWaterRegionY(tile)); }
|
static inline TWaterRegionIndex GetWaterRegionIndex(TileIndex tile) { return GetWaterRegionIndex(GetWaterRegionX(tile), GetWaterRegionY(tile)); }
|
||||||
|
|
||||||
|
using TWaterRegionPatchLabelArray = std::array<TWaterRegionPatchLabel, WATER_REGION_NUMBER_OF_TILES>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a square section of the map of a fixed size. Within this square individual unconnected patches of water are
|
* Represents a square section of the map of a fixed size. Within this square individual unconnected patches of water are
|
||||||
* identified using a Connected Component Labeling (CCL) algorithm. Note that all information stored in this class applies
|
* identified using a Connected Component Labeling (CCL) algorithm. Note that all information stored in this class applies
|
||||||
|
@ -49,10 +51,10 @@ class WaterRegion
|
||||||
private:
|
private:
|
||||||
std::array<TWaterRegionTraversabilityBits, DIAGDIR_END> edge_traversability_bits{};
|
std::array<TWaterRegionTraversabilityBits, DIAGDIR_END> edge_traversability_bits{};
|
||||||
bool has_cross_region_aqueducts = false;
|
bool has_cross_region_aqueducts = false;
|
||||||
|
bool initialized = false;
|
||||||
TWaterRegionPatchLabel number_of_patches = 0; // 0 = no water, 1 = one single patch of water, etc...
|
TWaterRegionPatchLabel number_of_patches = 0; // 0 = no water, 1 = one single patch of water, etc...
|
||||||
const OrthogonalTileArea tile_area;
|
const OrthogonalTileArea tile_area;
|
||||||
std::array<TWaterRegionPatchLabel, WATER_REGION_NUMBER_OF_TILES> tile_patch_labels{};
|
std::unique_ptr<TWaterRegionPatchLabelArray> tile_patch_labels; ///< Tile patch labels, this may be nullptr in the following trivial cases: region is invalid, region is only land (0 patches), region is only water (1 patch)
|
||||||
bool initialized = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the local index of the tile within the region. The N corner represents 0,
|
* Returns the local index of the tile within the region. The N corner represents 0,
|
||||||
|
@ -110,7 +112,10 @@ public:
|
||||||
TWaterRegionPatchLabel GetLabel(TileIndex tile) const
|
TWaterRegionPatchLabel GetLabel(TileIndex tile) const
|
||||||
{
|
{
|
||||||
assert(this->tile_area.Contains(tile));
|
assert(this->tile_area.Contains(tile));
|
||||||
return this->tile_patch_labels[GetLocalIndex(tile)];
|
if (this->tile_patch_labels == nullptr) {
|
||||||
|
return this->NumberOfPatches() == 0 ? INVALID_WATER_REGION_PATCH : 1;
|
||||||
|
}
|
||||||
|
return (*this->tile_patch_labels)[GetLocalIndex(tile)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,7 +127,12 @@ public:
|
||||||
Debug(map, 3, "Updating water region ({},{})", GetWaterRegionX(this->tile_area.tile), GetWaterRegionY(this->tile_area.tile));
|
Debug(map, 3, "Updating water region ({},{})", GetWaterRegionX(this->tile_area.tile), GetWaterRegionY(this->tile_area.tile));
|
||||||
this->has_cross_region_aqueducts = false;
|
this->has_cross_region_aqueducts = false;
|
||||||
|
|
||||||
this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH);
|
/* Acquire a tile patch label array if this region does not already have one */
|
||||||
|
if (this->tile_patch_labels == nullptr) {
|
||||||
|
this->tile_patch_labels = std::make_unique<TWaterRegionPatchLabelArray>();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->tile_patch_labels->fill(INVALID_WATER_REGION_PATCH);
|
||||||
this->edge_traversability_bits.fill(0);
|
this->edge_traversability_bits.fill(0);
|
||||||
|
|
||||||
TWaterRegionPatchLabel current_label = 1;
|
TWaterRegionPatchLabel current_label = 1;
|
||||||
|
@ -143,9 +153,10 @@ public:
|
||||||
const TrackdirBits valid_dirs = TrackBitsToTrackdirBits(GetWaterTracks(tile));
|
const TrackdirBits valid_dirs = TrackBitsToTrackdirBits(GetWaterTracks(tile));
|
||||||
if (valid_dirs == TRACKDIR_BIT_NONE) continue;
|
if (valid_dirs == TRACKDIR_BIT_NONE) continue;
|
||||||
|
|
||||||
if (this->tile_patch_labels[GetLocalIndex(tile)] != INVALID_WATER_REGION_PATCH) continue;
|
TWaterRegionPatchLabel &tile_patch = (*this->tile_patch_labels)[GetLocalIndex(tile)];
|
||||||
|
if (tile_patch != INVALID_WATER_REGION_PATCH) continue;
|
||||||
|
|
||||||
this->tile_patch_labels[GetLocalIndex(tile)] = current_label;
|
tile_patch = current_label;
|
||||||
highest_assigned_label = current_label;
|
highest_assigned_label = current_label;
|
||||||
increase_label = true;
|
increase_label = true;
|
||||||
|
|
||||||
|
@ -172,6 +183,12 @@ public:
|
||||||
|
|
||||||
this->number_of_patches = highest_assigned_label;
|
this->number_of_patches = highest_assigned_label;
|
||||||
this->initialized = true;
|
this->initialized = true;
|
||||||
|
|
||||||
|
if (this->number_of_patches == 0 || (this->number_of_patches == 1 &&
|
||||||
|
std::all_of(this->tile_patch_labels->begin(), this->tile_patch_labels->end(), [](TWaterRegionPatchLabel label) { return label == 1; }))) {
|
||||||
|
/* No need for patch storage: trivial cases */
|
||||||
|
this->tile_patch_labels.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,7 +213,7 @@ public:
|
||||||
for (int y = 0; y < WATER_REGION_EDGE_LENGTH; ++y) {
|
for (int y = 0; y < WATER_REGION_EDGE_LENGTH; ++y) {
|
||||||
std::string line{};
|
std::string line{};
|
||||||
for (int x = 0; x < WATER_REGION_EDGE_LENGTH; ++x) {
|
for (int x = 0; x < WATER_REGION_EDGE_LENGTH; ++x) {
|
||||||
const auto label = this->tile_patch_labels[x + y * WATER_REGION_EDGE_LENGTH];
|
const auto label = this->GetLabel(TileAddXY(tile_area.tile, x, y));
|
||||||
const std::string label_str = label == INVALID_WATER_REGION_PATCH ? "." : std::to_string(label);
|
const std::string label_str = label == INVALID_WATER_REGION_PATCH ? "." : std::to_string(label);
|
||||||
line = fmt::format("{:{}}", label_str, max_element_width) + " " + line;
|
line = fmt::format("{:{}}", label_str, max_element_width) + " " + line;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue