Changeset - r8306:a191fc6e2f8e
[Not reviewed]
master
0 10 0
smatz - 17 years ago 2008-01-16 01:18:15
smatz@openttd.org
(svn r11871) -Fix [FS#1074]: do not update signals after each tile when building/removing a large block of track/signals/station
10 files changed with 124 insertions and 31 deletions:
0 comments (0 inline, 0 general)
src/ai/ai.cpp
Show inline comments
 
@@ -10,6 +10,7 @@
 
#include "../player_base.h"
 
#include "ai.h"
 
#include "default/default.h"
 
#include "../signal_func.h"
 

	
 
AIStruct _ai;
 
AIPlayer _ai_player[MAX_PLAYERS];
 
@@ -159,6 +160,9 @@ static void AI_RunTick(PlayerID player)
 
		AiDoGameLoop(p);
 
		_is_old_ai_player = false;
 
	}
 

	
 
	/* AI could change some track, so update signals */
 
	UpdateSignalsInBuffer();
 
}
 

	
 

	
src/command.cpp
Show inline comments
 
@@ -20,6 +20,7 @@
 
#include "debug.h"
 
#include "player_func.h"
 
#include "player_base.h"
 
#include "signal_func.h"
 

	
 
#include "table/strings.h"
 

	
 
@@ -642,6 +643,9 @@ bool DoCommandP(TileIndex tile, uint32 p
 

	
 
	SubtractMoneyFromPlayer(res2);
 

	
 
	/* update signals if needed */
 
	UpdateSignalsInBuffer();
 

	
 
	if (IsLocalPlayer() && _game_mode != GM_EDITOR) {
 
		if (res2.GetCost() != 0 && tile != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2.GetCost());
 
		if (_additional_cash_required != 0) {
src/economy.cpp
Show inline comments
 
@@ -440,10 +440,13 @@ void ChangeOwnershipOfPlayerItems(Player
 
					TrackBits tracks = GetTrackBits(tile);
 
					do { // there may be two tracks with signals for TRACK_BIT_HORZ and TRACK_BIT_VERT
 
						Track track = RemoveFirstTrack(&tracks);
 
						if (HasSignalOnTrack(tile, track)) SetSignalsOnBothDir(tile, track, new_player);
 
						if (HasSignalOnTrack(tile, track)) AddTrackToSignalBuffer(tile, track, new_player);
 
					} while (tracks != TRACK_BIT_NONE);
 
				}
 
			} while (++tile != MapSize());
 

	
 
			/* update signals in buffer */
 
			UpdateSignalsInBuffer();
 
		}
 
	}
 

	
src/rail_cmd.cpp
Show inline comments
 
@@ -418,7 +418,7 @@ CommandCost CmdBuildSingleRail(TileIndex
 

	
 
	if (flags & DC_EXEC) {
 
		MarkTileDirtyByTile(tile);
 
		SetSignalsOnBothDir(tile, track, _current_player);
 
		AddTrackToSignalBuffer(tile, track, _current_player);
 
		YapfNotifyTrackLayoutChange(tile, track);
 
	}
 

	
 
@@ -502,12 +502,12 @@ CommandCost CmdRemoveSingleRail(TileInde
 
			 * are removing one of these pieces, we'll need to update signals for
 
			 * both directions explicitly, as after the track is removed it won't
 
			 * 'connect' with the other piece. */
 
			SetSignalsOnBothDir(tile, TRACK_X, owner);
 
			SetSignalsOnBothDir(tile, TRACK_Y, owner);
 
			AddTrackToSignalBuffer(tile, TRACK_X, owner);
 
			AddTrackToSignalBuffer(tile, TRACK_Y, owner);
 
			YapfNotifyTrackLayoutChange(tile, TRACK_X);
 
			YapfNotifyTrackLayoutChange(tile, TRACK_Y);
 
		} else {
 
			SetSignalsOnBothDir(tile, track, owner);
 
			AddTrackToSignalBuffer(tile, track, owner);
 
			YapfNotifyTrackLayoutChange(tile, track);
 
		}
 
	}
 
@@ -745,7 +745,7 @@ CommandCost CmdBuildTrainDepot(TileIndex
 

	
 
		d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 

	
 
		UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, _current_player);
 
		AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_player);
 
		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 
		d_auto_delete.Detach();
 
	}
 
@@ -871,7 +871,7 @@ CommandCost CmdBuildSingleSignal(TileInd
 
		}
 

	
 
		MarkTileDirtyByTile(tile);
 
		SetSignalsOnBothDir(tile, track, _current_player);
 
		AddTrackToSignalBuffer(tile, track, _current_player);
 
		YapfNotifyTrackLayoutChange(tile, track);
 
	}
 

	
 
@@ -1102,7 +1102,7 @@ CommandCost CmdRemoveSingleSignal(TileIn
 
			SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
 
		}
 

	
 
		SetSignalsOnBothDir(tile, track, GetTileOwner(tile));
 
		AddTrackToSignalBuffer(tile, track, GetTileOwner(tile));
 
		YapfNotifyTrackLayoutChange(tile, track);
 

	
 
		MarkTileDirtyByTile(tile);
 
