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 (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;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "newgrf_spritegroup.h"
|
#include "newgrf_spritegroup.h"
|
||||||
#include "newgrf_town.h"
|
#include "newgrf_town.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
/** Scope resolver for stations. */
|
/** Scope resolver for stations. */
|
||||||
struct StationScopeResolver : public ScopeResolver {
|
struct StationScopeResolver : public ScopeResolver {
|
||||||
@ -191,15 +192,8 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
|
|||||||
|
|
||||||
uint8_t internal_flags; ///< Bitmask of internal spec flags (StationSpecIntlFlags)
|
uint8_t internal_flags; ///< Bitmask of internal spec flags (StationSpecIntlFlags)
|
||||||
|
|
||||||
/**
|
/** 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);
|
||||||
|
|
||||||
@ -208,6 +202,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.
|
||||||
|
@ -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)
|
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) {
|
||||||
CreateSingle(layout, numtracks);
|
CreateSingle(layout, numtracks);
|
||||||
|
Loading…
Reference in New Issue
Block a user