(svn r2059) -Codechange: rewrote SetSignalsAfterProc so now the tiles from the PF

are checked against the vehicle-position-hash, instead all vehicles to 
the PF-position-hash. Big speed increase (function usages drops from 9% 
to 0.5%!) for maps with a lot of trains.
replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
truelight 20 years ago
parent 1eab014524
commit 6d75cce924

@ -1554,47 +1554,80 @@ static bool SetSignalsEnumProc(uint tile, SetSignalsData *ssd, int track, uint l
return false; return false;
} }
/* Struct to parse data from VehicleFromPos to SignalVehicleCheckProc */
typedef struct SignalVehicleCheckStruct {
TileIndex tile;
uint track;
} SignalVehicleCheckStruct;
static void *SignalVehicleCheckProc(Vehicle *v, void *data)
{
SignalVehicleCheckStruct *dest = data;
TileIndex tile;
/* Find the tile outside the tunnel, for signalling */
if (v->u.rail.track == 0x40) {
tile = GetVehicleOutOfTunnelTile(v);
} else {
tile = v->tile;
}
/* Wrong tile, or no train? Not a match */
if (tile != dest->tile || v->type != VEH_Train)
return NULL;
/* Are we on the same piece of track? */
if (dest->track & (v->u.rail.track + (v->u.rail.track<<8)))
return v;
return NULL;
}
/* Special check for SetSignalsAfterProc, to see if there is a vehicle on this tile */
bool SignalVehicleCheck(TileIndex tile, uint track)
{
SignalVehicleCheckStruct dest;
dest.tile = tile;
dest.track = track;
return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
}
static void SetSignalsAfterProc(TrackPathFinder *tpf) static void SetSignalsAfterProc(TrackPathFinder *tpf)
{ {
SetSignalsData *ssd = tpf->userdata; SetSignalsData *ssd = tpf->userdata;
Vehicle *v;
uint tile, hash, val, offs;
TrackPathFinderLink *link; TrackPathFinderLink *link;
uint offs;
uint i;
ssd->stop = false; ssd->stop = false;
// for each train, check if it is in the segment. /* Go through all the PF tiles */
// then we know that the signal should be red. for (i = 0; i < lengthof(tpf->hash_head); i++) {
FOR_ALL_VEHICLES(v) { /* Empty hash item */
if (v->type != VEH_Train) if (tpf->hash_head[i] == 0)
continue;
tile = v->tile;
if (v->u.rail.track == 0x40) { tile = GetVehicleOutOfTunnelTile(v); }
hash = PATHFIND_HASH_TILE(tile);
val = tpf->hash_head[hash];
if (val == 0)
continue; continue;
if (!(val & 0x8000)) { /* If 0x8000 is not set, there is only 1 item */
if ((TileIndex)tile == tpf->hash_tile[hash]) if (!(tpf->hash_head[i] & 0x8000)) {
goto check_val; /* Check if there is a vehicle on this tile */
if (SignalVehicleCheck(tpf->hash_tile[i], tpf->hash_head[i])) {
ssd->stop = true;
return;
}
} else { } else {
offs = tpf->hash_tile[hash]; /* There are multiple items, where hash_tile points to the first item in the list */
offs = tpf->hash_tile[i];
do { do {
/* Find the next item */
link = PATHFIND_GET_LINK_PTR(tpf, offs); link = PATHFIND_GET_LINK_PTR(tpf, offs);
if ( (TileIndex)tile == link->tile) { /* Check if there is a vehicle on this tile */
val = link->flags; if (SignalVehicleCheck(link->tile, link->flags)) {
check_val:; ssd->stop = true;
// the train is on the track, in either direction? return;
if (val & (v->u.rail.track + (v->u.rail.track<<8))) {
ssd->stop = true;
return;
}
break;
} }
/* Goto the next item */
} while ((offs=link->next) != 0xFFFF); } while ((offs=link->next) != 0xFFFF);
} }
} }

Loading…
Cancel
Save