Chunnel: Increase tunnel pool size, make tunnel IDs 32 bit.

Add lookup mechanism for tunnel IDs which don't fit in 16 bits in M2.
This commit is contained in:
Jonathan G Rennison
2017-03-04 23:49:55 +00:00
parent 87142ed840
commit afd8c6b867
4 changed files with 54 additions and 6 deletions

View File

@@ -41,6 +41,7 @@ static void Load_TUNN()
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Tunnel *tunnel = new (index) Tunnel(); Tunnel *tunnel = new (index) Tunnel();
SlObject(tunnel, _tunnel_desc); SlObject(tunnel, _tunnel_desc);
tunnel->UpdateIndexes();
} }
} }

View File

@@ -17,7 +17,7 @@
struct Tunnel; struct Tunnel;
typedef Pool<Tunnel, TunnelID, 64, 64000> TunnelPool; typedef Pool<Tunnel, TunnelID, 64, 1048576> TunnelPool;
extern TunnelPool _tunnel_pool; extern TunnelPool _tunnel_pool;
struct Tunnel : TunnelPool::PoolItem<&_tunnel_pool> { struct Tunnel : TunnelPool::PoolItem<&_tunnel_pool> {
@@ -27,13 +27,21 @@ struct Tunnel : TunnelPool::PoolItem<&_tunnel_pool> {
bool is_chunnel; bool is_chunnel;
Tunnel() {} Tunnel() {}
Tunnel(TileIndex tile_n, TileIndex tile_s, bool is_chunnel) : tile_n(tile_n), tile_s(tile_s), is_chunnel(is_chunnel) {}
~Tunnel(); ~Tunnel();
Tunnel(TileIndex tile_n, TileIndex tile_s, bool is_chunnel) : tile_n(tile_n), tile_s(tile_s), is_chunnel(is_chunnel)
{
this->UpdateIndexes();
}
void UpdateIndexes();
static inline Tunnel *GetByTile(TileIndex tile) static inline Tunnel *GetByTile(TileIndex tile)
{ {
return Tunnel::Get(GetTunnelIndex(tile)); return Tunnel::Get(GetTunnelIndex(tile));
} }
static void PreCleanPool();
}; };
#define FOR_ALL_TUNNELS_FROM(var, start) FOR_ALL_ITEMS_FROM(Tunnel, tunnel_index, var, start) #define FOR_ALL_TUNNELS_FROM(var, start) FOR_ALL_ITEMS_FROM(Tunnel, tunnel_index, var, start)

View File

@@ -13,6 +13,7 @@
#include "tunnelbridge_map.h" #include "tunnelbridge_map.h"
#include "core/pool_func.hpp" #include "core/pool_func.hpp"
#include <unordered_map>
#include "safeguards.h" #include "safeguards.h"
@@ -20,12 +21,45 @@
TunnelPool _tunnel_pool("Tunnel"); TunnelPool _tunnel_pool("Tunnel");
INSTANTIATE_POOL_METHODS(Tunnel) INSTANTIATE_POOL_METHODS(Tunnel)
static std::unordered_map<TileIndex, TunnelID> tunnel_tile_index_map;
/** /**
* Clean up a tunnel tile * Clean up a tunnel tile
*/ */
Tunnel::~Tunnel() Tunnel::~Tunnel()
{ {
if (CleaningPool()) return; if (CleaningPool()) return;
if (this->index >= TUNNEL_ID_MAP_LOOKUP) {
tunnel_tile_index_map.erase(this->tile_n);
tunnel_tile_index_map.erase(this->tile_s);
}
}
/**
* Update tunnel indexes
*/
void Tunnel::UpdateIndexes()
{
if (this->index >= TUNNEL_ID_MAP_LOOKUP) {
tunnel_tile_index_map[this->tile_n] = this->index;
tunnel_tile_index_map[this->tile_s] = this->index;
}
}
/**
* Tunnel pool is about to be cleaned
*/
void Tunnel::PreCleanPool()
{
tunnel_tile_index_map.clear();
}
TunnelID GetTunnelIndexByLookup(TileIndex t)
{
auto iter = tunnel_tile_index_map.find(t);
assert_msg(iter != tunnel_tile_index_map.end(), "tile: 0x%X", t);
return iter->second;
} }
/** /**

View File

@@ -14,7 +14,9 @@
#include "road_map.h" #include "road_map.h"
typedef uint16 TunnelID; ///< Type for the unique identifier of tunnels. typedef uint32 TunnelID; ///< Type for the unique identifier of tunnels.
static const TunnelID TUNNEL_ID_MAP_LOOKUP = 0xFFFF; ///< Sentinel ID value to store in m2 to indiciate that the ID should be looked up instead
/** /**
* Is this a tunnel (entrance)? * Is this a tunnel (entrance)?
@@ -46,8 +48,11 @@ static inline bool IsTunnelTile(TileIndex t)
*/ */
static inline TunnelID GetTunnelIndex(TileIndex t) static inline TunnelID GetTunnelIndex(TileIndex t)
{ {
extern TunnelID GetTunnelIndexByLookup(TileIndex t);
assert(IsTunnelTile(t)); assert(IsTunnelTile(t));
return _m[t].m2; TunnelID map_id = _m[t].m2;
return map_id == TUNNEL_ID_MAP_LOOKUP ? GetTunnelIndexByLookup(t) : map_id;
} }
TileIndex GetOtherTunnelEnd(TileIndex); TileIndex GetOtherTunnelEnd(TileIndex);
@@ -65,7 +70,7 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, TunnelID id, DiagDirecti
{ {
SetTileType(t, MP_TUNNELBRIDGE); SetTileType(t, MP_TUNNELBRIDGE);
SetTileOwner(t, o); SetTileOwner(t, o);
_m[t].m2 = id; _m[t].m2 = (id >= TUNNEL_ID_MAP_LOOKUP) ? TUNNEL_ID_MAP_LOOKUP : id;
_m[t].m3 = 0; _m[t].m3 = 0;
_m[t].m4 = 0; _m[t].m4 = 0;
_m[t].m5 = TRANSPORT_ROAD << 2 | d; _m[t].m5 = TRANSPORT_ROAD << 2 | d;
@@ -88,7 +93,7 @@ static inline void MakeRailTunnel(TileIndex t, Owner o, TunnelID id, DiagDirecti
{ {
SetTileType(t, MP_TUNNELBRIDGE); SetTileType(t, MP_TUNNELBRIDGE);
SetTileOwner(t, o); SetTileOwner(t, o);
_m[t].m2 = id; _m[t].m2 = (id >= TUNNEL_ID_MAP_LOOKUP) ? TUNNEL_ID_MAP_LOOKUP : id;
SB(_m[t].m1, 7, 1, GB(r, 4, 1)); SB(_m[t].m1, 7, 1, GB(r, 4, 1));
SB(_m[t].m3, 0, 4, GB(r, 0, 4)); SB(_m[t].m3, 0, 4, GB(r, 0, 4));
SB(_m[t].m3, 4, 4, 0); SB(_m[t].m3, 4, 4, 0);