src/signal.cpp
changeset 8802 e08824cdab46
parent 8796 81b0d6b54a1f
child 8833 b2fe42c9ea64
equal deleted inserted replaced
8801:a1eb885cc491 8802:e08824cdab46
    20 #include "player_func.h"
    20 #include "player_func.h"
    21 
    21 
    22 
    22 
    23 /** these are the maximums used for updating signal blocks */
    23 /** these are the maximums used for updating signal blocks */
    24 enum {
    24 enum {
    25 	SIG_TBU_SIZE  =  64, ///< number of signals entering to block
    25 	SIG_TBU_SIZE    =  64, ///< number of signals entering to block
    26 	SIG_TBD_SIZE  = 256, ///< number of intersections - open nodes in current block
    26 	SIG_TBD_SIZE    = 256, ///< number of intersections - open nodes in current block
    27 	SIG_GLOB_SIZE =  64, ///< number of open blocks (block can be opened more times until detected)
    27 	SIG_GLOB_SIZE   = 128, ///< number of open blocks (block can be opened more times until detected)
       
    28 	SIG_GLOB_UPDATE =  64, ///< how many items need to be in _globset to force update
    28 };
    29 };
       
    30 
       
    31 assert_compile(SIG_GLOB_UPDATE <= SIG_GLOB_SIZE);
    29 
    32 
    30 /** incidating trackbits with given enterdir */
    33 /** incidating trackbits with given enterdir */
    31 static const TrackBitsByte _enterdir_to_trackbits[DIAGDIR_END] = {
    34 static const TrackBitsByte _enterdir_to_trackbits[DIAGDIR_END] = {
    32 	{TRACK_BIT_3WAY_NE},
    35 	{TRACK_BIT_3WAY_NE},
    33 	{TRACK_BIT_3WAY_SE},
    36 	{TRACK_BIT_3WAY_SE},
    96 	 */
    99 	 */
    97 	bool IsFull()
   100 	bool IsFull()
    98 	{
   101 	{
    99 		return this->n == lengthof(data);
   102 		return this->n == lengthof(data);
   100 	}
   103 	}
       
   104 
       
   105 	/**
       
   106 	 * Reads the number of items
       
   107 	 * @return current number of items
       
   108 	 */
       
   109 	uint Items()
       
   110 	{
       
   111 		return this->n;
       
   112 	}
       
   113 
   101 
   114 
   102 	/**
   115 	/**
   103 	 * Tries to remove first instance of given tile and dir
   116 	 * Tries to remove first instance of given tile and dir
   104 	 * @param tile tile
   117 	 * @param tile tile
   105 	 * @param dir and dir to remove
   118 	 * @param dir and dir to remove
   532 
   545 
   533 	return state;
   546 	return state;
   534 }
   547 }
   535 
   548 
   536 
   549 
   537 /**
   550 static Owner _last_owner = INVALID_OWNER; ///< last owner whose track was put into _globset
   538  * Update signals, starting at one side of a tile
   551 
   539  * Will check tile next to this at opposite side too
   552 
   540  *
   553 /**
   541  * @see UpdateSignalsInBuffer()
   554  * Update signals in buffer
   542  * @param tile tile where we start
   555  * Called from 'outside'
   543  * @param side side of tile
   556  */
   544  * @param owner owner whose signals we will update
   557 void UpdateSignalsInBuffer()
   545  * @return false iff train can leave depot
   558 {
   546  */
   559 	if (!_globset.IsEmpty()) {
   547 bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
   560 		UpdateSignalsInBuffer(_last_owner);
   548 {
   561 		_last_owner = INVALID_OWNER; // invalidate
   549 	assert(_globset.IsEmpty());
   562 	}
   550 	_globset.Add(tile, side);
   563 }
   551 
   564 
   552 	return UpdateSignalsInBuffer(owner);
   565 
   553 }
   566 /**
   554 
   567  * Add track to signal update buffer
   555 
   568  *
   556 /**
       
   557  * Update signals at segments that are at both ends of
       
   558  * given (existent or non-existent) track
       
   559  *
       
   560  * @see UpdateSignalsInBuffer()
       
   561  * @param tile tile where we start
   569  * @param tile tile where we start
   562  * @param track track at which ends we will update signals
   570  * @param track track at which ends we will update signals
   563  * @param owner owner whose signals we will update
   571  * @param owner owner whose signals we will update
   564  */
   572  */
   565 void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
   573 void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
   566 {
   574 {
   567 	static const DiagDirection _search_dir_1[] = {
   575 	static const DiagDirection _search_dir_1[] = {
   568 		DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
   576 		DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
   569 	};
   577 	};
   570 	static const DiagDirection _search_dir_2[] = {
   578 	static const DiagDirection _search_dir_2[] = {
   571 		DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
   579 		DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
   572 	};
   580 	};
   573 
   581 
   574 	assert(_globset.IsEmpty());
   582 	/* do not allow signal updates for two players in one run */
       
   583 	assert(_globset.IsEmpty() || owner == _last_owner);
       
   584 
       
   585 	_last_owner = owner;
   575 
   586 
   576 	_globset.Add(tile, _search_dir_1[track]);
   587 	_globset.Add(tile, _search_dir_1[track]);
   577 	_globset.Add(tile, _search_dir_2[track]);
   588 	_globset.Add(tile, _search_dir_2[track]);
       
   589 
       
   590 	if (_globset.Items() >= SIG_GLOB_UPDATE) {
       
   591 		/* too many items, force update */
       
   592 		UpdateSignalsInBuffer(_last_owner);
       
   593 		_last_owner = INVALID_OWNER;
       
   594 	}
       
   595 }
       
   596 
       
   597 
       
   598 /**
       
   599  * Add side of tile to signal update buffer
       
   600  *
       
   601  * @param tile tile where we start
       
   602  * @param side side of tile
       
   603  * @param owner owner whose signals we will update
       
   604  */
       
   605 void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
       
   606 {
       
   607 	/* do not allow signal updates for two players in one run */
       
   608 	assert(_globset.IsEmpty() || owner == _last_owner);
       
   609 
       
   610 	_last_owner = owner;
       
   611 
       
   612 	_globset.Add(tile, side);
       
   613 
       
   614 	if (_globset.Items() >= SIG_GLOB_UPDATE) {
       
   615 		/* too many items, force update */
       
   616 		UpdateSignalsInBuffer(_last_owner);
       
   617 		_last_owner = INVALID_OWNER;
       
   618 	}
       
   619 }
       
   620 
       
   621 /**
       
   622  * Update signals, starting at one side of a tile
       
   623  * Will check tile next to this at opposite side too
       
   624  *
       
   625  * @see UpdateSignalsInBuffer()
       
   626  * @param tile tile where we start
       
   627  * @param side side of tile
       
   628  * @param owner owner whose signals we will update
       
   629  * @return false iff train can leave depot
       
   630  */
       
   631 bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
       
   632 {
       
   633 	assert(_globset.IsEmpty());
       
   634 	_globset.Add(tile, side);
       
   635 
       
   636 	return UpdateSignalsInBuffer(owner);
       
   637 }
       
   638 
       
   639 
       
   640 /**
       
   641  * Update signals at segments that are at both ends of
       
   642  * given (existent or non-existent) track
       
   643  *
       
   644  * @see UpdateSignalsInBuffer()
       
   645  * @param tile tile where we start
       
   646  * @param track track at which ends we will update signals
       
   647  * @param owner owner whose signals we will update
       
   648  */
       
   649 void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
       
   650 {
       
   651 	assert(_globset.IsEmpty());
       
   652 
       
   653 	AddTrackToSignalBuffer(tile, track, owner);
   578 	UpdateSignalsInBuffer(owner);
   654 	UpdateSignalsInBuffer(owner);
   579 }
   655 }