mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +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.
(cherry picked from commit ff972ec4ff
)
# Conflicts:
# src/newgrf.cpp
# src/newgrf_station.h
This commit is contained in:
parent
839ec6f1e8
commit
fe14fe6d3c
@ -2029,14 +2029,14 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, cons
|
||||
|
||||
if (length == 0 || number == 0) break;
|
||||
|
||||
if (statspec->layouts.size() < length) statspec->layouts.resize(length);
|
||||
if (statspec->layouts[length - 1].size() < number) statspec->layouts[length - 1].resize(number);
|
||||
const uint8_t *buf_layout = buf->ReadBytes(length * number);
|
||||
|
||||
const uint8_t *layout = buf->ReadBytes(length * number);
|
||||
statspec->layouts[length - 1][number - 1].assign(layout, layout + length * number);
|
||||
/* Create entry in layouts and assign the layout to it. */
|
||||
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. */
|
||||
for (auto &tile : statspec->layouts[length - 1][number - 1]) {
|
||||
for (auto &tile : layout) {
|
||||
if ((tile & ~1U) != tile) {
|
||||
GrfMsg(1, "StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
|
||||
tile &= ~1U;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "newgrf_spritegroup.h"
|
||||
#include "newgrf_town.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
/** Scope resolver for stations. */
|
||||
struct StationScopeResolver : public ScopeResolver {
|
||||
@ -191,15 +192,8 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
|
||||
|
||||
uint8_t internal_flags; ///< Bitmask of internal spec flags (StationSpecIntlFlags)
|
||||
|
||||
/**
|
||||
* Custom platform 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;
|
||||
/** Custom platform layouts, keyed by platform and length combined. */
|
||||
std::unordered_map<uint16_t, std::vector<uint8_t>> layouts;
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(StationSpec::TileFlags);
|
||||
|
||||
@ -208,6 +202,17 @@ using StationClass = NewGRFClass<StationSpec, StationClassID, STAT_CLASS_MAX>;
|
||||
|
||||
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.
|
||||
* @param cls StationClass to test.
|
||||
|
@ -1325,14 +1325,14 @@ 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)
|
||||
{
|
||||
if (statspec != nullptr && statspec->layouts.size() >= plat_len &&
|
||||
statspec->layouts[plat_len - 1].size() >= numtracks &&
|
||||
!statspec->layouts[plat_len - 1][numtracks - 1].empty()) {
|
||||
/* Custom layout defined, follow it. */
|
||||
memcpy(layout, statspec->layouts[plat_len - 1][numtracks - 1].data(),
|
||||
static_cast<size_t>(plat_len) * numtracks);
|
||||
if (statspec != nullptr) {
|
||||
auto found = statspec->layouts.find(GetStationLayoutKey(numtracks, plat_len));
|
||||
if (found != std::end(statspec->layouts)) {
|
||||
/* Custom layout defined, copy to buffer. */
|
||||
std::copy(std::begin(found->second), std::end(found->second), layout);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (plat_len == 1) {
|
||||
CreateSingle(layout, numtracks);
|
||||
|
Loading…
Reference in New Issue
Block a user