Codechange: Use std::optional for town parent scope resolver. (#12530)

When resolving NewGRF, the parent town_scope is lazily initialised as it does not always need to be used.

Replace the manually managed pointer with std::optional to simplify. Using std::optional avoids extra memory allocation.
This commit is contained in:
Peter Nelson 2024-04-18 22:14:16 +01:00 committed by GitHub
parent 3b75d8bbf8
commit 774f811217
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 23 additions and 52 deletions

View File

@ -219,7 +219,7 @@ uint32_t AirportResolverObject::GetDebugID() const
*/
TownScopeResolver *AirportResolverObject::GetTown()
{
if (!this->town_scope) {
if (!this->town_scope.has_value()) {
Town *t = nullptr;
if (this->airport_scope.st != nullptr) {
t = this->airport_scope.st->town;
@ -227,9 +227,9 @@ TownScopeResolver *AirportResolverObject::GetTown()
t = ClosestTownFromTile(this->airport_scope.tile, UINT_MAX);
}
if (t == nullptr) return nullptr;
this->town_scope.reset(new TownScopeResolver(*this, t, this->airport_scope.st == nullptr));
this->town_scope.emplace(*this, t, this->airport_scope.st == nullptr);
}
return this->town_scope.get();
return &*this->town_scope;
}
/**

View File

@ -174,7 +174,7 @@ struct AirportScopeResolver : public ScopeResolver {
/** Resolver object for airports. */
struct AirportResolverObject : public ResolverObject {
AirportScopeResolver airport_scope;
std::unique_ptr<TownScopeResolver> town_scope; ///< The town scope resolver (created on the first call).
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< The town scope resolver (created on the first call).
AirportResolverObject(TileIndex tile, Station *st, uint8_t airport_id, uint8_t layout,
CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0);

View File

@ -467,24 +467,18 @@ static const GRFFile *GetGrffile(IndustryType type)
IndustriesResolverObject::IndustriesResolverObject(TileIndex tile, Industry *indus, IndustryType type, uint32_t random_bits,
CallbackID callback, uint32_t callback_param1, uint32_t callback_param2)
: ResolverObject(GetGrffile(type), callback, callback_param1, callback_param2),
industries_scope(*this, tile, indus, type, random_bits),
town_scope(nullptr)
industries_scope(*this, tile, indus, type, random_bits)
{
this->root_spritegroup = GetIndustrySpec(type)->grf_prop.spritegroup[0];
}
IndustriesResolverObject::~IndustriesResolverObject()
{
delete this->town_scope;
}
/**
* Get or create the town scope object associated with the industry.
* @return The associated town scope, if it exists.
*/
TownScopeResolver *IndustriesResolverObject::GetTown()
{
if (this->town_scope == nullptr) {
if (!this->town_scope.has_value()) {
Town *t = nullptr;
bool readonly = true;
if (this->industries_scope.industry != nullptr) {
@ -494,9 +488,9 @@ TownScopeResolver *IndustriesResolverObject::GetTown()
t = ClosestTownFromTile(this->industries_scope.tile, UINT_MAX);
}
if (t == nullptr) return nullptr;
this->town_scope = new TownScopeResolver(*this, t, readonly);
this->town_scope.emplace(*this, t, readonly);
}
return this->town_scope;
return &*this->town_scope;
}
GrfSpecFeature IndustriesResolverObject::GetFeature() const

View File

@ -41,11 +41,10 @@ struct IndustriesScopeResolver : public ScopeResolver {
/** Resolver for industries. */
struct IndustriesResolverObject : public ResolverObject {
IndustriesScopeResolver industries_scope; ///< Scope resolver for the industry.
TownScopeResolver *town_scope; ///< Scope resolver for the associated town (if needed and available, else \c nullptr).
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< Scope resolver for the associated town (if needed and available, else \c std::nullopt).
IndustriesResolverObject(TileIndex tile, Industry *indus, IndustryType type, uint32_t random_bits = 0,
CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0);
~IndustriesResolverObject();
TownScopeResolver *GetTown();

View File

@ -378,16 +378,10 @@ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj,
CallbackID callback, uint32_t param1, uint32_t param2)
: ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, spec, tile, view)
{
this->town_scope = nullptr;
this->root_spritegroup = (obj == nullptr && spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] != nullptr) ?
spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_PURCHASE] : spec->grf_prop.spritegroup[OBJECT_SPRITE_GROUP_DEFAULT];
}
ObjectResolverObject::~ObjectResolverObject()
{
delete this->town_scope;
}
/**
* Get the town resolver scope that belongs to this object resolver.
* On the first call, the town scope is created (if possible).
@ -395,7 +389,7 @@ ObjectResolverObject::~ObjectResolverObject()
*/
TownScopeResolver *ObjectResolverObject::GetTown()
{
if (this->town_scope == nullptr) {
if (!this->town_scope.has_value()) {
Town *t;
if (this->object_scope.obj != nullptr) {
t = this->object_scope.obj->town;
@ -403,9 +397,9 @@ TownScopeResolver *ObjectResolverObject::GetTown()
t = ClosestTownFromTile(this->object_scope.tile, UINT_MAX);
}
if (t == nullptr) return nullptr;
this->town_scope = new TownScopeResolver(*this, t, this->object_scope.obj == nullptr);
this->town_scope.emplace(*this, t, this->object_scope.obj == nullptr);
}
return this->town_scope;
return &*this->town_scope;
}
GrfSpecFeature ObjectResolverObject::GetFeature() const

View File

@ -133,11 +133,10 @@ struct ObjectScopeResolver : public ScopeResolver {
/** A resolver object to be used with feature 0F spritegroups. */
struct ObjectResolverObject : public ResolverObject {
ObjectScopeResolver object_scope; ///< The object scope resolver.
TownScopeResolver *town_scope; ///< The town scope resolver (created on the first call).
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< The town scope resolver (created on the first call).
ObjectResolverObject(const ObjectSpec *spec, Object *o, TileIndex tile, uint8_t view = 0,
CallbackID callback = CBID_NO_CALLBACK, uint32_t param1 = 0, uint32_t param2 = 0);
~ObjectResolverObject();
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0) override
{

View File

@ -210,10 +210,7 @@ const SpriteGroup *RoadStopResolverObject::ResolveReal(const RealSpriteGroup *gr
RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view,
CallbackID callback, uint32_t param1, uint32_t param2)
: ResolverObject(roadstopspec->grf_prop.grffile, callback, param1, param2), roadstop_scope(*this, st, roadstopspec, tile, roadtype, type, view)
{
this->town_scope = nullptr;
{
CargoID ctype = SpriteGroupCargo::SG_DEFAULT_NA;
if (st == nullptr) {
@ -240,14 +237,9 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec,
this->root_spritegroup = roadstopspec->grf_prop.spritegroup[ctype];
}
RoadStopResolverObject::~RoadStopResolverObject()
{
delete this->town_scope;
}
TownScopeResolver *RoadStopResolverObject::GetTown()
{
if (this->town_scope == nullptr) {
if (!this->town_scope.has_value()) {
Town *t;
if (this->roadstop_scope.st != nullptr) {
t = this->roadstop_scope.st->town;
@ -255,9 +247,9 @@ TownScopeResolver *RoadStopResolverObject::GetTown()
t = ClosestTownFromTile(this->roadstop_scope.tile, UINT_MAX);
}
if (t == nullptr) return nullptr;
this->town_scope = new TownScopeResolver(*this, t, this->roadstop_scope.st == nullptr);
this->town_scope.emplace(*this, t, this->roadstop_scope.st == nullptr);
}
return this->town_scope;
return &*this->town_scope;
}
uint16_t GetRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view)

View File

@ -95,10 +95,9 @@ struct RoadStopScopeResolver : public ScopeResolver {
/** Road stop resolver. */
struct RoadStopResolverObject : public ResolverObject {
RoadStopScopeResolver roadstop_scope; ///< The stop scope resolver.
TownScopeResolver *town_scope; ///< The town scope resolver (created on the first call).
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< The town scope resolver (created on the first call).
RoadStopResolverObject(const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view, CallbackID callback = CBID_NO_CALLBACK, uint32_t param1 = 0, uint32_t param2 = 0);
~RoadStopResolverObject();
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0) override
{

View File

@ -254,7 +254,7 @@ static struct {
*/
TownScopeResolver *StationResolverObject::GetTown()
{
if (this->town_scope == nullptr) {
if (!this->town_scope.has_value()) {
Town *t = nullptr;
if (this->station_scope.st != nullptr) {
t = this->station_scope.st->town;
@ -262,9 +262,9 @@ TownScopeResolver *StationResolverObject::GetTown()
t = ClosestTownFromTile(this->station_scope.tile, UINT_MAX);
}
if (t == nullptr) return nullptr;
this->town_scope = new TownScopeResolver(*this, t, this->station_scope.st == nullptr);
this->town_scope.emplace(*this, t, this->station_scope.st == nullptr);
}
return this->town_scope;
return &*this->town_scope;
}
/* virtual */ uint32_t StationScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] uint32_t parameter, bool *available) const
@ -569,7 +569,7 @@ uint32_t StationResolverObject::GetDebugID() const
StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *base_station, TileIndex tile,
CallbackID callback, uint32_t callback_param1, uint32_t callback_param2)
: ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2),
station_scope(*this, statspec, base_station, tile), town_scope(nullptr)
station_scope(*this, statspec, base_station, tile)
{
/* Invalidate all cached vars */
_svc.valid = 0;
@ -600,11 +600,6 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt
this->root_spritegroup = this->station_scope.statspec->grf_prop.spritegroup[this->station_scope.cargo_type];
}
StationResolverObject::~StationResolverObject()
{
delete this->town_scope;
}
/**
* Resolve sprites for drawing a station tile.
* @param statspec Station spec

View File

@ -49,11 +49,10 @@ struct StationScopeResolver : public ScopeResolver {
/** Station resolver. */
struct StationResolverObject : public ResolverObject {
StationScopeResolver station_scope; ///< The station scope resolver.
TownScopeResolver *town_scope; ///< The town scope resolver (created on the first call).
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< The town scope resolver (created on the first call).
StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile,
CallbackID callback = CBID_NO_CALLBACK, uint32_t callback_param1 = 0, uint32_t callback_param2 = 0);
~StationResolverObject();
TownScopeResolver *GetTown();