Ticket #2022: Territory_Memfrag.patch

File Territory_Memfrag.patch, 22.8 KB (added by tuan kuranes, 11 years ago)

patch

  • source/simulation2/helpers/Grid.h

     
    8080            memset(m_Data, 0, m_W*m_H*sizeof(T));
    8181    }
    8282
    83     void set(int i, int j, const T& value)
     83    void set(const int i, const int j, const T& value)
    8484    {
    8585#if GRID_BOUNDS_DEBUG
    8686        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
    8787#endif
    8888        m_Data[j*m_W + i] = value;
    8989    }
     90   
     91    void add(const int i, const int j, T val)
     92    {
     93#if GRID_BOUNDS_DEBUG
     94        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     95#endif
     96        m_Data[j*m_W + i] += val;
     97    }
     98    void getPtr(const int i, const int j)
     99    {
     100#if GRID_BOUNDS_DEBUG
     101        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     102#endif
     103        return m_Data[j*m_W + i];
     104    }
    90105
    91     T& get(int i, int j) const
     106    T& get(const int i, const int j) const
    92107    {
    93108#if GRID_BOUNDS_DEBUG
    94109        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     
    113128
    114129    enum { BucketBits = 4, BucketSize = 1 << BucketBits };
    115130
    116     T* GetBucket(int i, int j)
     131    T* GetBucket(const int i, const int j)
    117132    {
    118         size_t b = (j >> BucketBits) * m_BW + (i >> BucketBits);
     133        const size_t b = (j >> BucketBits) * m_BW + (i >> BucketBits);
    119134        if (!m_Data[b])
    120135        {
    121             m_Data[b] = new T[BucketSize*BucketSize];
     136            if (m_Reserve.empty())
     137            {               
     138                m_Data[b] = new T[BucketSize*BucketSize];
     139            }
     140            else
     141            {
     142                m_Data[b] = m_Reserve.back();
     143                m_Reserve.pop_back();
     144            }
    122145            memset(m_Data[b], 0, BucketSize*BucketSize*sizeof(T));
    123146        }
    124147        return m_Data[b];
     
    134157
    135158        m_Data = new T*[m_BW*m_BH];
    136159        memset(m_Data, 0, m_BW*m_BH*sizeof(T*));
     160
    137161    }
    138162
    139163    ~SparseGrid()
    140164    {
    141         reset();
     165        //reset();
     166        for (size_t i = 0; i < (size_t)(m_BW*m_BH); ++i)
     167            delete[] m_Data[i];
    142168        delete[] m_Data;
    143169    }
    144170
    145171    void reset()
    146172    {
    147173        for (size_t i = 0; i < (size_t)(m_BW*m_BH); ++i)
    148             delete[] m_Data[i];
     174        {           
     175            if (m_Data[i])
     176            {
     177                m_Reserve.push_back(m_Data[i]);
     178            }
     179        }
    149180
    150181        memset(m_Data, 0, m_BW*m_BH*sizeof(T*));
    151182    }
    152183
    153     void set(int i, int j, const T& value)
     184    void set(const int i, const int j, const T& value)
    154185    {
    155186#if GRID_BOUNDS_DEBUG
    156187        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     
    158189        GetBucket(i, j)[(j % BucketSize)*BucketSize + (i % BucketSize)] = value;
    159190    }
    160191
    161     T& get(int i, int j)
     192    T& get(const int i, const int j)
    162193    {
    163194#if GRID_BOUNDS_DEBUG
    164195        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     
    169200    u16 m_W, m_H;
    170201    u16 m_BW, m_BH;
    171202    T** m_Data;
     203    std::deque < T* > m_Reserve;
    172204
    173205    size_t m_DirtyID; // if this is < the id maintained by ICmpObstructionManager then it needs to be updated
    174206};
  • source/simulation2/components/CCmpTerritoryManager.cpp

     
    5656
    5757    TerritoryOverlay(CCmpTerritoryManager& manager);
    5858    virtual void StartRender();
    59     virtual void ProcessTile(ssize_t i, ssize_t j);
     59    virtual void ProcessTile(const ssize_t i, const ssize_t j);
    6060};
    6161
    6262class CCmpTerritoryManager : public ICmpTerritoryManager
     
    8888    // connected flag in bit 6 (TERRITORY_CONNECTED_MASK);
    8989    // processed flag in bit 7 (TERRITORY_PROCESSED_MASK)
    9090    Grid<u8>* m_Territories;
     91    Grid<u8>* m_Territories_Data;
     92    Grid<u8>* m_InfluenceGrid;
    9193
     94    u16 m_TilesW;
     95    u16 m_TilesH;
     96    // For each player, store the sum of influences on each tile
     97    std::vector<std::pair<player_id_t, Grid<u32>* > > playerGrids;
     98
     99    std::map<player_id_t, std::vector<entity_id_t> > influenceEntities;
     100    std::vector<entity_id_t> rootInfluenceEntities;
     101
     102    std::vector<std::pair<u16, u16> > tileStack;
     103
     104    std::deque<Grid<u32>* > grid32Pool;
     105
    92106    // Set to true when territories change; will send a TerritoriesChanged message
    93107    // during the Update phase
    94108    bool m_TriggerEvent;
     
    113127    virtual void Init(const CParamNode& UNUSED(paramNode))
    114128    {
    115129        m_Territories = NULL;
     130        m_Territories_Data = NULL;
     131        m_InfluenceGrid = NULL;
    116132        m_DebugOverlay = NULL;
    117133//      m_DebugOverlay = new TerritoryOverlay(*this);
    118134        m_BoundaryLinesDirty = true;
     
    120136        m_EnableLineDebugOverlays = false;
    121137        m_DirtyID = 1;
    122138
     139        m_TilesW = 0;
     140        m_TilesH = 0;
    123141        m_AnimTime = 0.0;
    124142
    125143        CParamNode externalParamNode;
     
    134152
    135153    virtual void Deinit()
    136154    {
    137         SAFE_DELETE(m_Territories);
     155        SAFE_DELETE(m_Territories_Data);
     156        SAFE_DELETE(m_InfluenceGrid);
    138157        SAFE_DELETE(m_DebugOverlay);
     158        for(std::deque<Grid<u32>* >::iterator it = grid32Pool.begin(); it != grid32Pool.end(); ++it )
     159            delete *it;
    139160    }
    140 
     161    Grid<u32>* getPooledGrid32()
     162    {
     163        if (grid32Pool.empty())
     164        {
     165            return new Grid<u32>(m_TilesW, m_TilesH);
     166        }
     167        Grid<u32>* ret = grid32Pool.back();
     168        grid32Pool.pop_back();
     169        ret->reset();
     170        return ret;
     171    }
     172    void returnPooledGrid32(Grid<u32>* ret)
     173    {
     174        grid32Pool.push_back(ret);
     175    }
    141176    virtual void Serialize(ISerializer& UNUSED(serialize))
    142177    {
    143178        // Territory state can be recomputed as required, so we don't need to serialize any of it.
     
    233268
    234269    void MakeDirty()
    235270    {
    236         SAFE_DELETE(m_Territories);
     271        m_Territories = NULL;
    237272        ++m_DirtyID;
    238273        m_BoundaryLinesDirty = true;
    239274        m_TriggerEvent = true;
     
    256291     * a TerritoryInfluence component. Grid cells are 0 if no influence,
    257292     * or 1+c if the influence have cost c (assumed between 0 and 254).
    258293     */
    259     void RasteriseInfluences(CComponentManager::InterfaceList& infls, Grid<u8>& grid);
     294    void RasteriseInfluences(const CComponentManager::InterfaceList& infls, Grid<u8>& grid);
    260295
    261296    std::vector<STerritoryBoundary> ComputeBoundaries();
    262297
     
    279314
    280315typedef PriorityQueueHeap<std::pair<u16, u16>, u32, std::greater<u32> > OpenQueue;
    281316
    282 static void ProcessNeighbour(u32 falloff, u16 i, u16 j, u32 pg, bool diagonal,
     317static void ProcessNeighbour(const u32 falloff, const u16 i, const u16 j, const u32 pg, bool diagonal,
    283318        Grid<u32>& grid, OpenQueue& queue, const Grid<u8>& costGrid)
    284319{
    285320    u32 dg = falloff * costGrid.get(i, j);
     
    291326    if (pg <= grid.get(i, j) + dg)
    292327        return;
    293328
    294     u32 g = pg - dg; // cost to this tile = cost to predecessor - falloff from predecessor
     329    const u32 g = pg - dg; // cost to this tile = cost to predecessor - falloff from predecessor
    295330
    296331    grid.set(i, j, g);
    297332    OpenQueue::Item tile = { std::make_pair(i, j), g };
    298333    queue.push(tile);
    299334}
    300335
    301 static void FloodFill(Grid<u32>& grid, Grid<u8>& costGrid, OpenQueue& openTiles, u32 falloff)
     336static void FloodFill(Grid<u32>& grid, Grid<u8>& costGrid, OpenQueue& openTiles, const u32 falloff)
    302337{
    303     u16 tilesW = grid.m_W;
    304     u16 tilesH = grid.m_H;
     338    const u16 tilesW = grid.m_W;
     339    const u16 tilesH = grid.m_H;
    305340
    306341    while (!openTiles.empty())
    307342    {
    308343        OpenQueue::Item tile = openTiles.pop();
    309344
    310345        // Process neighbours (if they're not off the edge of the map)
    311         u16 x = tile.id.first;
    312         u16 z = tile.id.second;
    313         if (x > 0)
     346        const u16 x = tile.id.first;
     347        const u16 z = tile.id.second;
    314348            ProcessNeighbour(falloff, (u16)(x-1), z, tile.rank, false, grid, openTiles, costGrid);
    315         if (x < tilesW-1)
     349        if (x < tilesW-1){
    316350            ProcessNeighbour(falloff, (u16)(x+1), z, tile.rank, false, grid, openTiles, costGrid);
    317         if (z > 0)
     351            ProcessNeighbour(falloff, (u16)(x+1), (u16)(z-1), tile.rank, true, grid, openTiles, costGrid);
     352        }
    318353            ProcessNeighbour(falloff, x, (u16)(z-1), tile.rank, false, grid, openTiles, costGrid);
    319         if (z < tilesH-1)
     354        if (z < tilesH-1){
    320355            ProcessNeighbour(falloff, x, (u16)(z+1), tile.rank, false, grid, openTiles, costGrid);
    321         if (x > 0 && z > 0)
     356            ProcessNeighbour(falloff, (u16)(x-1), (u16)(z+1), tile.rank, true, grid, openTiles, costGrid);
     357        }
    322358            ProcessNeighbour(falloff, (u16)(x-1), (u16)(z-1), tile.rank, true, grid, openTiles, costGrid);
    323         if (x > 0 && z < tilesH-1)
    324             ProcessNeighbour(falloff, (u16)(x-1), (u16)(z+1), tile.rank, true, grid, openTiles, costGrid);
    325         if (x < tilesW-1 && z > 0)
    326             ProcessNeighbour(falloff, (u16)(x+1), (u16)(z-1), tile.rank, true, grid, openTiles, costGrid);
     359       
    327360        if (x < tilesW-1 && z < tilesH-1)
    328361            ProcessNeighbour(falloff, (u16)(x+1), (u16)(z+1), tile.rank, true, grid, openTiles, costGrid);
    329362    }
     
    343376    if (!cmpTerrain->IsLoaded())
    344377        return;
    345378
    346     u16 tilesW = cmpTerrain->GetTilesPerSide();
    347     u16 tilesH = cmpTerrain->GetTilesPerSide();
     379    const u16 tilesW = cmpTerrain->GetTilesPerSide();
     380    const u16 tilesH = cmpTerrain->GetTilesPerSide();
     381   
     382    if (!m_Territories_Data)
     383    {
     384        m_TilesW = tilesW;
     385        m_TilesH = tilesH;
     386        m_Territories_Data = new Grid<u8>(tilesW, tilesH);
     387    }
     388    ENSURE(m_TilesW == tilesW);
     389    ENSURE(m_TilesH == tilesH);
     390   
     391    const u32 gridSize = tilesH * tilesW;
    348392
    349     m_Territories = new Grid<u8>(tilesW, tilesH);
     393    m_Territories = m_Territories_Data;
     394    m_Territories->reset();
    350395
    351396    // Compute terrain-passability-dependent costs per tile
    352     Grid<u8> influenceGrid(tilesW, tilesH);
     397    if (!m_InfluenceGrid)
     398        m_InfluenceGrid = new Grid<u8>(tilesW, tilesH);
     399    Grid<u8>* influenceGrid = m_InfluenceGrid;
     400    influenceGrid->reset();
    353401
    354402    CmpPtr<ICmpPathfinder> cmpPathfinder(GetSimContext(), SYSTEM_ENTITY);
    355     ICmpPathfinder::pass_class_t passClassDefault = cmpPathfinder->GetPassabilityClass("default");
    356     ICmpPathfinder::pass_class_t passClassUnrestricted = cmpPathfinder->GetPassabilityClass("unrestricted");
     403    const ICmpPathfinder::pass_class_t passClassDefault = cmpPathfinder->GetPassabilityClass("default");
     404    const ICmpPathfinder::pass_class_t passClassUnrestricted = cmpPathfinder->GetPassabilityClass("unrestricted");
    357405
    358406    const Grid<u16>& passGrid = cmpPathfinder->GetPassabilityGrid();
    359     for (u16 j = 0; j < tilesH; ++j)
    360407    {
    361         for (u16 i = 0; i < tilesW; ++i)
     408        u8* const __restrict inflgridData = influenceGrid->m_Data;
     409        const u16* const __restrict passgridData = passGrid.m_Data;
     410        for (u32 k = 0; k < gridSize; ++k)
    362411        {
    363             u16 g = passGrid.get(i, j);
     412            const u16 g = passgridData[k];
    364413            u8 cost;
    365414            if (g & passClassUnrestricted)
    366415                cost = 255; // off the world; use maximum cost
     
    368417                cost = m_ImpassableCost;
    369418            else
    370419                cost = 1;
    371             influenceGrid.set(i, j, cost);
     420            inflgridData[k] = cost;
    372421        }
    373422    }
    374423
     
    376425    CComponentManager::InterfaceList influences = GetSimContext().GetComponentManager().GetEntitiesWithInterface(IID_TerritoryInfluence);
    377426
    378427    // Allow influence entities to override the terrain costs
    379     RasteriseInfluences(influences, influenceGrid);
     428    RasteriseInfluences(influences, *influenceGrid);
    380429
    381430    // Split influence entities into per-player lists, ignoring any with invalid properties
    382     std::map<player_id_t, std::vector<entity_id_t> > influenceEntities;
    383     std::vector<entity_id_t> rootInfluenceEntities;
    384     for (CComponentManager::InterfaceList::iterator it = influences.begin(); it != influences.end(); ++it)
     431    influenceEntities.clear();
     432    rootInfluenceEntities.clear();
     433    const CComponentManager::InterfaceList::const_iterator itiEnd = influences.end();
     434    for (CComponentManager::InterfaceList::const_iterator it = influences.begin(); it != itiEnd; ++it)
    385435    {
    386436        // Ignore any with no weight or radius (to avoid divide-by-zero later)
    387437        ICmpTerritoryInfluence* cmpTerritoryInfluence = static_cast<ICmpTerritoryInfluence*>(it->second);
     
    393443            continue;
    394444
    395445        // Ignore Gaia and unassigned
    396         player_id_t owner = cmpOwnership->GetOwner();
     446        const player_id_t owner = cmpOwnership->GetOwner();
    397447        if (owner <= 0)
    398448            continue;
    399449
     
    412462            rootInfluenceEntities.push_back(it->first);
    413463    }
    414464
    415     // For each player, store the sum of influences on each tile
    416     std::vector<std::pair<player_id_t, Grid<u32> > > playerGrids;
     465    playerGrids.clear();
    417466    // TODO: this is a large waste of memory; we don't really need to store
    418467    // all the intermediate grids
    419468
    420     for (std::map<player_id_t, std::vector<entity_id_t> >::iterator it = influenceEntities.begin(); it != influenceEntities.end(); ++it)
     469
     470    OpenQueue openTiles;
     471    Grid<u32>* entityGrid = getPooledGrid32();
     472    const std::map<player_id_t, std::vector<entity_id_t> >::iterator itieEnd = influenceEntities.end();
     473    for (std::map<player_id_t, std::vector<entity_id_t> >::iterator it = influenceEntities.begin(); it != itieEnd; ++it)
    421474    {
    422         Grid<u32> playerGrid(tilesW, tilesH);
     475        Grid<u32>* playerGrid = getPooledGrid32();
    423476
    424         std::vector<entity_id_t>& ents = it->second;
    425         for (std::vector<entity_id_t>::iterator eit = ents.begin(); eit != ents.end(); ++eit)
     477        const std::vector<entity_id_t>& ents = it->second;
     478        const std::vector<entity_id_t>::const_iterator eitEnd = ents.end();     
     479        for (std::vector<entity_id_t>::const_iterator eit = ents.begin(); eit != eitEnd; ++eit)
    426480        {
    427481            // Compute the influence map of the current entity, then add it to the player grid
     482            entityGrid->reset();
    428483
    429             Grid<u32> entityGrid(tilesW, tilesH);
     484            {
     485                CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), *eit);
     486                const CFixedVector2D pos = cmpPosition->GetPosition2D();
     487                const u16 i = (u16)clamp((pos.X / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesW-1);
     488                const u16 j = (u16)clamp((pos.Y / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesH-1);
    430489
    431             CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), *eit);
    432             CFixedVector2D pos = cmpPosition->GetPosition2D();
    433             u16 i = (u16)clamp((pos.X / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesW-1);
    434             u16 j = (u16)clamp((pos.Y / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesH-1);
     490                CmpPtr<ICmpTerritoryInfluence> cmpTerritoryInfluence(GetSimContext(), *eit);
     491                const u32 weight = cmpTerritoryInfluence->GetWeight();
     492                const u32 radius = cmpTerritoryInfluence->GetRadius() / TERRAIN_TILE_SIZE;
     493                const u32 falloff = weight / radius; // earlier check for GetRadius() == 0 prevents divide-by-zero
    435494
    436             CmpPtr<ICmpTerritoryInfluence> cmpTerritoryInfluence(GetSimContext(), *eit);
    437             u32 weight = cmpTerritoryInfluence->GetWeight();
    438             u32 radius = cmpTerritoryInfluence->GetRadius() / TERRAIN_TILE_SIZE;
    439             u32 falloff = weight / radius; // earlier check for GetRadius() == 0 prevents divide-by-zero
     495                // TODO: we should have some maximum value on weight, to avoid overflow
     496                // when doing all the sums
    440497
    441             // TODO: we should have some maximum value on weight, to avoid overflow
    442             // when doing all the sums
     498                // Initialise the tile under the entity
     499                entityGrid->set(i, j, weight);
     500                OpenQueue::Item tile = { std::make_pair(i, j), weight };
     501                openTiles.push(tile);
    443502
    444             // Initialise the tile under the entity
    445             entityGrid.set(i, j, weight);
    446             OpenQueue openTiles;
    447             OpenQueue::Item tile = { std::make_pair((u16)i, (i16)j), weight };
    448             openTiles.push(tile);
    449 
    450             // Expand influences outwards
    451             FloodFill(entityGrid, influenceGrid, openTiles, falloff);
    452 
     503                // Expand influences outwards
     504                FloodFill(*entityGrid, *influenceGrid, openTiles, falloff);
     505            }
    453506            // TODO: we should do a sparse grid and only add the non-zero regions, for performance
    454             for (u16 j = 0; j < entityGrid.m_H; ++j)
    455                 for (u16 i = 0; i < entityGrid.m_W; ++i)
    456                     playerGrid.set(i, j, playerGrid.get(i, j) + entityGrid.get(i, j));
     507            const u32* const __restrict eData = entityGrid->m_Data;
     508            u32* const __restrict pData = playerGrid->m_Data;
     509            for(u32 k = 0; k < gridSize; k++)
     510                pData[k] += eData[k];
    457511        }
    458512
    459513        playerGrids.push_back(std::make_pair(it->first, playerGrid));
     
    467521            u32 bestWeight = 0;
    468522            for (size_t k = 0; k < playerGrids.size(); ++k)
    469523            {
    470                 u32 w = playerGrids[k].second.get(i, j);
     524                u32 w = playerGrids[k].second->get(i, j);
    471525                if (w > bestWeight)
    472526                {
    473                     player_id_t id = playerGrids[k].first;
     527                    const player_id_t id = playerGrids[k].first;
    474528                    m_Territories->set(i, j, (u8)id);
    475529                    bestWeight = w;
    476530                }
     
    479533    }
    480534
    481535    // Detect territories connected to a 'root' influence (typically a civ center)
    482     // belonging to their player, and mark them with the connected flag
    483     for (std::vector<entity_id_t>::iterator it = rootInfluenceEntities.begin(); it != rootInfluenceEntities.end(); ++it)
     536    // belonging to their player, and mark them with the connected flag,
     537
     538    Grid<u8>& grid = *m_Territories;
     539    const u16 maxi = (u16)(grid.m_W-1);
     540    const u16 maxj = (u16)(grid.m_H-1);
     541    std::vector<entity_id_t>::const_iterator itrEnd = rootInfluenceEntities.end();
     542    for (std::vector<entity_id_t>::const_iterator it = rootInfluenceEntities.begin(); it != itrEnd; ++it)
    484543    {
    485544        // (These components must be valid else the entities wouldn't be added to this list)
    486545        CmpPtr<ICmpOwnership> cmpOwnership(GetSimContext(), *it);
    487546        CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), *it);
    488547
    489         CFixedVector2D pos = cmpPosition->GetPosition2D();
    490         u16 i = (u16)clamp((pos.X / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesW-1);
    491         u16 j = (u16)clamp((pos.Y / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesH-1);
     548        const CFixedVector2D pos = cmpPosition->GetPosition2D();
     549        const u16 i = (u16)clamp((pos.X / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesW-1);
     550        const u16 j = (u16)clamp((pos.Y / (int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(), 0, tilesH-1);
    492551
    493         u8 owner = (u8)cmpOwnership->GetOwner();
     552        const u8 owner = (u8)cmpOwnership->GetOwner();
    494553
    495         if (m_Territories->get(i, j) != owner)
     554        if (grid.get(i, j) != owner)
    496555            continue;
    497556
    498557        // TODO: would be nice to refactor some of the many flood fill
    499558        // algorithms in this component
    500 
    501         Grid<u8>& grid = *m_Territories;
    502 
    503         u16 maxi = (u16)(grid.m_W-1);
    504         u16 maxj = (u16)(grid.m_H-1);
    505 
    506         std::vector<std::pair<u16, u16> > tileStack;
    507 
    508559#define MARK_AND_PUSH(i, j) STMT(grid.set(i, j, owner | TERRITORY_CONNECTED_MASK); tileStack.push_back(std::make_pair(i, j)); )
    509560
    510561        MARK_AND_PUSH(i, j);
    511562        while (!tileStack.empty())
    512563        {
    513             int ti = tileStack.back().first;
    514             int tj = tileStack.back().second;
     564            const u16 ti = tileStack.back().first;
     565            const u16 tj = tileStack.back().second;
    515566            tileStack.pop_back();
    516567
    517568            if (ti > 0 && grid.get(ti-1, tj) == owner)
     
    540591/**
    541592 * Compute the tile indexes on the grid nearest to a given point
    542593 */
    543 static void NearestTile(entity_pos_t x, entity_pos_t z, u16& i, u16& j, u16 w, u16 h)
     594static void NearestTile(const entity_pos_t x, const entity_pos_t z, u16& i, u16& j, const u16 w, const u16 h)
    544595{
    545596    i = (u16)clamp((x / (int)TERRAIN_TILE_SIZE).ToInt_RoundToZero(), 0, w-1);
    546597    j = (u16)clamp((z / (int)TERRAIN_TILE_SIZE).ToInt_RoundToZero(), 0, h-1);
     
    549600/**
    550601 * Returns the position of the center of the given tile
    551602 */
    552 static void TileCenter(u16 i, u16 j, entity_pos_t& x, entity_pos_t& z)
     603static void TileCenter(const u16 i, const u16 j, entity_pos_t& x, entity_pos_t& z)
    553604{
    554605    x = entity_pos_t::FromInt(i*(int)TERRAIN_TILE_SIZE + (int)TERRAIN_TILE_SIZE/2);
    555606    z = entity_pos_t::FromInt(j*(int)TERRAIN_TILE_SIZE + (int)TERRAIN_TILE_SIZE/2);
     
    558609// TODO: would be nice not to duplicate those two functions from CCmpObstructionManager.cpp
    559610
    560611
    561 void CCmpTerritoryManager::RasteriseInfluences(CComponentManager::InterfaceList& infls, Grid<u8>& grid)
     612void CCmpTerritoryManager::RasteriseInfluences(const CComponentManager::InterfaceList& infls, Grid<u8>& grid)
    562613{
    563     for (CComponentManager::InterfaceList::iterator it = infls.begin(); it != infls.end(); ++it)
     614   
     615    const CComponentManager::InterfaceList::const_iterator itEnd = infls.end();
     616    for (CComponentManager::InterfaceList::const_iterator it = infls.begin(); it != itEnd; ++it)
    564617    {
    565618        ICmpTerritoryInfluence* cmpTerritoryInfluence = static_cast<ICmpTerritoryInfluence*>(it->second);
    566619
    567         i32 cost = cmpTerritoryInfluence->GetCost();
     620        const i32 cost = cmpTerritoryInfluence->GetCost();
    568621        if (cost == -1)
    569622            continue;
    570623
     
    576629        if (!cmpObstruction->GetObstructionSquare(square))
    577630            continue;
    578631
    579         CFixedVector2D halfSize(square.hw, square.hh);
    580         CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(square.u, square.v, halfSize);
     632        const CFixedVector2D halfSize(square.hw, square.hh);
     633        const CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(square.u, square.v, halfSize);
    581634
    582635        u16 i0, j0, i1, j1;
    583636        NearestTile(square.x - halfBound.X, square.z - halfBound.Y, i0, j0, grid.m_W, grid.m_H);
     
    691744        m_BoundaryLinesDirty = false;
    692745    }
    693746
    694     for (size_t i = 0; i < m_BoundaryLines.size(); ++i)
     747    const float alpha = 0.2f + 0.8f * fabsf((float)cos(m_AnimTime * M_PI));// TODO: should let artists tweak this
     748    const std::vector<SBoundaryLine>::iterator itEnd = m_BoundaryLines.end();
     749    for (std::vector<SBoundaryLine>::iterator it = m_BoundaryLines.begin(); it != itEnd; ++it)
    695750    {
    696         if (!m_BoundaryLines[i].connected)
     751        SBoundaryLine& boundaryline = *it;
     752        if (!boundaryline.connected)
    697753        {
    698             CColor c = m_BoundaryLines[i].color;
    699             c.a *= 0.2f + 0.8f * fabsf((float)cos(m_AnimTime * M_PI)); // TODO: should let artists tweak this
    700             m_BoundaryLines[i].overlay.m_Color = c;
     754            CColor c (boundaryline.color);
     755            c.a *= alpha;
     756            boundaryline.overlay.m_Color = c;
    701757        }
    702758    }
    703759}
    704760
    705761void CCmpTerritoryManager::RenderSubmit(SceneCollector& collector)
    706762{
    707     for (size_t i = 0; i < m_BoundaryLines.size(); ++i)
    708         collector.Submit(&m_BoundaryLines[i].overlay);
    709    
    710     for (size_t i = 0; i < m_DebugBoundaryLineNodes.size(); ++i)
    711         collector.Submit(&m_DebugBoundaryLineNodes[i]);
     763    {
     764        const std::vector<SBoundaryLine>::iterator itEnd = m_BoundaryLines.end();
     765        for (std::vector<SBoundaryLine>::iterator it = m_BoundaryLines.begin();
     766             it != itEnd; ++it)
     767        {
     768            SBoundaryLine& boundaryline = *it;
     769            collector.Submit(&boundaryline.overlay);
     770        }
     771    }
    712772
     773    {
     774        const std::vector<SOverlayLine>::iterator itEnd = m_DebugBoundaryLineNodes.end();
     775        for (std::vector<SOverlayLine>::iterator it = m_DebugBoundaryLineNodes.begin();
     776             it != itEnd; ++it)
     777        {
     778            SOverlayLine& overlayLine = *it;
     779            collector.Submit(&overlayLine);
     780        }
     781    }
    713782}
    714783
    715784player_id_t CCmpTerritoryManager::GetOwner(entity_pos_t x, entity_pos_t z)
    716785{
    717     u16 i, j;
    718786    CalculateTerritories();
    719787    if (!m_Territories)
    720788        return 0;
    721789
     790    u16 i, j;
    722791    NearestTile(x, z, i, j, m_Territories->m_W, m_Territories->m_H);
    723792    return m_Territories->get(i, j) & TERRITORY_PLAYER_MASK;
    724793}
    725794
    726795bool CCmpTerritoryManager::IsConnected(entity_pos_t x, entity_pos_t z)
    727796{
    728     u16 i, j;
    729797    CalculateTerritories();
    730798    if (!m_Territories)
    731799        return false;
    732800
     801    u16 i, j;
    733802    NearestTile(x, z, i, j, m_Territories->m_W, m_Territories->m_H);
    734803    return (m_Territories->get(i, j) & TERRITORY_CONNECTED_MASK) != 0;
    735804}
     
    743812    m_TerritoryManager.CalculateTerritories();
    744813}
    745814
    746 void TerritoryOverlay::ProcessTile(ssize_t i, ssize_t j)
     815void TerritoryOverlay::ProcessTile(const ssize_t i, const ssize_t j)
    747816{
    748817    if (!m_TerritoryManager.m_Territories)
    749818        return;
    750819
    751     u8 id = (m_TerritoryManager.m_Territories->get((int) i, (int) j) & ICmpTerritoryManager::TERRITORY_PLAYER_MASK);
     820    const u8 id = (m_TerritoryManager.m_Territories->get((int) i, (int) j) & ICmpTerritoryManager::TERRITORY_PLAYER_MASK);
    752821
    753     float a = 0.2f;
     822    const float a = 0.2f;
    754823    switch (id)
    755824    {
    756825    case 0:  break;
     
    762831    case 6:  RenderTile(CColor(1, 0, 1, a), false); break;
    763832    default: RenderTile(CColor(1, 1, 1, a), false); break;
    764833    }
    765 }
     834}
     835 No newline at end of file