mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-10 08:00:05 +00:00
Codechange: Store custom station layouts in a map instead of nested vectors. (#12898)
The map key is the platforms and length combined. This simplifies allocation and searching for layouts.
This commit is contained in:
parent
39465d7f5c
commit
ff972ec4ff
@ -2042,14 +2042,14 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
|||||||
|
|
||||||
if (length == 0 || number == 0) break;
|
if (length == 0 || number == 0) break;
|
||||||
|
|
||||||
if (statspec->layouts.size() < length) statspec->layouts.resize(length);
|
const uint8_t *buf_layout = buf.ReadBytes(length * number);
|
||||||
if (statspec->layouts[length - 1].size() < number) statspec->layouts[length - 1].resize(number);
|
|
||||||
|
|
||||||
const uint8_t *layout = buf.ReadBytes(length * number);
|
/* Create entry in layouts and assign the layout to it. */
|
||||||
statspec->layouts[length - 1][number - 1].assign(layout, layout + length * number);
|
auto &layout = statspec->layouts[GetStationLayoutKey(number, length)];
|
||||||
|
layout.assign(buf_layout, buf_layout + length * number);
|
||||||
|
|
||||||
/* Ensure the first bit, axis, is zero. The rest of the value is validated during rendering, as we don't know the range yet. */
|
/* Ensure the first bit, axis, is zero. The rest of the value is validated during rendering, as we don't know the range yet. */
|
||||||
for (auto &tile : statspec->layouts[length - 1][number - 1]) {
|
for (auto &tile : layout) {
|
||||||
if ((tile & ~1U) != tile) {
|
if ((tile & ~1U) != tile) {
|
||||||
GrfMsg(1, "StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
|
GrfMsg(1, "StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
|
||||||
tile &= ~1U;
|
tile &= ~1U;
|
||||||
|
@ -170,15 +170,8 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
|
|||||||
|
|
||||||
AnimationInfo animation;
|
AnimationInfo animation;
|
||||||
|
|
||||||
/**
|
/** Custom platform layouts, keyed by platform and length combined. */
|
||||||
* Custom platform layouts.
|
std::unordered_map<uint16_t, std::vector<uint8_t>> layouts;
|
||||||
* This is a 2D array containing an array of tiles.
|
|
||||||
* 1st layer is platform lengths.
|
|
||||||
* 2nd layer is tracks (width).
|
|
||||||
* These can be sparsely populated, and the upper limit is not defined but
|
|
||||||
* limited to 255.
|
|
||||||
*/
|
|
||||||
std::vector<std::vector<std::vector<uint8_t>>> layouts;
|
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(StationSpec::TileFlags);
|
DECLARE_ENUM_AS_BIT_SET(StationSpec::TileFlags);
|
||||||
|
|
||||||
@ -187,6 +180,17 @@ using StationClass = NewGRFClass<StationSpec, StationClassID, STAT_CLASS_MAX>;
|
|||||||
|
|
||||||
const StationSpec *GetStationSpec(TileIndex t);
|
const StationSpec *GetStationSpec(TileIndex t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the station layout key for a given station layout size.
|
||||||
|
* @param platforms Number of platforms.
|
||||||
|
* @param length Length of platforms.
|
||||||
|
* @returns Key of station layout.
|
||||||
|
*/
|
||||||
|
inline uint16_t GetStationLayoutKey(uint8_t platforms, uint8_t length)
|
||||||
|
{
|
||||||
|
return (length << 8U) | platforms;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if a StationClass is the waypoint class.
|
* Test if a StationClass is the waypoint class.
|
||||||
* @param cls StationClass to test.
|
* @param cls StationClass to test.
|
||||||
|
@ -1127,13 +1127,13 @@ static inline uint8_t *CreateMulti(uint8_t *layout, int n, uint8_t b)
|
|||||||
*/
|
*/
|
||||||
void GetStationLayout(uint8_t *layout, uint numtracks, uint plat_len, const StationSpec *statspec)
|
void GetStationLayout(uint8_t *layout, uint numtracks, uint plat_len, const StationSpec *statspec)
|
||||||
{
|
{
|
||||||
if (statspec != nullptr && statspec->layouts.size() >= plat_len &&
|
if (statspec != nullptr) {
|
||||||
statspec->layouts[plat_len - 1].size() >= numtracks &&
|
auto found = statspec->layouts.find(GetStationLayoutKey(numtracks, plat_len));
|
||||||
!statspec->layouts[plat_len - 1][numtracks - 1].empty()) {
|
if (found != std::end(statspec->layouts)) {
|
||||||
/* Custom layout defined, follow it. */
|
/* Custom layout defined, copy to buffer. */
|
||||||
memcpy(layout, statspec->layouts[plat_len - 1][numtracks - 1].data(),
|
std::copy(std::begin(found->second), std::end(found->second), layout);
|
||||||
static_cast<size_t>(plat_len) * numtracks);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plat_len == 1) {
|
if (plat_len == 1) {
|
||||||
|
Loading…
Reference in New Issue
Block a user