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:
		 Jonathan G Rennison
					Jonathan G Rennison
				
			
				
					committed by
					
						 rubidium42
						rubidium42
					
				
			
			
				
	
			
			
			 rubidium42
						rubidium42
					
				
			
						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; | ||||||
| 			} | 			} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user