mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Add iterator for vehicles on a tile.
parent
917ef03e97
commit
fca3103d8c
|
@ -471,6 +471,35 @@ bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
|
||||||
return VehicleFromPosXY(x, y, data, proc, true) != nullptr;
|
return VehicleFromPosXY(x, y, data, proc, true) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator constructor.
|
||||||
|
* Find first vehicle on tile.
|
||||||
|
*/
|
||||||
|
VehiclesOnTile::Iterator::Iterator(TileIndex tile) : tile(tile)
|
||||||
|
{
|
||||||
|
int x = GB(TileX(tile), HASH_RES, HASH_BITS);
|
||||||
|
int y = GB(TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS;
|
||||||
|
this->current = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
|
||||||
|
this->SkipFalseMatches();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the internal state to the next potential vehicle.
|
||||||
|
* The vehicle may not be on the correct tile though.
|
||||||
|
*/
|
||||||
|
void VehiclesOnTile::Iterator::Increment()
|
||||||
|
{
|
||||||
|
this->current = this->current->hash_tile_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the internal state until it reaches a vehicle on the correct tile or the end.
|
||||||
|
*/
|
||||||
|
void VehiclesOnTile::Iterator::SkipFalseMatches()
|
||||||
|
{
|
||||||
|
while (this->current != nullptr && this->current->tile != this->tile) this->Increment();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for FindVehicleOnPos/HasVehicleOnPos.
|
* Helper function for FindVehicleOnPos/HasVehicleOnPos.
|
||||||
* @note Do not call this function directly!
|
* @note Do not call this function directly!
|
||||||
|
|
|
@ -46,6 +46,58 @@ static const Money VEHICLE_PROFIT_THRESHOLD = 10000; ///< Threshold for a
|
||||||
template <VehicleType T>
|
template <VehicleType T>
|
||||||
bool IsValidImageIndex(uint8_t image_index);
|
bool IsValidImageIndex(uint8_t image_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over all vehicles on a tile.
|
||||||
|
* @warning The order is non-deterministic. You have to make sure, that your processing is not order dependant.
|
||||||
|
*/
|
||||||
|
class VehiclesOnTile {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Forward iterator
|
||||||
|
*/
|
||||||
|
class Iterator {
|
||||||
|
public:
|
||||||
|
using value_type = Vehicle *;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using pointer = void;
|
||||||
|
using reference = void;
|
||||||
|
|
||||||
|
explicit Iterator(TileIndex tile);
|
||||||
|
|
||||||
|
bool operator==(const Iterator &rhs) const { return this->current == rhs.current; }
|
||||||
|
bool operator==(const std::default_sentinel_t &) const { return this->current == nullptr; }
|
||||||
|
|
||||||
|
Vehicle *operator*() const { return this->current; }
|
||||||
|
|
||||||
|
Iterator &operator++()
|
||||||
|
{
|
||||||
|
this->Increment();
|
||||||
|
this->SkipFalseMatches();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator operator++(int)
|
||||||
|
{
|
||||||
|
Iterator result = *this;
|
||||||
|
++*this;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
TileIndex tile;
|
||||||
|
Vehicle *current;
|
||||||
|
|
||||||
|
void Increment();
|
||||||
|
void SkipFalseMatches();
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit VehiclesOnTile(TileIndex tile) : start(tile) {}
|
||||||
|
Iterator begin() const { return this->start; }
|
||||||
|
std::default_sentinel_t end() const { return std::default_sentinel_t(); }
|
||||||
|
private:
|
||||||
|
Iterator start;
|
||||||
|
};
|
||||||
|
|
||||||
typedef Vehicle *VehicleFromPosProc(Vehicle *v, void *data);
|
typedef Vehicle *VehicleFromPosProc(Vehicle *v, void *data);
|
||||||
|
|
||||||
void VehicleServiceInDepot(Vehicle *v);
|
void VehicleServiceInDepot(Vehicle *v);
|
||||||
|
|
Loading…
Reference in New Issue