@@ -1314,7 +1314,7 @@ static CommandCost RemoveTrainDepot(Tile
 

	
 
		DoClearSquare(tile);
 
		delete GetDepotByTile(tile);
 
		UpdateSignalsOnSegment(tile, dir, owner);
 
		AddSideToSignalBuffer(tile, dir, owner);
 
		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 
	}
 

	
src/signal.cpp
Show inline comments
 
@@ -22,11 +22,14 @@
 

	
 
/** these are the maximums used for updating signal blocks */
 
enum {
 
	SIG_TBU_SIZE  =  64, ///< number of signals entering to block
 
	SIG_TBD_SIZE  = 256, ///< number of intersections - open nodes in current block
 
	SIG_GLOB_SIZE =  64, ///< number of open blocks (block can be opened more times until detected)
 
	SIG_TBU_SIZE    =  64, ///< number of signals entering to block
 
	SIG_TBD_SIZE    = 256, ///< number of intersections - open nodes in current block
 
	SIG_GLOB_SIZE   = 128, ///< number of open blocks (block can be opened more times until detected)
 
	SIG_GLOB_UPDATE =  64, ///< how many items need to be in _globset to force update
 
};
 

	
 
assert_compile(SIG_GLOB_UPDATE <= SIG_GLOB_SIZE);
 

	
 
/** incidating trackbits with given enterdir */
 
static const TrackBitsByte _enterdir_to_trackbits[DIAGDIR_END] = {
 
	{TRACK_BIT_3WAY_NE},
 
@@ -100,6 +103,16 @@ public:
 
	}
 

	
 
	/**
 
	 * Reads the number of items
 
	 * @return current number of items
 
	 */
 
	uint Items()
 
	{
 
		return this->n;
 
	}
 

	
 

	
 
	/**
 
	 * Tries to remove first instance of given tile and dir
 
	 * @param tile tile
 
	 * @param dir and dir to remove
 
@@ -534,6 +547,77 @@ static bool UpdateSignalsInBuffer(Owner 
 
}
 

	
 

	
 
static Owner _last_owner = INVALID_OWNER; ///< last owner whose track was put into _globset
 

	
 

	
 
/**
 
 * Update signals in buffer
 
 * Called from 'outside'
 
 */
 
void UpdateSignalsInBuffer()
 
{
 
	if (!_globset.IsEmpty()) {
 
		UpdateSignalsInBuffer(_last_owner);
 
		_last_owner = INVALID_OWNER; // invalidate
 
	}
 
}
 

	
 

	
 
/**
 
 * Add track to signal update buffer
 
 *
 
 * @param tile tile where we start
 
 * @param track track at which ends we will update signals
 
 * @param owner owner whose signals we will update
 
 */
 
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
 
{
 
	static const DiagDirection _search_dir_1[] = {
 
		DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
 
	};
 
	static const DiagDirection _search_dir_2[] = {
 
		DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
 
	};
 

	
 
	/* do not allow signal updates for two players in one run */
 
	assert(_globset.IsEmpty() || owner == _last_owner);
 

	
 
	_last_owner = owner;
 

	
 
	_globset.Add(tile, _search_dir_1[track]);
 
	_globset.Add(tile, _search_dir_2[track]);
 

	
 
	if (_globset.Items() >= SIG_GLOB_UPDATE) {
 
		/* too many items, force update */
 
		UpdateSignalsInBuffer(_last_owner);
 
		_last_owner = INVALID_OWNER;
 
	}
 
}
 

	
 

	
 
/**
 
 * Add side of tile to signal update buffer
 
 *
 
 * @param tile tile where we start
 
 * @param side side of tile
 
 * @param owner owner whose signals we will update
 
 */
 
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
 
{
 
	/* do not allow signal updates for two players in one run */
 
	assert(_globset.IsEmpty() || owner == _last_owner);
 

	
 
	_last_owner = owner;
 

	
 
	_globset.Add(tile, side);
 

	
 
	if (_globset.Items() >= SIG_GLOB_UPDATE) {
 
		/* too many items, force update */
 
		UpdateSignalsInBuffer(_last_owner);
 
		_last_owner = INVALID_OWNER;
 
	}
 
}
 

	
 
/**
 
 * Update signals, starting at one side of a tile
 
 * Will check tile next to this at opposite side too
 
@@ -564,16 +648,8 @@ bool UpdateSignalsOnSegment(TileIndex ti
 
 */
 
void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
 
{
 
	static const DiagDirection _search_dir_1[] = {
 
		DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
 
	};
 
	static const DiagDirection _search_dir_2[] = {
 
		DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
 
	};
 

	
 
	assert(_globset.IsEmpty());
 

	
 
	_globset.Add(tile, _search_dir_1[track]);
 
	_globset.Add(tile, _search_dir_2[track]);
 
	AddTrackToSignalBuffer(tile, track, owner);
 
	UpdateSignalsInBuffer(owner);
 
}
src/signal_func.h
Show inline comments
 
