1
0
Fork 0

Codechange: Use per-vehicle-type list when ticking vehicles.

pull/11850/head
Peter Nelson 2024-01-20 22:29:19 +00:00
parent 526a0db956
commit 1306dd45f0
No known key found for this signature in database
GPG Key ID: 8EF8F0A467DF75ED
6 changed files with 121 additions and 81 deletions

View File

@ -2099,8 +2099,6 @@ bool Aircraft::Tick()
{
if (!this->IsNormalAircraft()) return true;
PerformanceAccumulator framerate(PFE_GL_AIRCRAFT);
this->tick_counter++;
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;

View File

@ -1643,8 +1643,6 @@ Money RoadVehicle::GetRunningCost() const
bool RoadVehicle::Tick()
{
PerformanceAccumulator framerate(PFE_GL_ROADVEHS);
this->tick_counter++;
if (this->IsFrontEngine()) {

View File

@ -839,8 +839,6 @@ static void ShipController(Ship *v)
bool Ship::Tick()
{
PerformanceAccumulator framerate(PFE_GL_SHIPS);
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
ShipController(this);

View File

@ -4097,8 +4097,6 @@ bool Train::Tick()
this->tick_counter++;
if (this->IsFrontEngine()) {
PerformanceAccumulator framerate(PFE_GL_TRAINS);
if (!(this->vehstatus & VS_STOPPED) || this->cur_speed > 0) this->running_ticks++;
this->current_order_time++;

View File

@ -9,6 +9,7 @@
#include "stdafx.h"
#include "error.h"
#include "disaster_vehicle.h"
#include "roadveh.h"
#include "ship.h"
#include "spritecache.h"
@ -950,6 +951,96 @@ static void RunVehicleDayProc()
}
}
static void SpecialVehicleTick(Vehicle *v)
{
[[maybe_unused]] size_t vehicle_index = v->index;
/* Vehicle could be deleted in this tick */
if (!v->Tick()) {
assert(Vehicle::Get(vehicle_index) == nullptr);
return;
}
assert(Vehicle::Get(vehicle_index) == v);
}
static void CommonVehicleTick(Vehicle *v)
{
[[maybe_unused]] size_t vehicle_index = v->index;
/* Vehicle could be deleted in this tick */
if (!v->Tick()) {
assert(Vehicle::Get(vehicle_index) == nullptr);
return;
}
assert(Vehicle::Get(vehicle_index) == v);
Vehicle *front = v->First();
if (v->vcache.cached_cargo_age_period != 0) {
v->cargo_age_counter = std::min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
if (--v->cargo_age_counter == 0) {
v->cargo.AgeCargo();
v->cargo_age_counter = v->vcache.cached_cargo_age_period;
}
}
/* Do not play any sound when crashed */
if (front->vehstatus & VS_CRASHED) return;
/* Do not play any sound when in depot or tunnel */
if (v->vehstatus & VS_HIDDEN) return;
/* Do not play any sound when stopped */
if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) return;
/* Check vehicle type specifics */
switch (v->type) {
case VEH_TRAIN:
if (Train::From(v)->IsWagon()) return;
break;
case VEH_ROAD:
if (!RoadVehicle::From(v)->IsFrontEngine()) return;
break;
case VEH_AIRCRAFT:
if (!Aircraft::From(v)->IsNormalAircraft()) return;
break;
default:
break;
}
v->motion_counter += front->cur_speed;
/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
/* Play an alternating running sound every 16 ticks */
if (GB(v->tick_counter, 0, 4) == 0) {
/* Play running sound when speed > 0 and not braking */
bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
}
}
template <class T, typename Pred>
static void IterateTickable(Pred pred)
{
for (auto it = std::begin(T::tickable_vehicles), next_it = it; it != std::end(T::tickable_vehicles); it = next_it) {
++next_it;
pred(it->second);
}
}
template <class T, typename Pred>
static void IterateTickable(PerformanceElement pfe, Pred pred)
{
PerformanceMeasurer framerate(pfe);
IterateTickable<T>(pred);
}
void CallVehicleTicks()
{
_vehicles_to_autoreplace.clear();
@ -960,81 +1051,14 @@ void CallVehicleTicks()
PerformanceMeasurer framerate(PFE_GL_ECONOMY);
for (Station *st : Station::Iterate()) LoadUnloadStation(st);
}
PerformanceAccumulator::Reset(PFE_GL_TRAINS);
PerformanceAccumulator::Reset(PFE_GL_ROADVEHS);
PerformanceAccumulator::Reset(PFE_GL_SHIPS);
PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT);
for (Vehicle *v : Vehicle::Iterate()) {
[[maybe_unused]] size_t vehicle_index = v->index;
IterateTickable<DisasterVehicle>(SpecialVehicleTick);
IterateTickable<EffectVehicle>(SpecialVehicleTick);
/* Vehicle could be deleted in this tick */
if (!v->Tick()) {
assert(Vehicle::Get(vehicle_index) == nullptr);
continue;
}
assert(Vehicle::Get(vehicle_index) == v);
switch (v->type) {
default: break;
case VEH_TRAIN:
case VEH_ROAD:
case VEH_AIRCRAFT:
case VEH_SHIP: {
Vehicle *front = v->First();
if (v->vcache.cached_cargo_age_period != 0) {
v->cargo_age_counter = std::min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
if (--v->cargo_age_counter == 0) {
v->cargo.AgeCargo();
v->cargo_age_counter = v->vcache.cached_cargo_age_period;
}
}
/* Do not play any sound when crashed */
if (front->vehstatus & VS_CRASHED) continue;
/* Do not play any sound when in depot or tunnel */
if (v->vehstatus & VS_HIDDEN) continue;
/* Do not play any sound when stopped */
if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
/* Check vehicle type specifics */
switch (v->type) {
case VEH_TRAIN:
if (Train::From(v)->IsWagon()) continue;
break;
case VEH_ROAD:
if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
break;
case VEH_AIRCRAFT:
if (!Aircraft::From(v)->IsNormalAircraft()) continue;
break;
default:
break;
}
v->motion_counter += front->cur_speed;
/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
/* Play an alternating running sound every 16 ticks */
if (GB(v->tick_counter, 0, 4) == 0) {
/* Play running sound when speed > 0 and not braking */
bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
}
break;
}
}
}
IterateTickable<Train>(PFE_GL_TRAINS, CommonVehicleTick);
IterateTickable<RoadVehicle>(PFE_GL_ROADVEHS, CommonVehicleTick);
IterateTickable<Ship>(PFE_GL_SHIPS, CommonVehicleTick);
IterateTickable<Aircraft>(PFE_GL_AIRCRAFT, CommonVehicleTick);
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
for (auto &it : _vehicles_to_autoreplace) {

View File

@ -1062,6 +1062,9 @@ public:
uint32_t GetDisplayMaxWeight() const;
uint32_t GetDisplayMinPowerToWeight() const;
virtual void AddTickable() {}
virtual void RemoveTickable() {}
};
/**
@ -1080,6 +1083,12 @@ struct SpecializedVehicle : public Vehicle {
inline SpecializedVehicle<T, Type>() : Vehicle(Type)
{
this->sprite_cache.sprite_seq.count = 1;
this->AddTickable();
}
inline ~SpecializedVehicle<T, Type>()
{
this->RemoveTickable();
}
/**
@ -1259,6 +1268,21 @@ struct SpecializedVehicle : public Vehicle {
* @return an iterable ensemble of all valid vehicles of type T
*/
static Pool::IterateWrapper<T> Iterate(size_t from = 0) { return Pool::IterateWrapper<T>(from); }
/**
* List of tickable vehicles for this type.
*/
static inline std::map<VehicleID, SpecializedVehicle<T, Type> *> tickable_vehicles;
void AddTickable() override
{
tickable_vehicles.insert(std::make_pair(this->index, this));
}
void RemoveTickable() override
{
tickable_vehicles.erase(this->index);
}
};
/** Generates sequence of free UnitID numbers */