@@ -43,5 +43,8 @@ static inline byte SignalOnTrack(Track t
 

	
 
bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner);
 
void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner);
 
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner);
 
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner);
 
void UpdateSignalsInBuffer();
 

	
 
#endif /* SIGNAL_FUNC_H */
src/station_cmd.cpp
Show inline comments
 
@@ -1073,7 +1073,7 @@ CommandCost CmdBuildRailroadStation(Tile
 

	
 
				tile += tile_delta;
 
			} while (--w);
 
			SetSignalsOnBothDir(tile_org, track, _current_player);
 
			AddTrackToSignalBuffer(tile_org, track, _current_player);
 
			YapfNotifyTrackLayoutChange(tile_org, track);
 
			tile_org += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
 
		} while (--numtracks);
 
@@ -1209,7 +1209,7 @@ CommandCost CmdRemoveFromRailroadStation
 

	
 
			DoClearSquare(tile2);
 
			st->rect.AfterRemoveTile(st, tile2);
 
			SetSignalsOnBothDir(tile2, track, owner);
 
			AddTrackToSignalBuffer(tile2, track, owner);
 
			YapfNotifyTrackLayoutChange(tile2, track);
 

	
 
			DeallocateSpecFromStation(st, specindex);
 
@@ -1270,7 +1270,7 @@ static CommandCost RemoveRailroadStation
 
					Track track = GetRailStationTrack(tile);
 
					Owner owner = GetTileOwner(tile); // _current_player can be OWNER_WATER
 
					DoClearSquare(tile);
 
					SetSignalsOnBothDir(tile, track, owner);
 
					AddTrackToSignalBuffer(tile, track, owner);
 
					YapfNotifyTrackLayoutChange(tile, track);
 
				}
 
			}
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -419,7 +419,7 @@ not_valid_below:;
 

	
 
	if (flags & DC_EXEC && railtype != INVALID_RAILTYPE) {
 
		Track track = AxisToTrack(direction);
 
		UpdateSignalsOnSegment(tile_start, INVALID_DIAGDIR, _current_player);
 
		AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_player);
 
		YapfNotifyTrackLayoutChange(tile_start, track);
 
	}
 

	
 
@@ -549,7 +549,7 @@ CommandCost CmdBuildTunnel(TileIndex sta
 
		if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
 
			MakeRailTunnel(start_tile, _current_player, direction,                 (RailType)GB(p1, 0, 4));
 
			MakeRailTunnel(end_tile,   _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4));
 
			UpdateSignalsOnSegment(start_tile, INVALID_DIAGDIR, _current_player);
 
			AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_player);
 
			YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction)));
 
		} else {
 
			MakeRoadTunnel(start_tile, _current_player, direction,                 (RoadTypes)GB(p1, 0, 3));
 
@@ -612,8 +612,8 @@ static CommandCost DoClearTunnel(TileInd
 
			DoClearSquare(endtile);
 

	
 
			/* cannot use INVALID_DIAGDIR for signal update because the tunnel doesn't exist anymore */
 
			UpdateSignalsOnSegment(tile, ReverseDiagDir(dir), owner);
 
			UpdateSignalsOnSegment(endtile, dir, owner);
 
			AddSideToSignalBuffer(tile, ReverseDiagDir(dir), owner);
 
			AddSideToSignalBuffer(endtile, dir, owner);
 

	
 
			Track track = AxisToTrack(DiagDirToAxis(dir));
 
			YapfNotifyTrackLayoutChange(tile, track);
 
@@ -674,8 +674,8 @@ static CommandCost DoClearBridge(TileInd
 

	
 
		if (rail) {
 
			/* cannot use INVALID_DIAGDIR for signal update because the bridge doesn't exist anymore */
 
			UpdateSignalsOnSegment(tile, ReverseDiagDir(direction), owner);
 
			UpdateSignalsOnSegment(endtile, direction, owner);
 
			AddSideToSignalBuffer(tile, ReverseDiagDir(direction), owner);
 
			AddSideToSignalBuffer(endtile, direction, owner);
 

	
 
			Track track = AxisToTrack(DiagDirToAxis(direction));
 
			YapfNotifyTrackLayoutChange(tile, track);
src/water_cmd.cpp
Show inline comments
 
@@ -648,6 +648,9 @@ static void TileLoopWaterHelper(TileInde
 
				MarkTileDirtyIfCanal(target + TileOffsByDir(dir));
 
			}
 
		}
 

	
 
		/* update signals if needed */
 
		UpdateSignalsInBuffer();
 
	}
 
}
 

	
src/waypoint.cpp
Show inline comments
 
@@ -297,7 +297,7 @@ CommandCost RemoveTrainWaypoint(TileInde
 
			MarkTileDirtyByTile(tile);
 
		} else {
 
			DoClearSquare(tile);
 
			SetSignalsOnBothDir(tile, track, owner);
 
			AddTrackToSignalBuffer(tile, track, owner);
 
		}
 
		YapfNotifyTrackLayoutChange(tile, track);
 
	}
0 comments (0 inline, 0 general)